crobar
crobar

Reputation: 2929

How to circular shift a 2D Eigen Array?

What is the best (by which I mean the fastest and/or most efficient) way to perform a circular shift on a 2D Eigen array?

For example, I would like to circularly shift a ArrayXXd to the right. I think I can do something like the following:

circShiftRight (ArrayXXd &arraytoshift)
{
    Matrix<double, Dynamic, 1> tmp;

    tmp = arraytoshift.col (arraytoshift.cols ()-1);

    arraytoshift.rightCols(_radForceVelocity.cols()-1) = arraytoshift.leftCols(_radForceVelocity.cols()-1).eval ();

    arraytoshift.col(0) = tmp;
}

but will this work and is there a better way? I assume the .eval() is necessary to avoid Aliasing. I'm new to using the Eigen Library.

Upvotes: 3

Views: 1318

Answers (1)

duburcqa
duburcqa

Reputation: 1131

After searching for a while on the internet for a related problem (actually I was looking for a way to deleting columns / rows from matrices), I was not able to find a satisfying answer about how to implement efficient row/column shifting with Eigen, so I investigated by myself.

As I already suspected, aliasing is only an issue for one of the shifting direction while it is safe for the other one. To be more specific: aliasing is NOT an issue when shifting left/up the columns/rows of matrices. This holds true regardless if the matrix is row- and column-major. Yet, it is necessary to make an intermediary copy when shifting right or down. This means the only way to avoid temporary when shifting to the right / down is to perform the shift column-by-column / row-by-row in a sequential for-loop style, which is probably slower than copying the whole original matrix in a temporary then assigning as many colmuns / rows as possible at once.

This behavior comes from the way the low-level assignment is performed. I'm not sure it is part of the official documentation or an implementation details, but I'm quite sure I have already see this edge-case use somewhere in Eigen itself to avoid copies, so it is very likely to stay like this in the future.

Upvotes: 0

Related Questions