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. 22 followers. lunamoonmoon (257) is leader.

8 Replies
825 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>...
> > 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>...
> > 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