Obtaininig an array, which corresponds to one one of the diagonals of a given matrix, without using loops

2 vues (au cours des 30 derniers jours)
I have a matrix mXm, like the following (5X5):
1 2 0 8 5
1 2 3 8 7
8 5 0 3 5
6 7 4 8 2
1 2 0 4 5
I want to obtain an array which holds, for example, only the term from the diagonal which starts at 0 from the top (sorry for not knowing the mathematical terminology for this), namely: A= [0 8 5] .
Otherwise, I could also ask for the terms from the diagonal which starts at 2 (again, that's probably not the correct terminology, but hopefuly it is clear from the example): B=[2 3 3 2].
Is there a nice and efficient way to do this, without using loops?
By the way: I am not asking for diagonals that start from terms in the left-most coloumn, since if there's an algorithim for the above, then these diagonals could be obtained from the transposed matrix (right?)
Thanks!

Réponse acceptée

Guillaume
Guillaume le 28 Mar 2019
Use the diag function:
M = [1 2 0 8 5
1 2 3 8 7
8 5 0 3 5
6 7 4 8 2
1 2 0 4 5]
>> diag(M, 2) %return 2nd upper diagonal
ans =
0
8
5
>> diag(M, -1) %return 1st lower diagonal
ans =
1
5
4
4

Plus de réponses (1)

Walter Roberson
Walter Roberson le 28 Mar 2019
diag() is a good easy solution. But another approach sometimes works out better, especially when you are vectorizing code.
MATLAB arrays are stored in memory with adjacent elements going down the columns. So A(1,1) is stored first in memory, and then A(2,1) is stored right be side that, and the third is A(3,1) and so on. In your 5 x 5 matrix, after A(5,1) the array would store A(1,2), then A(2,2), A(3,2) and so on.
If you count from the top corner, A(1,1) as being index 1, then A(2,1) being index 2, A(5,1) being index 5, then A(1,2) would be index 6, A(2,2) would be index 7, and so on. If you write this out and look at the pattern, you would see that the index for a particular entry is exactly 5 (the number of rows!) greater than the index of the element to its left:
1 6 11 16 21
2 7 12 17 22
3 8 13 18 23
4 9 14 19 24
5 10 15 20 25
Now consider any one location, and look at the index of the position diagonally down and to the right of it: it is 6 greater (number of rows, plus 1) than the index of the location. For example, diagonally down and to the right of 8 is 14, which is 8+5+1 .
This is a general rule: if you know the index of one element, idx, then diagonally down and to the right of it is (idx+rows+1), and down and right of that is (idx+2*(rows+1)), then (idx+3*(rows+1)) and so on until you reach the end of the array.
This leads to expressions such as A(6 + (rows+1).*(0:3)) to go diagonally down and to the right of location 6
This kind of manipulation of indexes by knowing that diagonal down and right is idx+rows+1 and diagonal up and right is idx+rows-1, can be very useful in contexts such as finite element analysis where you want to vectorize calculations that involve elements and the adjacent and diagonal elements relative to them .
[idx-rows-1 idx-1 idx+rows-1
idx-rows idx idx+rows
idx-rows+1 idx+1 idx+rows+1]
  1 commentaire
Erez
Erez le 29 Mar 2019
Thanks for the great and detailed answer! I've accepted the simplest, simply because it's simpler..

Connectez-vous pour commenter.

Catégories

En savoir plus sur Operating on Diagonal Matrices dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by