2013-03-22 26 views
7

Qualcuno sa cosa sta succedendo in questo semplice codice usando parfor in matlab? Grazie,Matlab parfor loop indexing

ho affettato una matrice in quattro matrici e desiderano aggiornare elementi in ogni matrice indipendentemente

Ecco una versione semplice:

a = zeros(4,4); 
parfor i = 1:4 
    j = 2;  
    a(j,i) = 3; 
end 

errore: indici validi per 'a' sono limitati in cicli parfor;

tuttavia,

funziona:

a = zeros(4,4); 
parfor i = 1:4 
    a(2,i) = 3; 
end 

un'altra versione non lavorativo semplice con lo stesso errore:

a = zeros(4,4); 
parfor i = 1:4 
    a(i,i) = 3; 
end 

nella mia domanda, indice j viene generato in modo indipendente per ogni matrice attraverso alcuni algoritmo

+1

Sembra che non sia possibile impostare altre variabili indice all'interno del ciclo. Vedi: http://www.mathworks.com/matlabcentral/newsreader/view_thread/162203 – cyang

+0

quale versione di matlab stai usando? – alrikai

+0

Anche se non ce l'ho nella mia versione di MATLAB, penso che sia degno dare un'occhiata a 'parpool' - http://www.mathworks.it/it/help/distcomp/parpool.html –

risposta

1

Quello che stai cercando di ottenere sembra non essere possibile

Secondo la documentazione MATLAB:

When you use other variables along with the loop variable to index an array, you cannot set these variables inside the loop. In effect, such variables are constant over the execution of the entire parfor statement. You cannot combine the loop variable with itself to form an index expression.

MATLAB Documentation Source

Quindi tutte le variabili che si utilizza per indicizzare il tuo array, altro che la variabile del ciclo devono essere costante per l'intero ciclo.

+0

Vedo. Ho visto che è possibile annidare un ciclo for all'interno di un parfor per indicizzare un array 2D. La variabile del ciclo "for", ad esempio: per j = 1: 4 {a (i, j) = ..} può cambiare all'interno del ciclo parfor: for i = 1: 4 {}. Mi sembra che j sia uguale per tutte le iterazioni, è sicuro. In effetti, ho trovato questo nel documento che si riferisce: "Elenco indice fisso - All'interno della parentesi o delle parentesi di primo livello, l'elenco degli indici è lo stesso per tutte le occorrenze di una determinata variabile (variabile affetta)". –

2

Solo i miei due centesimi: come @mmumbos ha già spiegato, ciò che stai cercando di ottenere non è possibile in questo modo, ma alcuni metodi alternativi possono ancora essere applicati.

Supponiamo è necessario implementare qualcosa di simile alla seguente (che è la permutazione di una trasformazione lineare di matrice A):

n=10; 
A=rand(n,n); 
B=zeros(n,n); 
parfor i=1:n, 
    j=(i<=5)*(2*(i-1)+1)+(i>5)*(2*(i-5)); 
    B(j,i) = my_function(A(i,:)); 
end 

Prova invece la seguente:

parfor i=1:n, 
    B_temp(i,:) = my_function(A(i,:)); 
end 

Quindi, è non è davvero necessario costruire la matrice B; è possibile accedervi utilizzando B_temp utilizzando un '' tavolo indice '' che è semplicemente costruito come segue:

J=zeros(n,1); 
parfor i=1:n, 
    J(i) = (i<=5)*(2*(i-1)+1)+(i>5)*(2*(i-5)); 
end 

Poi B(i) si accede tramite B_temp(J(i)).

Rivisitare il tuo ultimo esempio (contatore), vediamo come è possibile lavorare intorno:

n=4; 
diag_A = zeros(n,1); 
parfor i=1:n, 
    diag_A(i)=3; % or any function of i 
end 

Poi, ogni volta che è necessario per accedere al '' i '' - esimo elemento diagonale di A, l'accesso invece diag_A(i).Per tali casi è conveniente creare una funzione secondo le seguenti linee:

function a = access_matrix(A, diag_A, i, j) 
    if (i!=j), 
    a = A(i,j); 
    else 
    a = diag_A(i); 
    end 
end 

Fino MATLAB migliora l'implementazione di parfor, saranno (purtroppo) essere necessarie tali soluzioni alternative in molti casi.

+0

La seconda sezione di codice utilizzata per costruire 'B_temp' causa un errore in Matlab (R2016a). –

+0

@ErikM Grazie mille - hai effettivamente trovato un refuso. Il lato sinistro avrebbe dovuto essere 'B_temp (i, :)' invece di 'B_temp (i, i)' –

0

Poiché non è stato ancora menzionato, ecco un collegamento che è davvero utile per diagnosticare questi tipi di problemi: Classification of Variables in Parfor. Questi problemi sorgono quando MATLAB non è in grado di classificare le variabili nelle definizioni rigide definite in tale pagina.

Quello che sta accadendo qui è che non sa come suddividere la "variabile di sezione" A prima del ciclo. Pensa di programmare tu stesso l'implementazione parallela. Quello che vorresti fare è tagliare A in parti uguali che sai che gli altri processori non toccheranno, e poi darli a diverse CPU per agire in modo indipendente. MATLAB osserva il tuo ciclo e non sa come farlo perché non sa che cosa è j finché non esegue il programma. È una limitazione di MATLAB. Un altro caso in cui accade la stessa cosa se si utilizzano coefficienti complessi come A (i * j, :). Ancora una volta non sa come dividerlo.