Question

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;

}
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top