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

What is the correct way to solve a least square equation with eigen?

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

Assertion failed: (i>=0) && ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i

正确的做法是什么?

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 分解和 x 引用的右侧 B 触发求解操作,但是,等等...QR 分解对象已被删除,因此您充其量只会遇到段错误。

所以解决方案是这样写:

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

请参阅 Eigen 的 doc 了解更多关于 auto 在您不知道自己得到什么的情况下如何危险的详细信息。