2012-09-28 12 views
6

Ho questo ciclo seguente per un codice (che calcola gli istogrammi). Sto scrivendo in Matlab. Dato che sono nuovo di Matlab, non conosco metodi più veloci per farlo. Attualmente sto scrivendoottimizzazione di matlab per loop

for i=1:size(b) 
    a(b(i)) = a(b(i)) + 1; 
end 

Ci sono metodi più veloci per fare questo, preferibilmente quelli che non richiedono il ciclo for?

+2

commento generale: 'size' non è la funzione giusta per quello che stai facendo ora, piuttosto usare [lunghezza] (http://www.mathworks.nl/help/matlab/ref/length.html) o [numel] (http://www.mathworks.nl/help/matlab/ref/numel.html). –

+2

L'idea che i cicli for-loop siano inefficienti/lenti e che, se possibile, dovrebbero essere sostituiti è infondata. Anche se è possibile sostituire questo codice con qualcosa che è più veloce, probabilmente si risparmia solo una frazione di secondo. Questo non è il livello di ottimizzazione del codice di cui dovresti preoccuparti. – Kavka

+0

@Kavka Per quanto riguarda questo tipo di ciclo for, sarei d'accordo. Un ciclo più complesso per manipolare matrici di grandi dimensioni varrebbe la pena di vettorializzare, giusto? Matlab è stato progettato per funzionare con le matrici: tutte le sue operazioni sulla matrice dovrebbero essere ottimizzate. – Derek

risposta

9

È possibile vettorializzare semplicemente tramite a(b) = a(b) + 1. Controllare quanto segue:

>> a = [1 2 3 4]; 
>> b = [2 4]; %# indices to modify. Be sure that they are in bounds. 
>> a(b) = a(b) + 1 

a = 

    1  3  3  5 

Se si utilizzano alcuni indici più volte, poi accumarray aiuterà come segue:

>> a = [1 2 3 4]; 
>> b = [2 4 2]; 
>> a = accumarray([1:numel(a) b].',[a ones(size(b))])' 

a = 

    1  4  3  5 

In alternativa, è possibile utilizzare:

>> a = [1 2 3 4]; 
>> b = [2 4 2]; 
>> b = accumarray(b.',ones(size(b))); 
>> a(nzIndex) = a(nzIndex) + b(nzIndex)' 

a = 

    1  4  3  5 

Vedere this nice answer qui per maggiori dettagli.

+0

Nel mio caso b potrebbe essere [2 4 2], quindi ho bisogno di incrementare un (2) due volte. Questo metodo aggiorna un (2) solo una volta. – anirudh

+0

Ho aggiornato la domanda di conseguenza. – petrichor

1

Se entrambi i modelli a e sono vettoriali, questo dovrebbe funzionare.

a = 1:100; 
b = 100:-1:1; 

a(b) = a(b) + 1;