I'm wondering whether there's a better way to achieve what I'm doing here. I have an arma matrix and I want to reorder all of it's columns by the indices stored in a uvec
vector. I think I'm basically copying the whole matrix.
#include <armadillo>
using namespace arma;
int main(){
// get a discrete random matrix
// defined umat because eventually want to
// order by a given column OF A. irrelevant now.
umat A = randi<umat>(4,6,distr_param(0,3));
std::cout << "A " << std::endl;
std::cout << A << std::endl;
// get an index vector with the now row order
uvec b;
b << 3 << 2 << 1 << 0;
std::cout << "sort by b:" << std::endl;
std::cout << b << std::endl;
// get all col indices
uvec cols = linspace<uvec>(0,A.n_cols-1,A.n_cols);
// order ALL cols of A by b
// I'm afraid this just makes a copy
A = A.submat(b, cols );
std::cout << "reordered A by b" << std::endl;
std::cout << A << std::endl;
return 0;
}
You are right in that the code creates a new matrix A and does not exchange the rows in place.
Alternatively you could express the permutation as a product of transpositions and then swap the rows of A
one-by-one with swap_rows
. This is of course not trivial to implement and I would only go this route if memory usage is of concern or if you only need to permute a few of the rows and will leave the rest as they are. Otherwise rebuilding the matrix will probably be faster due to cache efficiency.
For your example case, which just reverses the row order, you might of course want to swap the last and first row, then the last-1'th and the 2nd and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With