How to extract a number of diagonals of a matrix

28 visualizaciones (últimos 30 días)
S. David
S. David el 6 de Jun. de 2014
Editada: S. David el 7 de Jun. de 2014
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

Respuesta aceptada

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

Iniciar sesión para comentar.

Más respuestas (2)

Cedric
Cedric el 7 de Jun. de 2014
Editada: Cedric el 7 de Jun. de 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 comentarios
Cedric
Cedric el 7 de Jun. de 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 el 7 de Jun. de 2014
Editada: S. David el 7 de Jun. de 2014
I needed it full, because I need to left-multiply an N-by-1 vector by it for signal processing.

Iniciar sesión para comentar.


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

Iniciar sesión para comentar.

Categorías

Más información sobre Operating on Diagonal Matrices en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by