I am not very comfortable with using accumarray function in Matlab, though I have begun to appreciate its powers! I was wondering if I could input 2 cols in the VAL field of accumarray function. Please see –
sz = 3 ; % num_rows for each ID
mat1 = [1 20 ; 1 40 ; 1 50 ; 2 10 ; 2 100 ; 2 110] ; % Col1 is ID, Col2 is Value
idx = [30 1000 ; 30 1200 ; 30 1500 ; 30 1000 ; 30 1200 ; 30 1500 ] ;
% col1: index ID, col2: value
mat1 is ID returns while idx is index returns. For simplicity, idx returns are repeated to match mat1. All IDs in mat1 have same rows. Even idx has the same rows.
[~,~,n] = unique(mat1(:,1), 'rows', 'last') ;
fncovariance = @(x,y) (x.*y)/sz ;
accumarray(n, [x(:,2) y(:,2)], [], fncovariance) % --> FAILS as VAL is not-vector!
You can see that I’m trying to calculate covariance (cov(x,y,1)) but cannot use Matlab’s function directly as mat1 has IDs and I need covariance for each ID w.r.t Index.
Ansmat:
1 2444.4
2 7888.9
The short answer is no. In the
accumarray()help, the key part is:This means you can’t even fake it out by using cells.
However, if you put the IDs in their own index variable, and then reshape your data so that data corresponding to different IDs are in different columns, this problem can be efficiently handled by
bsxfun(). For reference, I also included a matrix math method, a simpleforloop method usingcov(), and acellfun()method using a customfncovariance()function (note I modified it from yours above).If you simulate some more data and time these different methods, the
bsxfun()way is the fastest:A final option you might be interested in is the
grpstats()function in the statistics toolbox, which lets you sweep out arbitrary statistics based on a grouping variable.