Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best way to sort all columns of an armadillo matrix by an index vector

Tags:

c++

armadillo

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;

}
like image 449
Florian Oswald Avatar asked Mar 24 '14 19:03

Florian Oswald


1 Answers

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.

like image 126
rerx Avatar answered Nov 16 '22 00:11

rerx