2016-07-22 9 views
0

Ich habe Stück Code mit einer While-Schleife. Diese Schleife wird unter bestimmten Bedingungen divergieren und somit eine Endlosschleife ergeben.MATLAB: Überprüfen Sie auf While-Schleife Divergenz

Ich möchte überprüfen, ob die Schleife divergierend ist und die Schleife in einem eleganten und effizienten Verfahren unterbrechen.

Eine Lösung besteht darin, jeden Ausgang der Schleife zu prüfen, zu speichern und mit der zuvor berechneten Schleifenausgabe zu vergleichen.

Dies ist der Code:

ai = 0; 
ai_old = 100; 
iteration = 0; 
CDeff = 0; 

while abs(ai - ai_old)>2*10^-1            % Get induced angle of attack 

    iteration = iteration +1; 
    ai_old = ai; 

    Cleff = (Clp * cosd(ai)^2 + CDeff * sind(ai))/cosd(ai); 
    Veff = Vp/cosd(ai); 
    Re_eff = Reinf * Veff/Vinf * cp/c; 
    Meff = Mp/cosd(ai); 

if iteration ==1 
    AFdata(:,2) = AFdata(:,2)/cosd(SweepQC); 
end 

     [~,a_eff,CDeff] = obj.ConstantVortex(AFdata,[],Cleff,Meff); 
     ai = -a_eff + (AOA + Twists(zz))/cosd(SweepQC); 

end 

Hier ai mit der Funktion berechnet wird obj.ConstantVortex und mit den zuvor berechneten ai verglichen. Die while-Schleife wird beendet, wenn die Differenz klein genug ist. Es kann jedoch vorkommen, dass der Unterschied zwischen dem ursprünglichen ai und dem berechneten ai mit jeder Iteration zunimmt.

Wie kann ich das überprüfen? und die Schleife entsprechend unterbrechen?

Danke

Antwort

0

Eine typische Lösung für diese Situation besteht darin, mehr vorherige Werte zu speichern und das Verhalten im Zeitverlauf zu überwachen. Anstatt also ai_old, verwenden Sie:

ai = 0; 
num_prev = 5; % how many previous results to check 
ai_prev = zeros(1,num_prev); 
iteration = 0; 

while abs(ai - ai_prev(end))>2*10^-1 

    iteration = iteration+1; 
    % your loop code goes here 

    % now update the array of previous values 
    ai_prev = circshift(ai_prev,[0 -1]); 
    ai_prev(end) = ai; 

    if iteration > num_prev && all(sign(diff(ai_prev))) 
     % the slope of the previous five results is positive, so exit 
     break 
    end 
end 

Sie können die Anzahl der bisherigen Ergebnisse ändern und verwenden, was Funktion ist geeignet für eine Pause Zustand zu überprüfen, auf die Daten in ai_prev für Ihre Berechnung. Zum Beispiel möchten Sie vielleicht etwas über die vorherigen Ergebnisse mitteln oder eine andere Funktion als diff() verwenden.

+0

Hey, ai_prev = Nullen [1 num_prev]; Dies ist ein ungültiger Matlab-Befehl. Auch && all (sign (diff (ai_prev))) ist keine korrekte Definition für eine if-Anweisung, da sie nur eine Zahl und keine Bedingung liefert. –

+0

@BalrajBoyal danke dafür; bearbeitet, um Tippfehler mit Nullen zu korrigieren(). Die Anweisung 'all' gibt eine wahr/falsch-Bedingung zurück, so dass die Anweisung korrekt ausgewertet wird. – mhopeng

+0

@ Mhopeng, Oh Entschuldigung, das war mir nicht bewusst. Vielen Dank! –

0

Eine Lösung ist letzte Differenzen oder Unterschiede min zu halten und die Stromdifferenz mit dem vergleichen. Zum Beispiel können Sie die Variable ai_older haben und sie verwenden. Sie können

ai_older = 1000; 

vor Ihrer while-Schleife hinzufügen und dann

ai_older = ai_old; 
ai_old = ai; 

haben und while Zustand

while abs(ai - ai_old)>2*10^-1 && abs(ai - ai_old) < abs(ai_old - ai_older) 

Jetzt können Sie Divergenz vermeiden ändern. Allerdings ist mir Ihr Problem nicht vollständig bekannt und nicht sicher, ob abs erforderlich ist oder nicht.

Wie bereits erwähnt, möchten Sie vielleicht je nach Problem den minimalen Unterschied beibehalten und den aktuellen vergleichen.

+0

HALLO, sollten Sie ai_old nicht vor der Schleife definieren? –

+0

Definitiv müssen Sie es vor der Schleife definieren. Obwohl es sich in jeder Iteration ändert, ist es für den ersten Eintritt in die Schleife notwendig. –