3

I need to find index of maximum element in each row in matrix in MATLAB. Something like

[~,indexes] = maxValues = max(p_y_x,[],2);

works fine, but I need to get LAST index (when there is more than one with maximum value). Now I have something like this:

N=size(p_y_x,1);
maxValues = max(p_y_x,[],2);
indexes=zeros(1,N);

for n=1:N
   indexes(n)=find(p_y_x(n,:)==maxValues(n),1,'last');
end

Which is complicated and not very efficient (because of the for loop).

I doubt something that trivial must be done that way. Is there a more optimal solution?

Adriaan
  • 17,741
  • 7
  • 42
  • 75
michalsol
  • 752
  • 8
  • 29

3 Answers3

4

You can use linear indexing to get the last index of the maximum by finding all maximum values within a row, then using the index of the last to index the original column:

N=size(p_y_x,1);

for n=1:N
   [~, indices(n)] = max(fliplr(p_y_x(n,:))); %// find maxima in a row
end
indices= size(p_y_x,2)-indices+1;

Since the new execution engine was introduced in MATLAB R2015b for loops are no longer very slow, and this is the intuitive way of doing this. Omitting the time consuming find will probably be the largest efficiency improvement you can make.

Note that I renamed indexes to indices, as that is the Latin plural.

Community
  • 1
  • 1
Adriaan
  • 17,741
  • 7
  • 42
  • 75
4

Let bsxfun and accumarray help you out -

[r,c] = find(bsxfun(@eq,p_y_x,max(p_y_x,[],2)))
indexes = accumarray(r,c,[],@max)

If you are a fan of one-liners, for fun you could also do -

[~,indexes] = max(cumsum(bsxfun(@eq,p_y_x,max(p_y_x,[],2)),2),[],2)
Divakar
  • 218,885
  • 19
  • 262
  • 358
4

The same code for finding the first occurrence works for the last if you flip the array horizontally and then correct the indices:

[~, indexes] = max(fliplr(p_y_x),[],2);
indexes = size(p_y_x,2)-indexes+1;
Adriaan
  • 17,741
  • 7
  • 42
  • 75
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147