46 votes

Comment assigner des valeurs sur la diagonale?

Supposons que je dispose d’une matrice NxN A, d’un vecteur d’indice V constitué d’un sous-ensemble des nombres 1: N et d’une valeur K, et que je souhaite procéder ainsi:

  for i = V
     A(i,i) = K
 end
 

Y a-t-il un moyen de faire cela en une seule déclaration avec vectorisation?

par exemple A ( quelque chose ) = K

L'instruction A(V,V) = K ne fonctionnera pas, elle affectera des éléments hors diagonale et ce n'est pas ce que je veux. par exemple:

 >> A = zeros(5);
>> V = [1 3 4];
>> A(V,V) = 1

A =

 1     0     1     1     0
 0     0     0     0     0
 1     0     1     1     0
 1     0     1     1     0
 0     0     0     0     0
 

63voto

Jonas Points 54073

J'ai l'habitude de l'utiliser les YEUX pour que:

A = magic(4)
A(logical(eye(size(A)))) = 99

A =
    99     2     3    13
     5    99    10     8
     9     7    99    12
     4    14    15    99

Alternativement, vous pouvez simplement créer la liste linéaire des indices, car, d'un élément de la diagonale à l'autre, il prend nRows+1 étapes:

[nRows,nCols] = size(A);
A(1:(nRows+1):nRows*nCols) = 101
A =
   101     2     3    13
     5   101    10     8
     9     7   101    12
     4    14    15   101

Si vous souhaitez accéder à un sous-ensemble des éléments de la diagonale, vous devez créer une liste de diagonale indices:

subsetIdx = [1 3];
diagonalIdx = (subsetIdx-1) * (nRows + 1) + 1;
A(diagonalIdx) = 203
A =
   203     2     3    13
     5   101    10     8
     9     7   203    12
     4    14    15   101

Alternativement, vous pouvez créer un index logique tableau à l'aide d' diag (fonctionne uniquement pour les tableaux carrés)

diagonalIdx = false(nRows,1);
diagonalIdx(subsetIdx) = true;
A(diag(diagonalIdx)) = -1
A =
    -1     2     3    13
     5   101    10     8
     9     7    -1    12
     4    14    15   101

24voto

ysap Points 2255
 >> tt = zeros(5,5)
tt =
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     0
>> tt(1:6:end) = 3
tt =
     3     0     0     0     0
     0     3     0     0     0
     0     0     3     0     0
     0     0     0     3     0
     0     0     0     0     3
 

et plus générale:

 >> V=[1 2 5]; N=5;
>> tt = zeros(N,N);
>> tt((N+1)*(V-1)+1) = 3
tt =
     3     0     0     0     0
     0     3     0     0     0
     0     0     0     0     0
     0     0     0     0     0
     0     0     0     0     3
 

Ceci est basé sur le fait que les matrices peuvent être accédées sous forme de tableaux unidimensionnels (vecteurs), où les 2 indices (m, n) sont remplacés par une application linéaire m * N + n.

2voto

Amro Points 72743
A = zeros(7,6);
V = [1 3 5];

[n m] = size(A);
diagIdx = 1:n+1:n*m;
A( diagIdx(V) ) = 1

A =
     1     0     0     0     0     0
     0     0     0     0     0     0
     0     0     1     0     0     0
     0     0     0     0     0     0
     0     0     0     0     1     0
     0     0     0     0     0     0
     0     0     0     0     0     0

2voto

Eran W Points 385

J'utiliserais sub2ind et transmettrais les indices de diagonale en tant que paramètres x et y:

 A = zeros(4)
V=[2 4]

idx = sub2ind(size(A), V,V)
% idx = [6, 16]

A(idx) = 1

% A =
% 0     0     0     0
% 0     1     0     0
% 0     0     0     0
% 0     0     0     1
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X