WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Hängenbleiben in der for-Schleife

 

DerBesteMensch
Forum-Anfänger

Forum-Anfänger



Beiträge: 15
Anmeldedatum: 03.07.11
Wohnort: Lummerland
Version: ---
     Beitrag Verfasst am: 30.11.2011, 15:31     Titel: Hängenbleiben in der for-Schleife
  Antworten mit Zitat      
Hallo allerseits,

Ich habe ein ein etwas seltsames Problem, für das mir jede Erklärung fehlt. Das folgende Programm braucht wenige Sekunden um die gewünschte Konvergenzordnung eoc für ein gegebenes m (hier: m = 3) zu berechnen.

Nun möchte ich allerdings mit einer for-Schleife nacheinander die Konvergenzordnungen für m = 1, 2, ..., 6 berechnen. Obwohl für jedes fest vorgegebene m (d.h. ohne Schleife über m) die Rechenzeit jeweils nur wenige Sekunden beträgt, bleibt das Programm bei Verwendung einer for-Schleife bereits bei m = 2 stecken und nachdem 15 min lang nichts passiert ist, habe ich dann abgebrochen.

Wie kann sowas überhaupt möglich sein und was kann man dagegen tun?

Hier mein Programm:

Code:
function konvergenzordnung
t0 = 0;
y0 = 1;
tend = 1;
dt = 1/8;
n = 9;
m = 3

for k = 1:n
    v = (tend - t0)/dt;
    for i = 0:(m-1)        
        sol(i+1,1) = t0 + i*dt;
        sol(i+1,2) = exp(sol(i+1,1));            
    end
    for i = 0:(v-m)
        sol = bdf(i,m,dt,sol,t0);
    end
    err(k) = sol(length(sol(:,1)),2) - exp(tend);
    dt = dt/2;
    clear sol;
end

for k = 1:(n-1)
    eoc(k) = log(abs(err(k)/err(k+1)))/log(2);
end

eoc
end

function a = alpha(m,j)
a = 0;
for k = max(m-j,1):m
    a = a + binom(k,m-j)/k;    
end
a = (-1)^(m-j) * a;
end

function b = binom(n,k)
b = factorial(n)/(factorial(k)*factorial(n-k));
end

function sol = bdf(i,m,dt,sol,t0)
sol(i+m+1,1) = t0 + (i+m)*dt;
y = 0;
for j = 0:(m-1)
    y = y + alpha(m,j) * sol(i+j+1,2);
end
sol(i+m+1,2) = y/(dt-alpha(m,m));
end
Private Nachricht senden Benutzer-Profile anzeigen


Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 30.11.2011, 15:36     Titel:
  Antworten mit Zitat      
Code:
for i = 0:(v-m) %i=0:(1-3) 0:-2 geht nicht   geht nicht maximal i=0:-1:-3
 
Private Nachricht senden Benutzer-Profile anzeigen
 
DerBesteMensch
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 15
Anmeldedatum: 03.07.11
Wohnort: Lummerland
Version: ---
     Beitrag Verfasst am: 30.11.2011, 15:56     Titel:
  Antworten mit Zitat      
Hallo Winkow,

Das Programm arbeitet an sich schon so wie es soll. Der von dir bemerkte Fall, dass v - m < 0 kann mit der gewählten Anfangsschrittweite von dt = 1/8 niemals auftreten, da für diese Schrittweite v = 8 und somit für alle m = 1, ..., 6 gilt, dass v - m > 1.

Da dt in jedem weiteren Schritt in der Schleife über k halbiert wird, verdoppelt sich v in jedem Schritt, die Grenzen sind also alle ok.

Das Programm arbeitet wie gesagt ja auch genau so, wie es soll, ich habe nur Probleme bei der Laufzeit der for-Schleife über m. Damit das noch klarer wird, schreibe ich hier nochmal die abgeänderte Version auf, in der das fest vorgegebene m durch die Schleife ersetzt wird:

Code:
function konvergenzordnung
t0 = 0;
y0 = 1;
tend = 1;
dt = 1/8;
n = 9;

for m =1:6
for k = 1:n
    v = (tend - t0)/dt;
    for i = 0:(m-1)        
        sol(i+1,1) = t0 + i*dt;
        sol(i+1,2) = exp(sol(i+1,1));            
    end
    for i = 0:(v-m)
        sol = bdf(i,m,dt,sol,t0);
    end
    err(k) = sol(length(sol(:,1)),2) - exp(tend);
    dt = dt/2;
    clear sol;
end
for k = 1:(n-1)
    eoc(k) = log(abs(err(k)/err(k+1)))/log(2);
end

eoc
end
end

function a = alpha(m,j)
a = 0;
for k = max(m-j,1):m
    a = a + binom(k,m-j)/k;    
end
a = (-1)^(m-j) * a;
end

function b = binom(n,k)
b = factorial(n)/(factorial(k)*factorial(n-k));
end

function sol = bdf(i,m,dt,sol,t0)
sol(i+m+1,1) = t0 + (i+m)*dt;
y = 0;
for j = 0:(m-1)
    y = y + alpha(m,j) * sol(i+j+1,2);
end
sol(i+m+1,2) = y/(dt-alpha(m,m));
end
Private Nachricht senden Benutzer-Profile anzeigen
 
