Using accumarray for a weighted average?

451 Views Asked by At

accumarray in Matlab is amazing, and I use it often. I have a problem where the function I would like to pass to accumarray is a weighted average. i.e. it takes in two vectors, not a single vector. This appears to be a use case not supported by accumarray.

Is my understanding correct?

Consider, the function weightedAverage

function [ result ] = weightedMean( values, weights)

result = sum(values(:).*weights(:)) / sum(weights(:));

end

Now, we want to run accumarray as follows:

subs    = [1 1 1 2 2 3 3 3];
vals    = [1 2 3 4 5 6 6 7];
weights = [3 2 1 9 1 9 9 9];

accumarray(subs, [vals;weights],[], @weightedMean)

but matlab returns:

Error using accumarray
Second input VAL must be a vector with one element for each row in SUBS, or a scalar. 
1

There are 1 best solutions below

0
Suever On BEST ANSWER

You are correct, the second input must be either a column vector or a scalar. Rather than passing your data to accumarray, you can pass an array of indices which you can then use to index into your values and weights vectors from within the anonymous function which computes your weighted average.

inds = [1 1 2 2 3 3].';
values =  [1 2 3 4 5 6];
weights = [1 2 1 2 1 2];

output = accumarray(inds(:), (1:numel(inds)).', [], ...
                    @(x)sum(values(x) .* weights(x) ./ sum(weights(x))))
%    1.6667
%    3.6667
%    5.6667