2013-06-19 15 views
5

Ho una matrice 6X4 M1 contenente solo zeri. Ho anche due array 1D Y1 e Y2 ciascuno con lunghezza 4. I due array contengono i valori indice desiderati. Ora, voglio impostare (convertire in 1) gli elementi della matrice M1 tale che M1(Y1:Y2) è uguale a 1Indicizzazione di array 2D in MATLAB

es: Y1=[1 2 2 1] e Y2=[3 4 5 3]
poi, M1 dovrebbe essere

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

posso fai questo usando per il ciclo. Ma c'è un modo ottimizzato per farlo? (Intendo utilizzare matrici molto più grandi)

risposta

6

ci possono essere OTH tecniche, ma questo usa operazioni di saggio elemento che sono follemente parallele.

Una soluzione molto semplice. Grazie @Shai

>> [rows, cols] = size(M); 
>> Y1=[1 2 2 1]; Y2=[3 4 5 3]; 
>> M = bsxfun(@ge, (1:rows)', Y1) & bsxfun(@le, (1:rows)', Y2) 
M = 
    1  0  0  1 
    1  1  1  1 
    1  1  1  1 
    0  1  1  0 
    0  0  1  0 
    0  0  0  0 

codice inutilmente complicato

[rows, cols] = size(M); 
offsets = ((1 : cols) - 1) * rows 
Y1 = offsets + Y1; 
Y2 = offsets + Y2; 

M = reshape(1:numel(M), rows, cols); 
M = bsxfun(@ge, M, Y1) & bsxfun(@le, M, Y2); 
+0

grande uso di 'bsxfun' - ma lo si può fare senza usare' offsets' – Shai

+0

@shai c'è ancora un bug, sto riparando esso. –

+0

una risposta per la mia domanda può essere trovata se si passa sopra il fondo della mia risposta ;-) – Shai

8

utilizzare cumsum!

>> szM = size(M1); 
>> M1(sub2ind(szM, Y1, 1:szM(2))) = 1 
M1 = 
1  0  0  1 
0  1  1  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
0  0  0  0 
>> M1(sub2ind(szM, Y2+1, 1:szM(2))) = -1 
M1 = 
1  0  0  1 
0  1  1  0 
0  0  0  0 
-1  0  0 -1 
0 -1  0  0 
0  0 -1  0 
>> M = cumsum(M,1) 
M = 
1  0  0  1 
1  1  1  1 
1  1  1  1 
0  1  1  0 
0  0  1  0 
0  0  0  0 

Un errore: Se uno qualsiasi degli Y2 uguale 6 rispetto all'impostazione Y2+1 a -1 supererà dimensione della matrice.
Per risolvere questo problema è possibile aggiungere due righe prima di impostare a -1 gli elementi di M:

>> cols = 1:szM(2); 
>> sel = Y2 < szM(1); 
>> M1(sub2ind(szM, Y2(sel)+1, cols(sel))) = -1 

uno spin-off per Pavan Yalamanchili's answer utilizzando bsxfun: (hover per vedere :)

utilizzando bsxfun senza offsets:
M1 = bsxfun(@ge, (1:size(M1,1))', Y1) & bsxfun(@le, (1:size(M1,1))', Y2);