用本征求解最小二乘方程的正确方法是什么?

时间:2017-12-13 19:35:48

标签: c++ eigen

我有以下简单示例来执行最小二乘,但得到以下断言错误。

  

断言失败:(i> = 0)&& (((BlockRows == 1)&&   (BlockCols == XprType :: ColsAtCompileTime)&&一世

这样做的正确方法是什么?

typedef Eigen::ArrayXd arr;
typedef Eigen::ArrayXXd arr2;

arr2 A(3, 3);
arr B(3);
A << 1, 0, 0, 0, 1, 0, 0, 0, 1;
B << 1, 2, 3;
auto x = A.matrix().colPivHouseholderQr().solve(B.matrix());

1 个答案:

答案 0 :(得分:2)

正如我在评论中所说,问题是x是一个存储对QR对象的引用的抽象表达式,但是在最后一行之后它将引用一个死对象然后发生任何事情!

更准确地说,A.matrix().colPivHouseholderQr()创建了一个临时对象,我们称之为tmp_qr。然后tmp_qr.solve(B)创建另一个对象x Solve<...>。该对象实际上存储了两个引用:一个引用tmp_qr,一个引用B。在此行之后,临时对象tmp_qr将被删除,因此Solve<...>对象x有一个死引用。它就像一个引用已删除缓冲区的指针。最后,如果您x稍后,请:

VectorXd y = x;

operator=将使用x引用的QR分解和B引用的右侧x来触发求解操作,但等等.. .Q3分解对象已被删除,所以最多你会得到一个段错误。

所以解决方案是写:

VectorXd x = A.matrix().colPivHouseholderQr().solve(B.matrix());

如果您不知道自己得到了什么,请参阅Eigen的doc了解auto如何危险的详细信息。