14

I want to find the maximum values and indices by row of a matrix. I based this on an example on the eigen website (example 7).

#include <iostream>
#include <Eigen/Dense>

using namespace std;
using namespace Eigen;
int main()
{
    MatrixXf mat(2,4);
    mat << 1, 2, 6, 9,
           3, 1, 7, 2;

    MatrixXf::Index   maxIndex;

    VectorXf maxVal = mat.rowwise().maxCoeff(&maxIndex);

    std::cout << "Maxima at positions " << endl;
    std::cout << maxIndex << std::endl;
    std::cout << "maxVal " << maxVal << endl;
}

Problem here is that my line

    VectorXf maxVal = mat.rowwise().maxCoeff(&maxIndex);

is wrong. The original example has

    float maxNorm = mat.rowwise().sum().maxCoeff(&maxIndex);

i.e. there is an additional reduction .sum() involved. any suggestions? I guess I just want the eigen equivalent to what in matlab I would write as

[maxval maxind] = max(mymatrix,[],2)

i.e. find maximum value and it's index over the second dimension of mymatrix and return in a (nrow(mymatrix),2) matrix. thanks!

(sent to the eigen list as well, sorry for cross-posting.)

Florian Oswald
  • 5,054
  • 5
  • 30
  • 38

2 Answers2

13

My guess is that this is not possible without using a for loop using the current api. As you said yourself, you can get the vector of maximum row values using

VectorXf maxVal = mat.rowwise().maxCoeff();

As far as I can tell from the API Documentation for maxCoeff() it will only write back a single index value. Following code (untested) should give you what you want:

MatrixXf::Index   maxIndex[2];
VectorXf maxVal(2);
for(int i=0;i<2;++i)
    maxVal(i) = mat.row(i).maxCoeff( &maxIndex[i] );
Jakob
  • 2,360
  • 15
  • 21
  • hi jakob. yes, that's what i implemented in the meanwhile. thanks for your answer! I resorted to the eigen kde forum, since there don't seem to be many eigen users on SOF. – Florian Oswald Jul 19 '12 at 10:41
  • An option without using `MatrixXf::Index` would be int i, j; s = vector.minCoeff(&i); // s == vector[i] s = matrix.maxCoeff(&i, &j); // s == matrix(i,j) – Lxrd-AJ Jul 28 '18 at 17:11
  • Thank you for the insight. I know this question is outdated, but could you please elaborate on how to use maxIndex[] once it is initialized with the relevant indices? The current documentation of Eigen does not offer valuable insights on how to proceed with the type Eigen::Index, to actually index a matrix, or at least I failed to do so. – Abhinav Jun 01 '21 at 07:03
  • Eigen::Index is an integer type. I would assume you can access the indexed element as `mat(i, maxIndex[i])`. – Jakob Jun 02 '21 at 11:59
2

Besides the "for loop" solution by Jakob, you could also use libigl's igl::mat_max which functions like MATLAB's row-/column-wise max

Eigen::MatrixXf mat(2,4);
mat << 1, 2, 6, 9,
       3, 1, 7, 2;
Eigen::VectorXi maxIndices;
Eigen::VectorXf maxVals;
igl::mat_max(mat,2,maxVals,maxIndices);

Then maxVals would contain [9;7] and maxIndices would contain [3;2].

Community
  • 1
  • 1
Alec Jacobson
  • 6,032
  • 5
  • 51
  • 88