f



Diagonal of a matrix vector

I have a "matrix" with dimensions (n,n,M), which can be interpreted as
a vector of M n-by-n matrices. Is there a away for me to take the
diagonal of all these M matrices at once? I.e. taking the diagonal
only with respect to the first two dimensions.
0
Mauro
10/5/2010 7:23:31 PM
comp.soft-sys.matlab 211266 articles. 21 followers. lunamoonmoon (257) is leader. Post Follow

8 Replies
798 Views

Similar Articles

[PageSpeed] 55

Mauro <msmscarlatti@googlemail.com> wrote in message <f13aac49-c83e-432e-8697-60e7a8963834@x42g2000yqx.googlegroups.com>...
> I have a "matrix" with dimensions (n,n,M), which can be interpreted as
> a vector of M n-by-n matrices. Is there a away for me to take the
> diagonal of all these M matrices at once? I.e. taking the diagonal
> only with respect to the first two dimensions.

Like this:

M = repmat(magic(4),[1 1 4]);
M(logical(repmat(eye(4),[1 1 4])))
0
Sean
10/5/2010 7:35:27 PM
Another solution

%%Fake data
n=4;M=3;
A=rand(n,n,M),


%Put the diagonals  of each slice in columns of "Diags";

idx=bsxfun(@plus,(1:n+1:n^2).',(0:M-1)*n^2);

Diags= reshape( A(idx) , n,[]) ,  %the result
0
Matt
10/5/2010 8:11:21 PM
Thanks to both of you, but I did not explain very clearly: what I
actually need is to replace each matrix in the "vector" with its
diagonal version.
0
Mauro
10/5/2010 8:20:15 PM
Mauro <msmscarlatti@googlemail.com> wrote in message <06c553f7-b981-49c1-b937-5763c8f12af1@x42g2000yqx.googlegroups.com>...
> Thanks to both of you, but I did not explain very clearly: what I
> actually need is to replace each matrix in the "vector" with its
> diagonal version.
======


theResult=bsxfun(@times,A,eye(n)),
0
Matt
10/5/2010 8:30:41 PM
"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <i8g1th$kuf$1@fred.mathworks.com>...
> Mauro <msmscarlatti@googlemail.com> wrote in message <06c553f7-b981-49c1-b937-5763c8f12af1@x42g2000yqx.googlegroups.com>...
> > Thanks to both of you, but I did not explain very clearly: what I
> > actually need is to replace each matrix in the "vector" with its
> > diagonal version.
> ======
> 
> 
> theResult=bsxfun(@times,A,eye(n)),

Or:
n = 400;
m = 300;

A = repmat(magic(n),[1 1 m]);
theResult2 = A.*repmat(eye(n),[1 1 m]);

Though the bsxfun solution is much faster:

tic
theResult2 = A.*repmat(eye(n),[1 1 m]);
toc
tic
theResult1=bsxfun(@times,A,eye(n));
toc
isequal(theResult1,theResult2)
%{
Elapsed time is 8.480145 seconds.
Elapsed time is 0.877621 seconds.

ans =

     1
%}
0
Sean
10/5/2010 8:40:09 PM
"Matt J " <mattjacREMOVE@THISieee.spam> wrote in message <i8g1th$kuf$1@fred.mathworks.com>...
> Mauro <msmscarlatti@googlemail.com> wrote in message <06c553f7-b981-49c1-b937-5763c8f12af1@x42g2000yqx.googlegroups.com>...
> > Thanks to both of you, but I did not explain very clearly: what I
> > actually need is to replace each matrix in the "vector" with its
> > diagonal version.
> ======
> 
> 
> theResult=bsxfun(@times,A,eye(n)),

Probably not an issue with OP, but the above does not clear any inf or NaN values from the off-diagonal positions in the array ... they persist even after multiplying by 0. An alternate method that does clear these values from the off-diagonal elements is:

X = repmat(logical(eye(n)),1,M);
A(~X) = 0;

James Tursa
0
James
10/5/2010 9:26:19 PM
"James Tursa" <aclassyguy_with_a_k_not_a_c@hotmail.com> wrote in message <i8g55r$qme$1@fred.mathworks.com>...

> Probably not an issue with OP, but the above does not clear any inf or NaN values from the off-diagonal positions in the array ... they persist even after multiplying by 0. An alternate method that does clear these values from the off-diagonal elements is:
> 
> X = repmat(logical(eye(n)),1,M);
> A(~X) = 0;
> 
=============

True, but because I'm so anti-REPMAT, I would opt for the following,

idx=bsxfun(@plus,(1:n+1:n^2).',(0:M-1)*n^2);
B=zeros(size(A));
B(idx)=A(idx);
0
Matt
10/5/2010 9:38:21 PM
Thank you very much for all your help, guys!
0
Mauro
10/6/2010 10:56:23 AM
Reply: