Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomly permute rows/columns of a matrix with eigen

I'm using Eigen and I've got a matrix:

MatrixXi x = MatrixXi::Random(5);

I'd like to randomly permute the rows and columns using a randomly drawn permutation (just one permutation for both the rows and columns), i.e. if I have a permutation that sends indices [0,1,2,3,4] -> [3,4,2,1,0] than I want to reorder the rows and the columns with the same permutation.

Part 1: I can't find an example of PermutationMatrix online, and I'm having trouble figuring out the syntax.

Part 2: how do I obtain a randomly permuted vector of indices to pass to it? Maybe std::random_shuffle?

update:

Here is a (probably inefficient) way to get a shuffled set of indices:

std::vector<int> perm;
for (int i=0; i<5; ++i) {
    perm.push_back(i);
}

std::random_shuffle(perm.begin(), perm.end());

So now the question is how I do reorder my matrix x so that it's rows/columns are ordered by perm?

update 2:

Getting closer, this works (source for ideas: cplusplus.com):

int myrandom (int i) { return std::rand()%i;}

PermutationMatrix<Dynamic,Dynamic> perm(5);

perm.setIdentity();
for (int i=dim-1; i>0; --i) {
    swap (perm.indices()[i],perm.indices()[myrandom(i+1)]);
}

cout << "original x" << x << endl << endl;
cout << "permuted x" << perm * x * perm << endl << endl;

Anyone know how to do this with random_shuffle? (see attempt that didn't work below.)

(Bonus: any thoughts on whether perm * x * perm will be efficient if perm is a 1e4 x 1e4 matrix?)

like image 943
stackoverflax Avatar asked Apr 07 '13 03:04

stackoverflax


1 Answers

Using std::random_shuffle is perfectly fine, then you have to use a PermutationMatrix:

PermutationMatrix<Dynamic,Dynamic> perm(size);
perm.setIdentity();
std::random_shuffle(perm.indices().data(), perm.indices().data()+perm.indices().size());
A_perm = A * perm; // permute columns
A_perm = perm * A; // permute rows
like image 180
ggael Avatar answered Oct 13 '22 22:10

ggael