Rank: 4418 based on 19 downloads (last 30 days) and 3 files submitted
photo

Marcus Björk

E-mail
Company/University
Uppsala University

Personal Profile:

 

Watch this Author's files

 

Files Posted by Marcus Björk View all
Updated   File Tags Downloads
(last 30 days)
Comments Rating
05 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk general, signal processing, matrices 8 5
04 Nov 2013 meanDiag The mean over each diagonal (or anti-diagonal) of a 2D matrix returned in a vector Author: Marcus Björk signal processing, matrices, general 7 0
01 Nov 2013 Vandermonde matrix, vander() function extension Adds functionality to the original MATLAB vander() function. Author: Marcus Björk signal processing, matrix 4 3
Comments and Ratings by Marcus Björk View all
Updated File Comments Rating
05 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk

That's true Sven. I added 3D matrix support now, if anyone has an application for that.
In my case the code was used in an iterative algorithm, in which case the matrix is not known beforehand and cannot be stored in a 3D matrix. I figured the code was nice enough to make a function out of it and upload it here.

02 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk

Forgot to mention: If you need to compute the sum of diagonals for several matrices of the same size (in another loop), which was the application at hand, this for-loop free implementation is also faster (well, the inlined version). See below:

Test code:
%Input
K=1000;
A=randn(1000,100);

%Common
[N,M]=size(A);

%% Method 1
tic;
d = 1-N:M-1;
out = zeros(M+N-1,1,class(A));

for k=1:K
for p = 1:length(d)
out(p) = sum(diag(A,d(p)));
end
A=randn(N,M);
end
toc

%% Method 2
tic;
Amod=zeros(N+M-1,M);
logVec = [false(M-1,1);true(N,1);false(M-1,1)];
indMat = bsxfun(@plus, (1:M+N-1)',0:M-1);
logMat = logVec(indMat);

for k=1:K
Amod(logMat)=A;
sumVec=sum(Amod,2);
A=randn(N,M);
end
toc

>>
Elapsed time is 2.632392 seconds.
Elapsed time is 1.307457 seconds.

02 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk

Thanks for your comment Sven!
I had the for-loop implementation already, which is trivial, but was posed with the problem of solving it without a for-loop. Hence, I wrote this code. (Which could perhaps be optimized further?)
Didn't actually check which was faster, and I should probably make a note of this in the description.

Furthermore, you don't get the anti-diagonals by transposing. But rot90(A) works and is almost as fast as using the extra input.

01 Nov 2013 Vandermonde matrix, vander() function extension Adds functionality to the original MATLAB vander() function. Author: Marcus Björk

Thanks for the comments guys! Indeed, its a bad idea to REPLACE vander with this function, so I changed the name and made a note in the text. However, one of the points was to use the normal definition, so I won't change that. I also added bsxfun instead of the for-loop, that was just bad...

Comments and Ratings on Marcus Björk's Files View all
Updated File Comment by Comments Rating
05 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk Marcus Björk

That's true Sven. I added 3D matrix support now, if anyone has an application for that.
In my case the code was used in an iterative algorithm, in which case the matrix is not known beforehand and cannot be stored in a 3D matrix. I figured the code was nice enough to make a function out of it and upload it here.

03 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk Sven

Ha, but if you used the sumDiags() function itself multiple times you wouldn't actually get your speedup :)

I'd say if that's the goal then perhaps you can rewrite sumDiags to take in a 3D matrix and give the output as the sum of diags of each sheet.

In the little tests I ran I found that the sum(diag()) loop was about twice as fast for square matrices and about equal for really wide (10x10000) matrices.

Oh, and yep you're right that rot90() is the way to go for anti-diagonals :)

02 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk Marcus Björk

Forgot to mention: If you need to compute the sum of diagonals for several matrices of the same size (in another loop), which was the application at hand, this for-loop free implementation is also faster (well, the inlined version). See below:

Test code:
%Input
K=1000;
A=randn(1000,100);

%Common
[N,M]=size(A);

%% Method 1
tic;
d = 1-N:M-1;
out = zeros(M+N-1,1,class(A));

for k=1:K
for p = 1:length(d)
out(p) = sum(diag(A,d(p)));
end
A=randn(N,M);
end
toc

%% Method 2
tic;
Amod=zeros(N+M-1,M);
logVec = [false(M-1,1);true(N,1);false(M-1,1)];
indMat = bsxfun(@plus, (1:M+N-1)',0:M-1);
logMat = logVec(indMat);

for k=1:K
Amod(logMat)=A;
sumVec=sum(Amod,2);
A=randn(N,M);
end
toc

>>
Elapsed time is 2.632392 seconds.
Elapsed time is 1.307457 seconds.

02 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk Marcus Björk

Thanks for your comment Sven!
I had the for-loop implementation already, which is trivial, but was posed with the problem of solving it without a for-loop. Hence, I wrote this code. (Which could perhaps be optimized further?)
Didn't actually check which was faster, and I should probably make a note of this in the description.

Furthermore, you don't get the anti-diagonals by transposing. But rot90(A) works and is almost as fast as using the extra input.

02 Nov 2013 sumDiag Sum over each diagonal (or anti-diagonal) in a matrix Author: Marcus Björk Sven

Hi Marcus,

Nice entry, but sometimes a for-loop can be useful. The function below is simpler, uses less memory (no extra matrices or masks needed), and is actually more efficient (faster).

function out = sumDiag(A)
d = 1-size(A,1):size(A,2)-1;
out = zeros(size(d),class(A));
for k = 1:length(d)
out(k) = sum(diag(A,d(k)));
end

I chose the opposite convention, whereby the first element of the output is the lower left rather than upper right. I think this fits in with MATLAB's convention of numbering diagonals as lower to the left and higher to the right, but you can change it easily if you'd like on the first line.

Also, I think that the anti-diagonals case should really just be up to the user who can call sumDiag(A) or sumDiag(A'), as that is simpler for the same result than (possibly) providing an extra argument.

Contact us