Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Armadillo, finding max index in each column

I'm searching for a way to find the index corresponding to the maximum of each column. My goal is to avoid loops and find a Matlabic solution using vectorized armadillo functions.

This can easily be done in Matlab with the following command : [~, maxIndices] = max(A);

In armadillo you have the member function : A.max( row_of_max_val, col_of_max_val); that give the location of the maximum in the whole matrix.

And the standalone function vec M = max(A); that outputs the maximum values of each column but not their indices.

But none of them is doing the trick.

Having columns maximum's indices could be used to write numerous algorithms in a more vectorized way. For example, it could be used in a Viterbi Decoding, or in a k-means clustering.

Obviously, this question can be generalized considering minimums instead of maximums and rows instead of columns.

Is someone thinking of an alternative solution ?

Best.

like image 235
jcolafrancesco Avatar asked Nov 04 '15 08:11

jcolafrancesco


3 Answers

I typically go with the submatrix views. Something along these lines :

using idx_type = arma::uword;
using namespace std;
using namespace arma;

template<typename T>
vector<idx_type>
colwise_max_idx(const Mat<T>& A) {
    vector<idx_type> res;
    for (idx_type i = 0; i != A.n_cols; ++i) {
        idx_type row_idx;
        A.col(i).max(row_idx);
        res.push_back(row_idx);
    }
    return res;
}
like image 132
downhillFromHere Avatar answered Nov 10 '22 10:11

downhillFromHere


Armadillo now has, .index_max() and .index_min() methods to find these indices, as of version 7.2.

like image 35
kedarps Avatar answered Nov 10 '22 12:11

kedarps


A not perfect answer would be something like :

uvec indices = find((A.each_row()-max(A)) == 0);

Problems :

  1. Multiple indices can be returned for a unique column in case the max element is present more than one time.
  2. Indices are given relatively to the first element of the matrix and not the first element of each column.
like image 1
jcolafrancesco Avatar answered Nov 10 '22 11:11

jcolafrancesco