我有以下简单示例来执行最小二乘,但得到以下断言错误。
断言失败:(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());
答案 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
如何危险的详细信息。