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 |

10/5/2010 7:23:31 PM

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 |

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 |

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 |

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 |

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 |

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 |

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 |

10/5/2010 9:38:21 PM

Thank you very much for all your help, guys!

0 |

10/6/2010 10:56:23 AM