Azzera filtri
Azzera filtri

How to extract a number of diagonals of a matrix

14 visualizzazioni (ultimi 30 giorni)
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

Risposta accettata

Star Strider
Star Strider il 6 Giu 2014
The diag function can do everything you want. You just have to ask it!
  10 Commenti
S. David
S. David il 7 Giu 2014
Thanks Cedric Wannaz. Yes it is a banded matrix from F, that is the term.
Star Strider
Star Strider il 7 Giu 2014
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.

Accedi per commentare.

Più risposte (2)

Cedric
Cedric il 7 Giu 2014
Modificato: Cedric il 7 Giu 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 Commenti
Cedric
Cedric il 7 Giu 2014
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.
S. David
S. David il 7 Giu 2014
Modificato: S. David il 7 Giu 2014
I needed it full, because I need to left-multiply an N-by-1 vector by it for signal processing.

Accedi per commentare.


Sean de Wolski
Sean de Wolski il 6 Giu 2014
Or triu and tril
x = magic(10);
n = 3;
x = x(tril(ones(size(x)),n)&triu(ones(size(x)),-n))
  1 Commento
S. David
S. David il 6 Giu 2014
Still I want the new matrix to be N-by-N by nulling all elements not in the selected diagonals.

Accedi per commentare.

Categorie

Scopri di più su Sparse Matrices in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by