Search code examples
c++c++17eigeneigen3

Error during decomposition with Eigen with dynamic matrices


I'm trying the example provided with Eigen here, and it seems to work. However, when I try to alter the matrix type in order to support dynamic matrices, everything explodes (everything below is exactly as in the example but for the types of the matrix/vector):

#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;
}

outputs during running

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

Is this possible to do, and if so, what am I doing wrong?


Solution

  • This is one of those places where it's dangerous to use auto.

    The example you linked to has:

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

    You have:

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

    This is a very significant difference in this context, because the return type of solve() isn't Vector3f. It's some intermediate unutterable type - we're building an expression template to do work later. But that expression template keeps a bunch of intermediate references, which dangle if you don't immediately resolve them.

    From the Eigen docs:

    In short: do not use the auto keywords with Eigen's expressions, unless you are 100% sure about what you are doing. In particular, do not use the auto keyword as a replacement for a Matrix<> type.