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

© 版权声明
THE END
喜欢就支持一下吧
点赞693 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容