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 rando
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
As stated here: Stackoverflow:
If you can use C++11 I'd recommend implementing this without using
srand()
andrandom_shuffle()
; instead you should use the<random>
library withstd::shuffle
.First, if possible
rand
should be avoided. Aside from the fact that it isn't usually a very good pRNG, it also has problems with thread safety due to shared state. The<random>
library fixes both these problems by giving the programmer explicit control over pRNG state and by providing several options with guaranteed performance, size, and quality characteristics.Secondly,
random_shuffle
isn't actually specified to userand
so it's theoretically legal for reseeding usingsrand
not to have the effect you want. To get guaranteed results withrandom_shuffle
you have to write your own generator. Moving toshuffle
fixes that, as you can directly use standard engines.
#include <random> //seed generation
#include <algorithm> //shuffle()
int main() {
std::random_device r;
std::seed_seq rng_seed{r(), r(), r(), r(), r(), r(), r(), r()};
//create random engines with the rng seed
std::mt19937 eng1(rng_seed);
//create permutation Matrix with the size of the columns
Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> permX(inputX.cols());
permX.setIdentity();
std::shuffle(permX.indices().data(), permX.indices().data()+permX.indices().size(), eng1);
inputX = inputX * permX; //shuffle column wise
}
If you want to shuffle the rows use inputX.rows()
instead for the initialization of the Permutation Matrix. And use inputX = permX * inputX
instead.