How to extract a number of diagonals of a matrix

Hello all,
I have an N-by-N matrix. I want to extract the main diagonal and d diagonals to its right and d diagonals to its left and null all other elements. How can I do that?
Thanks

 Accepted Answer

The diag function can do everything you want. You just have to ask it!

10 Comments

I need a 2d+1 loops with this function like:
FNew=zeros(N);
for d=-3:3
FNew=diag(diag(F,d),d); % F is the original matrix
end
Is there a way without using a for loop?
Every time I’ve needed to do something like that, I used a loop.
I don’t understand the nested diag call. You only need to call it once. You’re apparently also not saving FNew. You need to save it in a cell array, e.g. ‘FNew{d} = ...’ if you want to use it later. (Cell array because they’re not all the same lengths.)
According to MATLAB help:
1- D = diag(v,k) places the elements of vector v on the kth diagonal. k=0 represents the main diagonal, k>0 is above the main diagonal, and k<0 is below the main diagonal.
2- x = diag(A,k) returns a column vector of the elements on the kth diagonal of A.
I need to put the kth diagonal of F (diag(F,d) from point 2) on the kth diagonal of FNew (FNew=diag(diag(F,d),d) from point 1). It works just fine.
Some times I need to include a large number of diagonals, and I was thinking of doing it without for loop if possible.
OK. But if the kth diagional of FNew is the kth diagonal of F, why not just do:
FNew = F;
What am I missing here?
I want to create from F (whose elements are not zero) a new matrix that has 2d+1 diagonals that are the same diagonals of F, while all other elements in FNew are set to zero.
I’m lost. F is (4x4), so that means FNew is (10x10) with zeros along its diagonals that aren’t congruent with the sizes of the diagonals of F?
Cedric
Cedric on 7 Jun 2014
Edited: Cedric on 7 Jun 2014
I may be wrong, but as far as I understand, he just wants to create a band matrix Fnew based on F.
Thanks Cedric Wannaz. Yes it is a banded matrix from F, that is the term.
Thank you. Please add your vote to Cedric’s answer.
I didn’t catch the banded matrix. It’s been a while since I encountered them.

Sign in to comment.

More Answers (2)

Cedric
Cedric on 7 Jun 2014
Edited: Cedric on 7 Jun 2014
Sparse, SPDIAGS - Here is a version using sparse matrices and SPDIAGS
Original, dense matrix:
>> N = 5 ;
>> A = randi( 10, N, N )
A =
9 1 2 2 7
10 3 10 5 1
2 6 10 10 9
10 10 5 8 10
7 10 9 10 7
Define diag ID "amplitude":
>> d = 1 ; % => -1,0,1 => band of width 3.
Build band sparse matrix:
>> Aband = spdiags( spdiags(A, -d:d), -d:d, N, N )
Aband =
(1,1) 9
(2,1) 10
(1,2) 1
(2,2) 3
(3,2) 6
(2,3) 10
(3,3) 10
(4,3) 5
(3,4) 10
(4,4) 8
(5,4) 10
(4,5) 10
If you needed to have it full despite the large amount of 0s (for large values of N):
>> Aband = full( Aband )
Aband =
9 1 0 0 0
10 3 10 0 0
0 6 10 10 0
0 0 5 8 10
0 0 0 10 7
Note that there is a processing time overhead when you deal with sparse matrices, which is compensated by the gain in efficiency (when N is large) due to the fact that only non-zero elements are stored/processed. For small values of N though, I would consider Star Strider's solution based on a loop with full matrices, or the solution below.
Dense, TRIL - Here is another "dense" solution based on TRIL and logical indexing (I am using the same A as above, and I display intermediary steps so you can see the logic):
>> id = logical( tril( ones(N), d ))
id =
1 1 0 0 0
1 1 1 0 0
1 1 1 1 0
1 1 1 1 1
1 1 1 1 1
>> id = id & id.'
id =
1 1 0 0 0
1 1 1 0 0
0 1 1 1 0
0 0 1 1 1
0 0 0 1 1
>> A(~id) = 0
A =
9 1 0 0 0
10 3 10 0 0
0 6 10 10 0
0 0 5 8 10
0 0 0 10 7
If you really need to optimize your code, I'd advise you to implement the 4 or 5 solutions presented in this thread, and time them specifically for your case.

3 Comments

Note that most built-ins in MATLAB support sparse matrices, so if N is large and d is small in comparison, it is in your interest not to transform back to full unless really needed.
I needed it full, because I need to left-multiply an N-by-1 vector by it for signal processing.

Sign in to comment.

Or triu and tril
x = magic(10);
n = 3;
x = x(tril(ones(size(x)),n)&triu(ones(size(x)),-n))

1 Comment

Still I want the new matrix to be N-by-N by nulling all elements not in the selected diagonals.

Sign in to comment.

Tags

Asked:

on 6 Jun 2014

Edited:

on 7 Jun 2014

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!