2010-08-09 7 views
9

je ne suis pas un programmeur, j'ai juste besoin de résoudre quelque chose numériquement dans MATLAB. i besoin d'une fonction pour la transformation suivante pour toute matrice carrée:transformer une matrice en un vecteur le long de ses diagonales

de

row 1: 1 2 3 
row 2: 4 5 6 
row 3: 7 8 9 

à

1 4 2 7 5 3 8 6 9 

-à-dire écrire la matrice dans un vecteur le long de ses diagonales de gauche à droite en haut . des idées s'il vous plaît?


je vraiment besoin d'un peu plus d'aide si:

dire la matrice que nous avons transformé en vecteur, a des entrées notées par M (i, j), où i sont des lignes et des colonnes j. maintenant je dois être capable de trouver à partir d'une position dans le vecteur, la position d'origine dans la matrice, c'est-à-dire si sa 3ème entrée dans le vecteur, j'ai besoin d'une fonction qui me donnerait i = 1 j = 2. des idées s'il vous plaît? im vraiment coincé sur ce :(merci

Répondre

3

Voici une façon de le faire

%# n is the number of rows (or cols) of the square array 
n = 3; 
array = [1 2 3;4 5 6;7 8 9]; %# this is the array we'll reorder 

%# create list of indices that allow us 
%# to read the array in the proper order 
hh = hankel(1:n,n:(2*n-1)); %# creates a matrix with numbered antidiagonals 
[dummy,sortIdx] = sort(hh(:)); %# sortIdx contains the new order 

%# reorder the array 
array(sortIdx) 

ans = 
    1  4  2  7  5  3  8  6  9 
+0

L'appel à BSXFUN est inutile.Vous pouvez juste faire 'sort (hh (:))' pour obtenir le vecteur d'index. – gnovice

+0

Merci, @gnovice – Jonas

1
A=[1,2,3;4,5,6;7,8,9]; 
d = size(A,1); 
X=[]; 
for n = 1:2*size(A,1) - 1 
    j = min(n,d); i = (n+1)-(j); 
    X = cat(2,X,diag(flipud(A(i:j,i:j)))'); 
end 

X 
X = 
    1  4  2  7  5  3  8  6  9 
1

Vous pouvez générer les diagonales de cette façon.

for i = -2:2 
    diag(flipud(a), i) 
end 

Je ne sais pas que ce soit la manière optimale de concaténer les diagonales:

d = [] 
for i = -2:2 
    d = vertcat(d, diag(flipud(a), i)) 
end 

(je l'ai testé en octave, pas en matlab)

2

Vous pouvez convertir votre matrice en vecteur en utilisant la fonction HANKEL pour générer des indices dans la matrice. Voici une version abrégée de Jonas' answer, en utilisant M comme matrice de l'échantillon donné ci-dessus:

N = size(M,1); 
A = hankel(1:N,N:(2*N-1)); 
[junk,sortIndex] = sort(A(:)); 

Maintenant, vous pouvez utiliser sortIndex pour changer votre matrice M à un vecteur vec comme ceci:

vec = M(sortIndex); 

Et si vous voulez obtenir les indices de ligne et de colonne (rIndex et cIndex) dans votre matrice d'origine qui correspondent aux valeurs de vec, vous pouvez utiliser la fonction IND2SUB:

[rIndex,cIndex] = ind2sub(N,sortIndex); 
6

C'est tout à fait semblable à un previous question traversant sur la matrice dans un ordre en zigzag. Avec une légère modification que nous obtenons:

A = rand(3);      %# input matrix 

ind = reshape(1:numel(A), size(A)); %# indices of elements 
ind = spdiags(fliplr(ind));   %# get the anti-diagonals 
ind = ind(end:-1:1);    %# reverse order 
ind = ind(ind~=0);     %# keep non-zero indices 
B = A(ind);       %# get elements in desired order 

en utilisant la fonction SPDIAGS. L'avantage de ceci est qu'il fonctionne pour n'importe quelle taille de matrice arbitraire (pas seulement les matrices carrées). Exemple:

A = 
     0.75127  0.69908  0.54722  0.25751 
     0.2551  0.8909  0.13862  0.84072 
     0.50596  0.95929  0.14929  0.25428 
B = 
    Columns 1 through 6 
     0.75127  0.2551  0.69908  0.50596  0.8909  0.54722 
    Columns 7 through 12 
     0.95929  0.13862  0.25751  0.14929  0.84072  0.25428 
Questions connexes