使用Eigen矩阵库,计算Ax = B (m>n)矩阵的方法
在使用 Eigen 矩阵库求解超定线性方程组Ax=B(其中m>n,即方程个数多于未知数个数)时,通常采用最小二乘法来求解最优解 x。Eigen 提供了多种方法来求解此类问题,最常用的是 SVD 分解(如 BDCSVD
)或 QR 分解。
推荐方法:使用 SVD 求最小二乘解
最小二乘解的数学公式为:
x=A+B
其中 A+ 是矩阵 A 的伪逆(Moore-Penrose 伪逆),可通过 SVD 计算。
在 Eigen 中推荐使用 BDCSVD
(适用于大矩阵)或 JacobiSVD
:
使用例程如下:
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main() {
int m = 6, n = 3; // m > n: 超定方程组
MatrixXd A(m, n);
VectorXd B(m);
// 示例数据
A << 1, 2, 3,
4, 5, 6,
7, 8, 9,
2, 1, 3,
5, 6, 7,
8, 9, 10;
B << 1, 2, 3, 4, 5, 6;
// 使用 SVD 求解最小二乘解
VectorXd x = A.bdcSvd(ComputeThinU | ComputeThinV).solve(B);
cout << "Solution x: " << x.transpose() << endl;
return 0;
}
其他方法(可选):
方法 | 公式 | Eigen 代码 |
---|---|---|
QR 分解(速度快,稳定性中等) | x=A−1_QRB | x = A.colPivHouseholderQr().solve(B); |
完全正交分解 | 稳定性好 | x = A.fullPivLu().solve(B); (不推荐用于超定) |
正规方程法(不推荐,数值不稳定) | x=(A⊤A)−1A⊤B | x = (A.transpose() * A).ldlt().solve(A.transpose() * B); |
注意:正规方程法虽然形式简单,但A⊤A 可能病态,导致精度差,不推荐用于实际工程。
总结
- 当 m>n 时,使用
A.bdcSvd().solve(B)
是最稳定、推荐的方法。 - 避免使用正规方程法,除非矩阵条件数很好。