take line sum of part of matrix
1 visualización (últimos 30 días)
Mostrar comentarios más antiguos
Hi all!
I'm trying to use (as always) vectorized commands but came to a problem which looks quite simple at the beginning. Let me give you an example.
A = [1, 2, 54, 4, 5, 6; ...
1, 2, 88, 4, 5, 6; ...
1, 2, 0, 4, 5, 6; ]; % identical rows except for column 3
b = [5;2;6];
The values in b give the last column in A I want to build the line-sum for: My result should give me
c = ??? = [1+2+54+4+5;
1+2;
1+2+0+4+5+6];
Thank you for your help!
0 comentarios
Respuesta aceptada
Daniel Shub
el 25 de Sept. de 2012
Editada: Daniel Shub
el 25 de Sept. de 2012
There are a number of ways to do this. A fully vectorized way is with cumsum, but it has a lot of extra calculations so may not be best, especially since MATLAB loops are no longer slow.
A = [1, 2, 54, 4, 5, 6; ...
1, 2, 88, 4, 5, 6; ...
1, 2, 0, 4, 5, 6; ];
b = [5;2;6];
Then get the cumulative sum of each row from the beginning to the end.
x = cumsum(A')';
Then extract the values you want.
x(sub2ind(size(x), 1:3, b'))
Solution 2
Give the rows are all identical except for the third column, you can cheat a little bit. If we leave out the 3rd column, then we only need to sum the first row up to the max of b.
maxb = max(b);
n = 3;
x = cumsum(A(1, [1:(n-1), (n+1):maxb]))';
If every element of b was less than 3, we could do
x(b)
If the every element of b was greater than or equal to 3, we could do something like
x(b-1)+*A(:, 3)
where we need to subtract the 1 from the index to account for the fact that we skipped the third column. These two statements can be combined into a single statement with a weight vector that tells us if b is greater or less than 3 (n).
w = (b >= n);
Then we adjust the indices
c = b;
c(w) = b(w)-1;
and finally get the answer
x(c)+w.*A(:, 3)
4 comentarios
Daniel Shub
el 3 de Oct. de 2012
Of course it is. I am curious as to what lead me to that strange construct and why I didn't notice.
Matt Fig
el 3 de Oct. de 2012
Mat,
I find ARRAYFUN almost always slower than loops and CELLFUN almost always faster. Strange but true. CELLFUN with the string args is very fast indeed.
Más respuestas (3)
Matt Fig
el 25 de Sept. de 2012
Editada: Matt Fig
el 25 de Sept. de 2012
Another:
% Given data
A = [1, 2, 54, 4, 5, 6;...
1, 2, 88, 4, 5, 6;...
1, 2, 0, 4, 5, 6];
b = [5;2;6];
% The method
R = size(A,1); % Just to be general.
S = cumsum(A,2); % The cumulative sum.
S = S((1:R).' + (b-1)*R) % The desired values.
0 comentarios
Thomas
el 25 de Sept. de 2012
A = [1, 2, 54, 4, 5, 6; 1, 2, 88, 4, 5, 6; 1, 2, 0, 4, 5, 6; ];
b = [5;2;6];
for ii=1:length(b)
sumA(ii)=sum(A(ii,1:b(ii)));
end
sumA
0 comentarios
Andrei Bobrov
el 25 de Sept. de 2012
A = [1, 2, 54, 4, 5, 6; ...
1, 2, 88, 4, 5, 6; ...
1, 2, 0, 4, 5, 6; ];
b = [5;2;6];
s = size(A);
q = zeros(s);
q((b - 1)*s(1) + (1:s(1))') = 1;
i1 = bsxfun(@times,fliplr(cumsum(fliplr(q),2)),(1:s(1))');
t = i1>0;
out = accumarray(i1(t),A(t));
0 comentarios
Ver también
Categorías
Más información sobre Logical en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!