Eigen conservativeResize strange behavior
Asked Answered
L

1

5

I am using m.conservativeResize() to do the equivalent in Eigen as the reshape function in MatLab. So let N = 3, and then...

static MatrixXd m(N*N,1);

and then I assign this matrix some values, and it looks like this:

1
1
0
1
0
1
0
1
1

and then try to reshape it...

m.conservativeResize(N,N);

So now the same values should be there, but now in N rows and N columns rather than N*N rows and one column.

However that's not what I get. The first column has the first three values in the column vector - OK so far - but then the remaining values just look like garbage values from uninitialized memory:

1  3.08116e-309      0.420085
1 -2.68156e+154    1.2461e-47
0 -2.68156e+154      0.634626

Any idea what I am doing wrong?

Lowrey answered 27/8, 2015 at 21:8 Comment(0)
S
10

conservativeResize() doesn't ``move" the elements around (in other words, doesn't work like MATLABs reshape, since it performs memory re-allocation even if the initial and final sizes are the same). From the documentation:

Resizes the matrix to rows x cols while leaving old values untouched.

...

Matrices are resized relative to the top-left element. In case values need to be appended to the matrix they will be uninitialized.

These statements seem a bit confusing. What it means is the following: think about the initial matrix as a rectangle, of size A x B. Then think about the resized matrix as another rectangle of size C x D. Then mentally overlap the two rectangles, making sure the top-left corner is common to both. The common elements of the intersection are the ones that are preserved by the conservativeResize. The rest just correspond to uninitialized memory.

In case you want a true reshaping, use resize() instead (making absolutely sure that A x B == C x D, otherwise reallocation takes place and all bets are off).

Sanmicheli answered 28/8, 2015 at 1:54 Comment(6)
Very many thanks for your answer! I used resize() and that works. Cheers!Lowrey
BTW, how does resize work in Eigen? Is it computationally expensive? Or is it just a matter of changing the way the array is indexed?Lowrey
@AaronSchurger It is not expensive whenever the old and new sizes are compatible (A x B == C x D). In this case, no re-allocation is made, only the view is changed. Otherwise, a reallocation takes place, without copying the elements.Sanmicheli
I agree that the statement is confusing. I thought that it means that the original matrix coefficients would remain unchanged during the transfer to a new matrix, which is exactly the opposite from what it does.Slay
@Sanmicheli If no re-allocation is made, how is resize() compared with Eigen::Map? i.e. eigen.tuxfamily.org/dox/group__TutorialReshapeSlicing.htmlSlay
@AlanWang resize() doesn't do re-allocation only if A*B == C*D. In this case it behaves like Map. Otherwise resize() re-allocates and all elements are lost (unlike conservativeResize() which keeps old elements).Sanmicheli

© 2022 - 2024 — McMap. All rights reserved.