Reputation: 59
I have a matrix like A and I want to calculate the sum of each diagonal of this matrix and show it in a vector like Y.
A=[1 2 3; 4 5 6; 7 8 9]
Y=[3 8 15 12 7]
I know the code
[sum(diag(y,2)),sum(diag(y,1)),sum(diag(y,0)),sum(diag (y,-1)),sum(diag (y,-2))]
but i want to write it as a function.
Upvotes: 3
Views: 1621
Reputation: 125854
Similar to the answer from rahnema1, you can also generate your indices using toeplitz
before applying accumarray
:
[r, c] = size(A);
index = toeplitz(c:(r+c-1), c:-1:1);
Y = accumarray(index(:), A(:)).';
Upvotes: 1
Reputation: 15837
Here is a possible solution:
[r ,c]=size(A);
idx=bsxfun(@plus,(r:-1:1)',0:c-1);
s=flipud(accumarray(idx(:),A(:)));
Comparing this with spdiags
that proposed in other answer this method performs much much better in Octave. Benchmark:
A = rand(1000);
disp('---------bsxfun+accumarray----------')
tic
[r ,c]=size(A);
idx=bsxfun(@plus,(r:-1:1)',0:c-1);
s=flipud(accumarray(idx(:),A(:)));
toc
disp('---------spdiags----------')
tic
dsum = fliplr(sum(spdiags(A)));
toc
Result:
---------bsxfun+accumarray----------
Elapsed time is 0.0114651 seconds.
---------spdiags----------
Elapsed time is 8.62041 seconds.
Upvotes: 3