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



正确的方法是什么?

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());

最佳答案

如我的评论所述,问题在于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触发求解操作,但是,等等... QR分解对象已被删除,因此充其量您会得到一个段错误。

因此解决方案是编写:
VectorXd x = A.matrix().colPivHouseholderQr().solve(B.matrix());

有关如果您不知道所得到的auto多么危险的信息,请参阅Eigen的doc

关于c++ - 用特征值求解最小二乘方程的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47800872/

10-11 23:22
查看更多