Search code examples
matlabaccumarray

Using accumarray for a weighted average?


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. 

Solution

  • 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