How to extract a number of diagonals of a matrix

조회 수: 25 (최근 30일)
S. David
S. David 2014년 6월 6일
편집: S. David 2014년 6월 7일
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

채택된 답변

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

댓글을 달려면 로그인하십시오.

추가 답변 (2개)

Cedric
Cedric 2014년 6월 7일
편집: Cedric 2014년 6월 7일
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
Cedric
Cedric 2014년 6월 7일
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 2014년 6월 7일
편집: S. David 2014년 6월 7일
I needed it full, because I need to left-multiply an N-by-1 vector by it for signal processing.

댓글을 달려면 로그인하십시오.


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

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Operating on Diagonal Matrices에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by