2016-03-22 7 views
1

Ich frage mich, ob es möglich ist, doppelte bsxfun oder etwas ähnliches zu verwenden. Ich habe dieses Stück Code:Kann ich double forcycle by bsxfun vermeiden?

N = 5; 
prob = [0.1 0.2 0 0.1; 0 0 0.05 0.1; 0.2 0.2 0 0.1]; 
r = rand(size(prob,1),N); 

P = zeros(N, size(prob,1)); 
csm = cumsum(normP([zeros(size(prob,1),1),prob]),2); 

for i = 1:N 
P(i,:) = sum(bsxfun(@ge,r(:,i),csm),2); 
end 

Prob Matrix enthält Zeilen mit Elementen zwischen 0 und 1, wobei jede Reihe ist Wahrscheinlichkeitsverteilung (nach durch normP getan Normalisierung). Die erste Reihe der Wahrscheinlichkeitsmatrix wird verwendet, um das erste Element des Vektors P (Werte 1, 2 oder 4), die zweite Reihe für das zweite Element (Werte 3 oder 4) und so weiter zu erzeugen.

Ich habe bereits Vektorelemente für einen Vektor P vektorisiert, aber ich muss mehrere (N) Vektoren generieren. Es muss einen Weg geben, den Zyklus zu vermeiden.

Im Anhang gibt es die NormP-Funktion. Ich werde mich freuen, danke.

Michal Roubalik

P.S. Code of normP ist hier:

function nP = normP(P) 
% 
% Probability matrix normalization to hold sum of rows be equal to one 
% i.e. sum(nP,2) = ones(N,1) 
% 
% No dependencies 
srowP = sum(P,2); 
good = srowP>0; 
bad = ~good; 
nP = zeros(size(P)); 

% good case 
if any(good) 
    nP(good,:) = bsxfun(@rdivide, P(good,:), srowP(good)); 
end 
% bad case 
if any(bad) 
    nP(bad,:) = nan(size(P(bad,:))); 
end 
+1

Bevor Sie irgendwelche fortgeschrittenen Sachen wie 'bsxfun' anfassen, machen Sie die einfachen Optimierungen. 'cumsum (normP ([zeros (size (prob, 1), 1), prob]), 2)) ist ein Ausdruck, den du immer wieder in deiner Schleife auswertest, um ihn außerhalb deiner Schleife zu berechnen. – Daniel

+0

Und ersetzen Sie 'nP = Nullen (Größe (P));' mit 'nP = nan (Größe (P));', dann können Sie die '% bad case' löschen – Daniel

+0

danke, ich habe den Code auch geändert Ich habe Code in der Frage bearbeitet. Es ist jetzt ungefähr 30% schneller. :) –

Antwort

4

Hier ist ein Weg, Vektorisierung zu vervollständigen mit permute -

P = squeeze(sum(bsxfun(@ge,permute(r,[1 3 2]),csm),2)).' 

Erklärung

1) Drücken dim-2 von r zu dim-3 Position in singleton-dim bringen um dim=2. Also, wenn sie mit csm für bsxfun(@ge Betrieb gepaart, würden wir eine 3D Array als Ausgang haben, deren:

dim-1 : r, csm 's dim-1 
dim-2 : csm's dim-2 
dim-3 : r's dim-2 

2) Die ursprüngliche Operation hatte iterativen Ausgang mit dim-2 noch darstellt csm's dim-2 und sum-reduction entlang. Also müssen wir in unserer 3D-Array-Ausgabe entlang dim-2 summieren.

3) Die letzten Schritte beinhalten squeeze -s und transponieren, um der Art und Weise zu entsprechen, wie wir die Ausgabe P iterativ speichern.