Append column to matrix, using Eigen library
Asked Answered
B

1

24

It's quite a simple task, but I was not able to find an answer to it:

Using the Eigen library, suppose I have Matrix2Xd mat and Vector2d vec, where

mat = 1 1 1
      1 1 1
vec = 2 2

Now I need something like mat.addCol(vec) such that afterwards

mat = 1 1 1 2
      1 1 1 2

What is the best (simplest) way to accomplish this?

Please note, that this is not a duplicate of How do you make a matrix out of vectors in eigen?. I don't want to initialy construct the matrix but append to an existing one. Or is there maybe a trick, how to use the comma initialization in this case? The following code will fail:

Matrix2Xd mat(2,3);
Vector2d vec;
mat << 1, 1, 1, 1, 1, 1;
vec << 2, 2;

cout << mat << endl;
mat << vec;             // <-- crashes here
cout << mat << endl;

Edit: The following works, but I don't like the need of a temporary variable for such a basic task. Is there a better way?

Matrix2Xd tmp(2, mat.cols()+1);
tmp << mat, vec;
mat = tmp;
Burtburta answered 10/12, 2014 at 15:30 Comment(7)
You did read the first answer in the dupe: "The matrix m mus have been properly resized first."? An Eigen Matrix has a resize member function... Documentation can be googled, or read, at the least.Cherie
@Cherie resize does not keep the content of the matrix. If I do mat.resize(2, mat.cols()+1);, the matrix is filled with some random values afterwards.Burtburta
Then you'll need to either create a temporary or initialize it to the correct size.Cherie
@Cherie The size is not known in the beginning, so this is not possible. I hoped there is a better solution than copying all the data to a temporary :/Burtburta
There is no data structure (that is contiguous in memory, as would be wanted for a numerical matrix) that fullfills your needs. What sizes are we talking about?Cherie
@Cherie Well, for example the matrix class of the Armadillo library has insert_cols() and insert_rows(), so I hoped there is something similar in Eigen. But I'm happy with ggaels answer, so I think we can end this discussion.Burtburta
just so you know, those functions might well reallocate the memory, you're just "hiding" that fact from plain view. See e.g. this question for some more info.Cherie
L
41

You can use conservativeResize for that purpose:

mat.conservativeResize(mat.rows(), mat.cols()+1);
mat.col(mat.cols()-1) = vec;
Lath answered 10/12, 2014 at 21:28 Comment(2)
Thanks, this is working. I figured out that it is even possible to write mat.conservativeResize(NoChange, mat.cols()+1); which lets the number of rows unchanged.Burtburta
Is this approach recommended from a performance perspective? As I understand, conservativeResize() will allocate memory again and copy old data to the new location. Suppose we need to append multiple vectors to the matrix, does this method suffer from performance loss significantly?Humphries

© 2022 - 2024 — McMap. All rights reserved.