Home > Software design >  Updating a matrix from list of redundant indices
Updating a matrix from list of redundant indices

Time:06-29

I have a matrix A, a list of indices is and js, and a list of values to add to A, ws. Originally I was simply iterating through A by a nested for loop:

for idx = 1:N
    i = is(idx);
    j = js(idx);
    w = ws(idx);
    A(i,j) = A(i,j)   w;
end

However, I would like to vectorize this to increase efficiency. I thought something simple like

A(is,js) = A(is,js)   ws

would work, and it does as long as the is and js don't repeat. Said differently, if I generate idx = sub2ind(size(A),is,js);, so long as idx has no repeat values, all is well. If it does, then only the last value is added, all previous values are left out. A concrete example:

A = zeros(3,3);
indices = [1,2,3,1];
additions = [5,5,5,5];
A(indices) = A(indices)   additions;

This results in the first column having values of 5, not 5,5,10.

This is a small example, but in my actual application the lists of indices are really long and filled with redundant values. I'm hoping to vectorize this to save time, so going through and eliminating redundancies isn't really an option. So my main question is, how do I add to a matrix from a given set of redundant indices? Alternatively, is there another way of working through this without any sort of iteration?

CodePudding user response:

To emphasize a nice property of accumarray (accumarray actually works with two indices)

With the example from Luis Mendo:

is = [2 3 3 1 1 2].';
js = [1 3 3 2 2 4].';
ws = [10 20 30 40 50 60].';

A3 = accumarray([is js],ws);


%% A3 =

%%   0    90     0     0
%%  10     0     0    60
%%   0     0    50     0

CodePudding user response:

If I understand correctly, you only need full(sparse(is, js, ws)). This works because sparse accumulates values at matching indices.

% Example data
is = [2 3 3 1 1 2];
js = [1 3 3 2 2 4];
ws = [10 20 30 40 50 60];

% With loop
N = numel(is);
A = zeros(max(is), max(js));
for idx = 1:N
    i = is(idx);
    j = js(idx);
    w = ws(idx);
    A(i,j) = A(i,j)   w;
end

% With `sparse`
A2 = full(sparse(is, js, ws));

% Check
isequal(A, A2)
  • Related