3 votes

Comment réinitialiser le "triangle inférieur" d'une matrice à 3 dimensions ?

Je dois remettre à zéro le "triangle inférieur" d'une matrice à trois dimensions. Cela signifie que si la matrice originale est :

C(:,:,1) = [1 2 3 ;  2 4 6  ;  3  6  9]

C(:,:,2) = [2 4 6 ;  4 8 12 ;  6 12 18]

C(:,:,3) = [3 6 9 ;  6 12 18 ; 9 18 27]

Alors la matrice résultante devrait être :

C(:,:,1) = [1 2 3 ;  2 4 6  ;  3  6  9]

C(:,:,2) = [0 0 0 ;  4 8 12 ;  6 12 18]

C(:,:,3) = [0 0 0 ;  0 0 0  ;  9 18 27]

Une idée de la façon dont cela peut être fait ? (Ma matrice originale à 3 dimensions est grande)

Merci !

6voto

Suever Points 52199

Le système intégré triu ne peut pas traiter ce tableau 3D mais vous pouvez le faire dans une simple boucle.

for k = 2:size(C, 3)
    C(1:k-1,:,k) = 0;
end

4voto

Luis Mendo Points 32011

Vous pouvez générer un masque 2D, permute ses dimensions, et multiplier avec l'expansion singleton utilisant bsxfun :

result = bsxfun(@times, C, permute((1:size(C,1)).'>=(1:size(C,2)), [1 3 2]));

Ou, à partir de la version R2016b, vous pouvez supprimer bsxfun grâce à expansion automatique des singleton :

result = C .* permute((1:size(C,1)).'>=(1:size(C,2)), [1 3 2]);

1voto

Franz Hahn Points 192

En supposant que vous ayez une matrice 3D "carrée" (c'est-à-dire NxNxN comme dans votre message original 3x3x3), vous pouvez également utiliser le remodelage et la reproduction :

Edit : puisque repmat est trop lent, je l'ai remplacé par une implémentation bsxfun.

[a,b,c] = size(C)
D = reshape(tril(ones(a)),[a,1,a]);
F = ones(1,size(E,1));
D = bsxfun(@times,D,F);
C(~D)=0;

J'ai également procédé à une comparaison rapide des trois solutions proposées. La solution de @LuisMendo ne fonctionne pas pour moi, il y a une erreur de dimension de la matrice dans la comparaison >= (les tailles [1 N] et [N 1] sont comparées).

Entre ma solution et celle de @Suever, la sienne est nettement plus rapide :

Comparing the three methods with variable size Cs:
Suever's version (for loop):
Took 0.3529s to compute.
Took 0.0002s to compute size 3x3x3.
Took 0.0008s to compute size 10x10x10.
Took 0.0008s to compute size 50x50x50.
Took 0.0455s to compute size 250x250x250.
Took 0.3055s to compute size 500x500x500.
My version (reshape/repmat):
Took 0.9086s to compute.
Took 0.0522s to compute size 3x3x3.
Took 0.0042s to compute size 10x10x10.
Took 0.0017s to compute size 50x50x50.
Took 0.1060s to compute size 250x250x250.
Took 0.7445s to compute size 500x500x500.

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