我有以下简单示例执行最小二乘,但出现以下断言错误。
正确的方法是什么?
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/