2010-08-09 18 views
9

im non è un programmatore, ho solo bisogno di risolvere qualcosa numericamente in MATLAB. Ho bisogno di una funzione di rendere la seguente trasformazione per qualsiasi matrice quadrata:trasformare una matrice in un vettore lungo le sue diagonali

da

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

a

1 4 2 7 5 3 8 6 9 

cioè scrivere la matrice in un vettore lungo le diagonali da sinistra a destra sopra . qualche idea per favore?


ho davvero bisogno di un piccolo aiuto però:

dire la matrice che abbiamo trasformato nel vettore, contiene voci indicate con M (i, j), dove i sono righe e colonne j. ora ho bisogno di essere in grado di scoprire da una posizione nel vettore, la posizione originale nella matrice, cioè se la sua terza entrata nel vettore, ho bisogno di una funzione che mi dia i = 1 j = 2. qualche idea per favore? im veramente bloccato su questo :(grazie

risposta

3

Ecco un modo per fare questo

%# 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

La chiamata a BSXFUN non è necessaria.Si può semplicemente fare 'sort (hh (:))' per ottenere il vettore dell'indice. – gnovice

+0

Grazie, @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

È possibile generare le diagonali in questo modo:.

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

Non lo so se questo è il modo ottimale per concatenare le diagonali:

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

(l'ho provato in ottava, non in MATLAB)

2

È possibile convertire la matrice in un vettore utilizzando la funzione HANKEL per generare indici nella matrice. Ecco una versione ridotta di Jonas' answer, utilizzando M come matrice del campione dato sopra:

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

Ora, è possibile utilizzare sortIndex per cambiare la matrice M ad un vettore vec in questo modo:

vec = M(sortIndex); 

E se si desidera ottenere gli indici di riga e colonna (rIndex e cIndex) nella matrice originale che corrisponde ai valori in vec, è possibile utilizzare la funzione IND2SUB:

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

Questo è molto simile ad una previous question sulla attraversa la matrice in un ordine zigzag. Con leggera modifica otteniamo:

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 

utilizzando la funzione SPDIAGS. Il vantaggio di questo è che funziona per qualsiasi dimensione di matrice arbitraria (non solo matrici quadrate). Esempio:

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 
Problemi correlati