2016-02-22 11 views
6

Y = zeros(5000,10); è un vettore predefinito 5000 x 1 composto da numeri da 1 a 10;Esiste un modo migliore per implementare questo codice MATLAB?

for i= 1:size(Y,1) 
    Y(i,y(i)) = 1; 
end 

C'è un modo migliore e più semplice da implementare questo dato che il resto del mio codice è vettorializzare e non contiene alcun ciclo for

+2

Questo codice è probabilmente abbastanza veloce come è, perché si sta facendo davvero piccole cose all'interno. –

risposta

6

Si potrebbe utilizzare bsxfun:

bsxfun(@eq,y,[1:10]) 

Invece di il tuo codice, puoi creare ogni riga usando y(i)==[1:10] che viene infine incluso in bsxfun per vettorializzare.

Un'altra idea sarebbe quella di calcolo dell'indice:

Y((y-1).*5000+(1:5000).')=1; 
+2

Bella cattura @ Daniel. Comunque la matrice restituita sembra essere logica, anche se la si preassegnasse con 'zeros()'. Potrebbe essere necessaria una conversione 'double()'. – Alessiox

+0

E sul mio sistema è molto più lento del ciclo 'for' ... (con conversione) – zeeMonkeez

+0

per me, il' bsxfun() ', inclusa la conversione' double() ', impiega la metà del tempo rispetto al 'for' loop (0,002190s vs 0,005001s) – Alessiox

2

Si potrebbe utilizzare sub2ind:

Y(sub2ind(size(Y), 1:size(Y, 1), y')) = 1; 

Tuttavia, questo potrebbe in realtà essere un po 'più lento:

Y = zeros(5000,10); 
y = randi(10, 5000, 1); 

tic 
for jj = 1:1000 
    for i = 1:size(Y,1) 
     Y(i,y(i)) = 1; 
    end 
end 
toc 
% Elapsed time is 0.126774 seconds. 

tic 
for jj = 1:1000 
    Y(sub2ind(size(Y), 1:size(Y, 1), y')) = 1; 
end 
toc 
% Elapsed time is 0.139531 seconds. 

% @Daniel's solution 
tic 
for jj = 1:1000 
    Y = double(bsxfun(@eq, y, 1:10)); 
end 
toc 
%Elapsed time is 0.187331 seconds. 
2

Ecco un altro approccio: creare una matrice sparse utilizzando y come indici delle colonne, e poi convertire in full se necessario:

Y = full(sparse(1:numel(y), y, 1, numel(y), 10));