动态矩阵的本征分解过程中的误差

时间:2018-08-07 15:12:42

标签: c++ c++17 eigen eigen3

我正在尝试使用Eigen here附带的示例,它似乎可行。但是,当我尝试更改矩阵类型以支持动态矩阵时,一切都会爆炸(除了矩阵/向量的类型,以下所有内容均与示例中的完全一样):

#include <Eigen/Dense>

#include <iostream>

using Matrix2D = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor | Eigen::AutoAlign>;
using Vector   = Eigen::Matrix<double, Eigen::Dynamic, 1>;

int main() {
   Matrix2D A(3,3);
   Vector b(3);

   A << 1,2,3,  4,5,6,  7,8,10;
   b << 3, 3, 4;

   std::cout << "Here is the matrix A:\n" << A << std::endl;
   std::cout << "Here is the vector b:\n" << b << std::endl;
   auto x = A.colPivHouseholderQr().solve(b);
   std::cout << "The solution is:\n" << x << std::endl;

    return 0;
}

运行过程中的输出

Here is the matrix A:
 1  2  3
 4  5  6
 7  8 10
Here is the vector b:
3
3
4
The solution is:
a.out: eigen33/Eigen/src/Core/Block.h:123: Eigen::Block<XprType, BlockRows, BlockCols, InnerPanel>::Block(XprType&, Eigen::Index) [with XprType = Eigen::Matrix<double, -1, 1>; int BlockRows = 1; int BlockCols = 1; bool InnerPanel = false; Eigen::Index = long int]: Assertion `(i>=0) && ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows()) ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols()))' failed.
./makeEigen.sh: line 6: 12045 Aborted                 (core dumped) ./a.out

这有可能吗?如果是这样,我在做什么错了?

1 个答案:

答案 0 :(得分:3)

这是使用auto的危险场所之一。

您链接到的示例具有:

Vector3f x = A.colPivHouseholderQr().solve(b);
^^^^^^^^

您有:

auto x = A.colPivHouseholderQr().solve(b);
^^^^^

在这种情况下,这是非常重要的区别,因为solve()的返回类型不是Vector3f。这是某种中间不可言喻的类型-我们正在构建一个表达式模板,以便以后使用。但是,该表达式模板保留了许多中间引用,如果您不立即解析它们,它们就会悬挂起来。

来自Eigen docs

  

简而言之:除非对自己的工作有100%的把握,否则请不要在Eigen的表达式中使用auto关键字。特别是,请勿使用auto关键字替代Matrix<>类型。