michalsol
michalsol

Reputation: 752

Index of maximum value element in each row (last index)

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?

Upvotes: 3

Views: 724

Answers (3)

Adriaan
Adriaan

Reputation: 18177

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.

Upvotes: 4

Divakar
Divakar

Reputation: 221504

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)

Upvotes: 4

Luis Mendo
Luis Mendo

Reputation: 112659

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;

Upvotes: 4

Related Questions