How to extract a number of diagonals of a matrix
    8 visualizzazioni (ultimi 30 giorni)
  
       Mostra commenti meno recenti
    
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
0 Commenti
Risposta accettata
  Star Strider
      
      
 il 6 Giu 2014
        10 Commenti
  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.
Più risposte (2)
  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
      
      
 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.
  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))
Vedere anche
Categorie
				Scopri di più su Linear Algebra in Help Center e File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!



