Search code examples
matlabcell-array

how to sum the elements specified by a cell in matlab?


I have a big matrix M (nxm). I am going to sum some elements which are specified by index stored in vector as cell elements. There are many groups of indices so the cell has more than one element. For example

M = rand(2103, 2030);
index{1} = [1 3 2 4 53 5 23 3];
index{2} = [2 3 1 3 23 10234 2032];
% ...
index{2032} = ...;

I am going to sum up all elements at index{1}, sum up all elements at index{2} ..., now I am using a loop

sums = zeros(1, 2032);
for n=1:2032
  sums(n) = sum(M(index{n}));
end

I am wondering if there is any way to use one-line command instead of a loop to do that. Using a loop is pretty slow.


Solution

  • Probably a classic use of cellfun

    sums = cellfun(@(idx) sum(M(idx)), index);
    

    EDIT: here is a benchmarking for a large case that shows that this approach is slightly slower than a for loop but faster than Eitan T's method

    M = rand(2103, 2030);
    index = cell(1, 2032);
    index{1} = [1 3 2 4 53 5 23 3];
    index{2} = [2 3 1 3 23 10234 2032];
    
    for n=3:2032
        index{n} = randi(numel(M), 1, randi(10000));
    end
    
    N = 1e1;
    sums = zeros(1, 2032);
    tic
    for kk = 1:N
        for n=1:2032
            sums(n) = sum(M(index{n}));
        end
    end
    toc
    
    tic
    for kk = 1:N
        sums = cellfun(@(idx) sum(M(idx)), index);
    end
    toc
    
    tic
    for kk = 1:N
        sums = cumsum(M([index{:}]));
        sums = diff([0, sums(cumsum(cellfun('length', index)))]);
    end
    toc
    

    results in

    Elapsed time is 2.072292 seconds.
    Elapsed time is 2.139882 seconds.
    Elapsed time is 2.669894 seconds.