Search code examples
c++matrixeigen

Eigen how do I cleanly append matrices in a container loop?


I have this code which uses Eigen:

struct Boundary
{
    Eigen::VectorXi VL;
    Eigen::MatrixXi EL;
    double length;
    bool isHole;
    bool isBoundary;
    bool isMainBoundary;
};

    int boundaryLoops = {};
    int boundariesNo = {};
    int holes = {};
    std::vector<Boundary> boundaries = {};

    MatrixXi SEUV;

    // ***** get all those boundaries here ****
    if (!CheckBoundaries(boundaryLoops, boundariesNo, holes, 
    boundaries))return false;

    // resize all loops container
    long size = {};
    for (auto &&boundary : boundaries){
        size += boundary.EL.rows();
    }
    SEUV.resize(size, 2);

    for (auto &&boundary : boundaries)
    {

        SEUV << boundary.EL; // Too few coefficients passed to comma initializer (operator<<)
        SEUV << SEUV, boundary.EL; // Too many rows passed to comma initializer (operator<<)
    }

is there a swift way to do this, apart from the usual cols and rows counting? This is recurring so I'm looking for the cleanest possible solution

Thank you


Solution

  • If you want to append matrices row-wise you have to ensure that number of columns are equal.

    You also have to take the previous number of rows in consideration when resizing and store the matrix before resizing it.

    SEUV << boundary.EL
    

    fails because the matrix SEUV is already resized and has more rows than boundary.EL

    SEUV << SEUV, boundary.EL
    

    fails because SEUV takes all the space of itself, there is no space left for boundary.EL

    Here an example how you can append 2 matrices with 3 columns and different rows:

    MatrixXi A(3,3);
    A << 1, 1, 1, 1, 1, 1, 1, 1, 1;
    cout << A << "\n\n";
    
    MatrixXi B(2,3) ;
    B << 2, 2, 2, 2, 2, 2;
    cout << B << "\n\n";
    
    MatrixXi tmp = A;
    A.resize(A.rows() + B.rows(), NoChange);
    A << tmp, B;
    cout << A << "\n";