Winkow
Moderator

Moderator



Beiträge: 3.842
Anmeldedatum: 04.11.11
Wohnort: Dresden
Version: R2014a 2015a
     Beitrag Verfasst am: 30.11.2011, 16:21     Titel:
  Antworten mit Zitat      
naja wenns ne laufzeit frage is solltest du mal speicher allokalisieren. du erstellest bei dir ja alle matritzen dynamisch. das macht sowas sehr langsam
Private Nachricht senden Benutzer-Profile anzeigen
 
Harald
Forum-Meister

Forum-Meister


Beiträge: 24.502
Anmeldedatum: 26.03.09
Wohnort: Nähe München
Version: ab 2017b
     Beitrag Verfasst am: 30.11.2011, 17:11     Titel:
  Antworten mit Zitat      
Hallo,

wie Winkow schon sagte: Matrizen dynamisch vorbelegen.

Im MATLAB Editor wirst du durch orange unterlegte Stellen auf mögliche Verbesserungen im Code hingewiesen. sol, err und eoc sollten also vorbelegt werden.

Grüße,
Harald
Private Nachricht senden Benutzer-Profile anzeigen
 
DerBesteMensch
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 15
Anmeldedatum: 03.07.11
Wohnort: Lummerland
Version: ---
     Beitrag Verfasst am: 30.11.2011, 17:51     Titel:
  Antworten mit Zitat      
Hallo,

Auch wenn ich nicht weiß, was "Speicher allokalisieren" bedeutet, glaube ich doch zu wissen, was ihr meint. Und ihr habt natürlich recht, dass speziell die alphas immer wieder neu berechnet werden, was absolut nicht notwendig ist.

Daher habe ich mein Programm nun dahingehend verändert, dass die Koeffizientenmatrix A mit den alphas nun vorab generiert wird und dann in bdf nur noch auf die fertig generierten Koeffizienten zugegriffen wird.

Auch err und eoc habe ich vorab als Null-Vektoren entsprechender Größe initialisiert.

Dies (vor allem die Einführung von A) hat die Laufzeit etwa um den Faktor 10 verkürzt, danke schonmal dafür.

Dennoch bleibt mein ursprüngliches Problem bestehen. Da noch niemand Bezug auf meine ursprüngliche Frage genommen hat, versuche ichs nochmal anders zu erklären:

Die Laufzeit L einer for-Schleife F der folgenden Form (Z bezeichnet beliebige von m abhängige Anweisungen)

Code:
for m = 1:6
Z(m)
end


sollte sich doch naheliegender Weise als L(F) = L(Z(1)) + L(Z(2)) + ... + L(Z(6)) ergeben.

Mit der Einführung der Koeffizientenmatrix A für die alphas liegt die Laufzeit von Z für ein beliebiges m nun unter einer Sekunde, d.h. L(Z(m)) < 1s für alle m = 1, ..., 6. ABER: Die gesamte Schleife bleibt stecken!

Hier nochmal die aktualisierte Programmversion:

Code:
function konvergenzordnung
t0 = 0;
y0 = 1;
tend = 1;
dt = 1/8;
n = 9;
mmax = 6;

err = zeros(1,n);
eoc = zeros(1,n-1);

global A;
A = zeros(mmax,mmax+1);
for i = 1:mmax
    for j = 0:i
        A(i,j+1) = alpha(i,j);
    end
end

for m = 1:mmax
m
for k = 1:n
    v = (tend - t0)/dt;
    for i = 0:(m-1)        
        sol(i+1,1) = t0 + i*dt;
        sol(i+1,2) = exp(sol(i+1,1));            
    end
    for i = 0:(v-m)
        sol = bdf(i,m,dt,sol,t0);
    end
    err(k) = sol(length(sol(:,1)),2) - exp(tend);
    dt = dt/2;
    clear sol;
end
for k = 1:(n-1)
    eoc(k) = log(abs(err(k)/err(k+1)))/log(2);
end
eoc
end
end

function a = alpha(m,j)
a = 0;
for k = max(m-j,1):m
    a = a + binom(k,m-j)/k;    
end
a = (-1)^(m-j) * a;
end

function b = binom(n,k)
b = factorial(n)/(factorial(k)*factorial(n-k));
end

function sol = bdf(i,m,dt,sol,t0)
global A;
sol(i+m+1,1) = t0 + (i+m)*dt;
y = 0;
for j = 0:(m-1)
    y = y + A(m,j+1) * sol(i+j+1,2);
end
sol(i+m+1,2) = y/(dt-A(m,m+1));
end
Private Nachricht senden Benutzer-Profile anzeigen
 
DerBesteMensch
Themenstarter

Forum-Anfänger

Forum-Anfänger



Beiträge: 15
Anmeldedatum: 03.07.11
Wohnort: Lummerland
Version: ---
     Beitrag Verfasst am: 30.11.2011, 18:03     Titel:
  Antworten mit Zitat      
ARG, ich bin so dämlich!
Natürlich muss das dt nach jedem Schleifendurchlauf wieder auf 1/8 zurückgesetzt werden.

Hat sich dann erledigt, aber danke trotzdem nochmals für die generellen Verbesserungsvorschläge zur Laufzeit! Smile
Private Nachricht senden Benutzer-Profile anzeigen
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2025 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.