Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Retrieving Indices of a vector whose elements fulfil a criteria

  1. May 10, 2010 #1
    I have a 100x1 vector A, and want to know the ten indices i for which A(i) are the greatest 10 values in A.

    I can find the values by:
    Code (Text):

    B = sort(A)
    B(1:10);
    But I don't know how to find the indices, apart from starting a new if loop which searches the entire matrix (which seems very time consuming).

    As another example, I have a matrix B which is 10,000x2 and I want to know the value of B(i,1) for which B(i,2) is the maximum value in the column vector B(:,2). Eg.

    Code (Text):
    >> B = [(5:0.1:5.9)',rand(10,1)]
    B =
       5.000000000000000   0.696266337082995
       5.100000000000000   0.093820026774866
       5.200000000000000   0.525404403859336
       5.300000000000000   0.530344218392863
       5.400000000000000   0.861139811393332
       5.500000000000000   0.484853333552102
       5.600000000000001   0.393456361215266
       5.700000000000000   0.671431139674026
       5.800000000000001   0.741257943454206
       5.900000000000000   0.520052467390387

    >> for i = 1:10
    if B(i,2) == max(B(:,2))
    B(i,1)
    end
    end
    ans =
       5.400000000000000
     
    However I think this is taking absolutely ages in my code (I need to find this 20bn times so it's definitely an area for optimisation). Is there a simpler way to find the indices?
     
  2. jcsd
  3. May 10, 2010 #2

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    It looks like you are using Matlab. Matlab's sort function can return two values, the sorted array and an array of permutation indices.
    Code (Text):
    [B,idx] = sort (A);
     
  4. May 10, 2010 #3
    I didn't realise sort had that second output! I've been using it for ages as well.

    Thanks for the fast response!
     
  5. May 12, 2010 #4
    Following on from this, is there any way to quickly find a specific row in a vector?

    For example, searching for the half-width half-maximum of a Gaussian

    Code (Text):

    >> x = -20:0.0001:20;
    >> f = 4*exp(-x.^2/3);
    >> time = cputime; for i = 200000:400001
    if abs(f(i) - max(f)/2) < 0.0001
    x(i)
    break
    end
    end; cputime-time
    ans =
        1.4420
    ans =
       45.2031
    ie. I can find the value but it takes a long time. 45 seconds is ordinarily fine but I need to perform this many, many times.

    Is there no "search" function?

    BTW. In the example I realise that there is probably no i such that f(i) = 2 exactly. If there is no answer to this question, would there be an answer if there did exist an i where f(i) = 2?
     
  6. May 12, 2010 #5

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    In the above example, you are calling max(f) 200,001 times, each invocation of which requires searching over a list of 400,001 elements. Of course that is slow. Cache the value of max(f) outside the loop and you will see a dramatic speed bump.
     
  7. May 12, 2010 #6
    What about instead of the loop, doing something like this (using your above definitions of f and x):

    [junk, halfwidthIndex] = min(abs(f - max(f)/2));
    x(halfwidthIndex)
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook