1k5
1k5

Reputation: 352

How to swap columns in eigen3 SparseMatrix

What is an efficient way to swap columns in a ColMajor eigen SparseMatrix?

I have tried the following:

SparseMatrix<mpz_class,ColMajor> H;
SparseVector<mpz_class> v;

// Somehow initialize H.

v = H.col(i);
H.col(i) = H.col(j);
H.col(j) = v;

which I think is not correct (assignment doesn't make a copy I assume?) I don't actually understand why this doesn't work, while e.g. the following does seem to work as intended:

v = H.col(i); w = H.col(j);
H.col(i) = s*v + t*w;  // s, t are some mpz_class elements.

A way which actually works is:

SparseMatrix<mpz_class,ColMajor> H, H_;
PermutationMatrix<Dynamic,Dynamic> P;
P.setIdentity();
P.applyTranspositionOnTheRight(i,j);
H_ = H; H = H_ * P;

Now this I assume makes a copy of the entire matrix H? So I would prefer the first method, or some efficient H *= P in place permutation. Or something like swap(H.col(i),H.col(j)).

Upvotes: 1

Views: 3756

Answers (1)

ggael
ggael

Reputation: 29205

The problem with the first version is that H is being partly modified before reading to the H.col(j) object (which is now invalid). You can workaround by copying both columns first:

Hi = H.col(i);
Hj = H.col(j);
H.col(i) = Hj;
H.col(j) = Hi;

Of course, it would be better to support H.col(i).swap(H.col(j)) as for dense matrices...

Also, if you apply numerous swap, then better fill them in a Eigen::Transpositions, convert it to a Eigen::PermutationMatrix and apply it once (or directly compute a unique permutation).

Upvotes: 5

Related Questions