Eigen學習筆記(13)-解決最小二乘系統的問題

原文: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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章