不调用任何库纯用C++实现np.linalg.lstsq
时间: 2023-08-10 20:30:22 浏览: 166
如果要在C++中实现最小二乘问题的求解,并且不使用任何第三方库,可以使用QR分解求解。以下是一个简单的C++代码示例,演示如何使用QR分解来实现最小二乘问题的求解:
```cpp
#include <iostream>
#include <cmath>
using namespace std;
const int n = 3; // 矩阵A的行数
const int m = 2; // 矩阵A的列数
void lstsq(double A[][m], double b[], double x[])
{
double Q[n][n], R[n][m], Qtb[n];
double epsilon = 1e-10;
// QR分解
for (int j = 0; j < m; j++)
{
// 计算第j列的范数
double norm = 0;
for (int i = j; i < n; i++)
norm += A[i][j] * A[i][j];
norm = sqrt(norm);
// 如果范数太小,则认为矩阵A不满秩,直接返回
if (norm < epsilon)
{
cout << "error: matrix A is rank deficient!" << endl;
return;
}
// 用第j列更新矩阵A的j~m-1列
for (int i = j; i < n; i++)
A[i][j] /= norm;
// 计算Q的j~n-1行
for (int i = j; i < n; i++)
{
Q[i][j] = A[i][j];
for (int k = j+1; k < m; k++)
Q[i][j] -= Q[i][k] * A[i][k];
}
// 计算R的j行
for (int k = j; k < m; k++)
{
R[j][k] = 0;
for (int i = j; i < n; i++)
R[j][k] += Q[i][j] * A[i][k];
}
}
// 计算Qt*b
for (int i = 0; i < n; i++)
{
Qtb[i] = 0;
for (int j = 0; j < m; j++)
Qtb[i] += Q[i][j] * b[j];
}
// 回代求解
for (int i = m-1; i >= 0; i--)
{
x[i] = Qtb[i];
for (int j = i+1; j < m; j++)
x[i] -= R[i][j] * x[j];
x[i] /= R[i][i];
}
}
int main()
{
double A[n][m] = {{1, 2}, {3, 4}, {5, 6}};
double b[m] = {1, 2, 3};
double x[m];
lstsq(A, b, x);
cout << "x = ";
for (int i = 0; i < m; i++)
cout << x[i] << " ";
cout << endl;
return 0;
}
```
在这个示例中,我们首先定义了矩阵A、向量b和解向量x。然后,我们使用QR分解来对矩阵A进行分解,并用分解后的矩阵来求解最小二乘问题。最后,我们输出了解向量x的值。
需要注意的是,这个示例中使用了C++的原生数组来表示矩阵和向量,如果要使用其他类型的矩阵和向量,需要根据实际情况进行调整。另外,这个示例中没有进行任何数值优化,运算速度可能会比较慢,如果需要更快的求解速度,可以考虑使用其他更高效的算法。
阅读全文