Is there an easier way to index diagonal elements of a matrix?

50 vues (au cours des 30 derniers jours)
Darcy Cordell
Darcy Cordell le 27 Juil 2022
Commenté : Darcy Cordell le 28 Juil 2022
Let's say I have a 10 x 10 diagonal matrix of random integers between 0 and 100:
A = diag(randi(100,10,1));
I want to replace some of the diagonals with different values. In particular, I want to replace the 3rd, 6th, 7th, and 9th diagonal element with the value 1000.
One intuitive way to do this would be:
A([3 6 7 9],[3 6 7 9]) = 1000;
But this doesn't work because MATLAB reads this as replacing matrix entries (3,3), (3,6), (3,7), (3,9), (6,3), (6,6), (6,7), (6,9), and so on.
One way that does work is to go:
v = diag(A);
v([3 6 7 9]) = 1000;
A = diag(v);
But this seems kind of clunky with double calls to "diag" and the additional variable "v" needing to be stored in memory. Is there a more elegant way to do it using matrix indexing?
Thanks

Réponse acceptée

John D'Errico
John D'Errico le 27 Juil 2022
Modifié(e) : John D'Errico le 27 Juil 2022
A = diag(randi(100,10,1));
n = size(A,1);
A(sub2ind([n,n],[3 6 7 9],[3 6 7 9])) = 1000;
A
A = 10×10
56 0 0 0 0 0 0 0 0 0 0 52 0 0 0 0 0 0 0 0 0 0 1000 0 0 0 0 0 0 0 0 0 0 23 0 0 0 0 0 0 0 0 0 0 84 0 0 0 0 0 0 0 0 0 0 1000 0 0 0 0 0 0 0 0 0 0 1000 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 0 0 0 0 0 1000 0 0 0 0 0 0 0 0 0 0 33
If you understand how matrix elements are stored in memory, it is not that hard either, even if we avoid sub2ind. Next, I'll change them to 999.
ind = [3 6 7 9];
A(ind + (ind - 1)*n) = 999;
A
A = 10×10
56 0 0 0 0 0 0 0 0 0 0 52 0 0 0 0 0 0 0 0 0 0 999 0 0 0 0 0 0 0 0 0 0 23 0 0 0 0 0 0 0 0 0 0 84 0 0 0 0 0 0 0 0 0 0 999 0 0 0 0 0 0 0 0 0 0 999 0 0 0 0 0 0 0 0 0 0 25 0 0 0 0 0 0 0 0 0 0 999 0 0 0 0 0 0 0 0 0 0 33
  1 commentaire
Darcy Cordell
Darcy Cordell le 28 Juil 2022
Thanks! The linear indexing method is exactly the kind of nice solution I was looking for.

Connectez-vous pour commenter.

Plus de réponses (1)

David Hill
David Hill le 27 Juil 2022
Or linear indexing
n=20;%size of matrix
A = diag(randi(100,n,1));
c=[4 7 8 12];%places on the diagonal wanting to replace
A((c-1)*(n+1)+1)=1000;

Catégories

En savoir plus sur Creating and Concatenating 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