原文:Eigen官網–Solving linear least squares systems
對於超定線性方程系統(An overdetermined system of equations):Ax = b,其是沒有解的。在這種情況下,可以尋找一個接近於方程解的向量x,那麼Ax-b的差值將會足夠小。向量x就被稱爲least square solution。
本篇文章將討論三種線性方程求解方法:
- SVD decomposition
- QR decomposition
- norm equations
其中,SVD
分解通常是最準確的,但也是最慢的;norm equations
是最快的,但也是最不準確的;QR
分解則位於上述兩種方法之間。
1. SVD decomposition
BDCSVD
類中的solve()
方法可以直接用於求解線性系統。
2. QR decomposition
QR
分解類中的solve()
方法也計算最小二乘解。
有三個QR decomposition
類:
HouseholderQR
(不旋轉,速度很快但不穩定)。ColPivHouseholderQR
(列旋轉,因此速度較慢但更準確)FullPivHouseholderQR
(完全旋轉,因此速度最慢且最穩定)。
3. normal equations
求解 Ax = b的最小二乘解,等價於求解normal equation AT Ax=ATb,因此引申出使用normal equations的求解方法。
如果矩陣A是病態的(ill-conditioned),那麼這不是一個好的方法,因爲ATA的條件數是A的條件數的平方,這意味着使用normal equations比使用其他方法減少兩倍的位數。
示例如下:
#include <iostream>
#include <Eigen/Dense>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf A = MatrixXf::Random(3, 2);
cout << "Here is the matrix A:\n" << A << endl;
VectorXf b = VectorXf::Random(3);
cout << "Here is the right hand side b:\n" << b << endl;
// SVD decomposition
cout << "The least-squares solution is:\n"
<< A.bdcSvd(ComputeThinU | ComputeThinV).solve(b) << endl;
// QR decomposition
cout << "The solution using the QR decomposition is:\n"
<< A.colPivHouseholderQr().solve(b) << endl;
// normal equations
cout << "The solution using normal equations is:\n"
<< (A.transpose() * A).ldlt().solve(A.transpose() * b) << endl;
}
結果如下:
Here is the matrix A:
0.68 0.597
-0.211 0.823
0.566 -0.605
Here is the right hand side b:
-0.33
0.536
-0.444
The least-squares solution is:
-0.67
0.314
The solution using the QR decomposition is:
-0.67
0.314
The solution using normal equations is:
-0.67
0.314