More on finding the n smallest values of array
posted Tue 22 Jul 2014 by Michael Galloy under IDL, OptimizationAtle Borsholm recently posted a clever solution for finding the n-th smallest element in an array on the IDL Data Point. He compares this to a naive solution which simply sorts all the elements and grabs the n-th element:
IDL> tic & x = ordinal_1(a, 123456) & toc
% Time elapsed: 3.0336552 seconds.
His solution performs much better:
IDL> tic & x = ordinal_2(a, 123456) & toc
% Time elapsed: 0.46286297 seconds.
I have a HISTOGRAM
-based solution called MG_N_SMALLEST
in mglib that can do even better:
IDL> tic & x = mg_n_smallest(a, 123456) & toc
% Time elapsed: 0.18394303 seconds.
Note: MG_N_SMALLEST
does not return the n-th smallest element directly, but returns indices to the smallest n
elements.
I have a more detailed description of what MG_N_SMALLEST
is doing in an older article. I like this routine as a good example of using HISTOGRAM
and its REVERSE_INDICES
keyword. It also a nice example of when using a FOR
loop in IDL isn’t so bad.
I include even more detail on this routine in the “Performance” chapter of my book.
July 29th, 2014 at 9:05 am
Using a simple min() function might be even faster.
function ordinal_3,array,N
tmp = array
tmp1 = min(tmp,imin,max=tmp2)
ind = 0
tmp3 = tmp1
while (ind lt N) and (tmp3 lt tmp2) do begin
tmp[imin] = tmp2
tmp1 = min(tmp,imin)
if tmp1 gt tmp3 then begin
ind = ind+1
tmp3 = tmp1
endif
endwhile
return,tmp1
end
July 29th, 2014 at 9:14 am
Scrap my post. Only works for small N.