tags:

views:

62

answers:

1

Suppose I have the following matrix:

01 02 03 06
03 05 07 02
13 10 11 12
32 01 08 03

And I want the indices of the top 5 elements (in this case, 32, 13, 12, 11, 10). What is the cleanest way to do this in MATLAB?

+2  A: 

There are a couple ways you can do this depending on how you want to deal with repeated values. Here's a solution that finds indices for the 5 largest values (which could include repeated values):

[sortedValues,sortIndex] = sort(A(:),'descend');  %# Sort the values in
                                                  %#   descending order
maxIndex = sortIndex(1:5);  %# Get a linear index into A of the 5 largest values

Here's a solution that finds the 5 largest unique values, then finds all elements equal to those values:

sortedValues = unique(A(:));          %# Unique sorted values
maxValues = sortedValues(end-4:end);  %# Get the 5 largest values
maxIndex = ismember(A,maxValues);     %# Get a logical index of all values
                                      %#   equal to the 5 largest values
gnovice
Actually, there is no need to do the last step posed by gnovice. The second output of sort is a list of tags for the sort. So the index of those selected values is given by the corresponding tags from the sort. If you wish for the index in terms of a pair of subscripts, then call ind2sub.
woodchips
@woodchips: Good catch. I was in the process of changing it as you commented, as well as adding another option to deal with repeated values in a different way.
gnovice
This method is probably the cleanest for small matrices, but clearly sub-optimal for large matrices since sorting scales like O(N*log(N)) while doing it the "non Matlab way" would scale like O(N).
Adrien
UNIQUE already returns sorted values and in vector format, so just `unique(A)` in the first line should work.
yuk
@yuk: Good catch. Fixed.
gnovice

related questions