I've been given the task of translating a piece of MATLAB code into IDL and have hit a roadblock when I came across the MATLAB function accumarry(). The function, described here is used to sum elements in one array, based on indices given in another. Example 1 perhaps explains this better than the actual function description at the top of the page. In trying to reproduce Example 1 in IDL, I haven't been able to avoid a for loop, but I'm confident that it is possible. My best attempt is the following:
vals = [101,102,103,104,105]
subs = [0,1,3,1,3]
n = max(subs)+1
accum = make_array(n)
for i = 0, n-1 do begin
wVals = where(subs eq i,count)
accum[i] = count eq 0 ? 0 : total(vals[wVals])
endfor
print,accum
; 101.000 206.000 0.00000 208.000
Any advice on improving this would be greatly appreciated! I expected IDL to have a similar built-in function, but haven't been able to track one down. Perhaps some magic with histogram binning?
I found a number of possible solutions to this problem on Coyote's IDL site (not surprisingly.) http://www.idlcoyote.com/code_tips/drizzling.html
I ended up using the following, as a compromise between performance and readability:
function accumarray,data,subs
mx = max(subs)
accum = fltarr(mx+1)
h = histogram(subs,reverse_indices=ri,OMIN=om)
for j=0L,n_elements(h)-1 do if ri[j+1] gt ri[j] then $
accum[j+om] = total(vals[ri[ri[j]:ri[j+1]-1]])
return,accum