MATLAB: Take line sum of part of matrix

sum of lines in matrixvectorize

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!

Best Answer

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)