<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Runge Kutta bei unabhängiger Variable?]]></title><description><![CDATA[<p>Hi!</p>
<p>Ich versuche eine, besser zwei - Differentialgleichung iterativ zu integrieren, und zwar nach der Zeit. Die DGL hängt aber nicht mehr direkt von der Zeit ab. (Lotka-Volterra-DGLn).</p>
<p>Das Euler-Verfahren ist da ja recht einfach, aber ich verstehe nicht, wie ich das Problem auf das Runge-Kutta-Verfahren (zunächst RK2) ummünzen kann.</p>
<p>Für das Euler verfahren benutze ich jetzt diese Schleife:</p>
<pre><code class="language-cpp">double w_punkt (const double w, const double k)
{ return w*(1-k); }

double k_punkt (const double w, const double k)
{ return (-k)*(1-w);}

int main () {

  double k=0.5;
  double w=0.5;
  double a=0.5;
  double h=0.001;
  double t=0; 

  while (t&lt;100) {

    a +=h*w_punkt(w,k);
    k +=h*k_punkt(w,k);
    t+=h;
    w=a; }
</code></pre>
<p>Wenn ich das ausführe und die Werte in eine Datei ausgebe lasse und das ganze plotte schaut das ja schon ganz gut aus.</p>
<p>Damit das noch genauer wird, muss jetzt das Runge-Kutta verfahren her, und ich verstehe nicht ganze, wie ich das anstellen muss, wenn meine Integrationsvariable gar nicht mehr explizit in einer dieser Gleichungen drin steckt? Ich muss ja jetzt einen halben Integrationsschritt weiter, da die &quot;Steigung&quot; bestimmen und dann damit den ganzen Integrationsschritt gehen.<br />
Integriere ich eine &quot;normale&quot; Dgl, zb. eine Parabelgleichung oder sowas, dann ist das ja recht einfach, aber die ist ja von der Integrationsvariable auch abhängig. Diese DGLn hier ja nicht.</p>
<p>Hat jemand vllt. irgendwo ein Beispiel für so eine Fall in Petto, oder einen Link, in der so ein ähnliches Problem behandelt wird? Oder kann mir jemand von der Grundidee her sagen, wie ich hier zur Lösung kommen könnte?</p>
<p>Vielen Dank für die Hilfe!</p>
<p>Grüße,</p>
<p>der raeuberhotzenplotz</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/277565/runge-kutta-bei-unabhängiger-variable</link><generator>RSS for Node</generator><lastBuildDate>Tue, 25 Aug 2026 21:37:44 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/277565.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 20 Nov 2010 19:54:05 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Runge Kutta bei unabhängiger Variable? on Sat, 20 Nov 2010 19:54:05 GMT]]></title><description><![CDATA[<p>Hi!</p>
<p>Ich versuche eine, besser zwei - Differentialgleichung iterativ zu integrieren, und zwar nach der Zeit. Die DGL hängt aber nicht mehr direkt von der Zeit ab. (Lotka-Volterra-DGLn).</p>
<p>Das Euler-Verfahren ist da ja recht einfach, aber ich verstehe nicht, wie ich das Problem auf das Runge-Kutta-Verfahren (zunächst RK2) ummünzen kann.</p>
<p>Für das Euler verfahren benutze ich jetzt diese Schleife:</p>
<pre><code class="language-cpp">double w_punkt (const double w, const double k)
{ return w*(1-k); }

double k_punkt (const double w, const double k)
{ return (-k)*(1-w);}

int main () {

  double k=0.5;
  double w=0.5;
  double a=0.5;
  double h=0.001;
  double t=0; 

  while (t&lt;100) {

    a +=h*w_punkt(w,k);
    k +=h*k_punkt(w,k);
    t+=h;
    w=a; }
</code></pre>
<p>Wenn ich das ausführe und die Werte in eine Datei ausgebe lasse und das ganze plotte schaut das ja schon ganz gut aus.</p>
<p>Damit das noch genauer wird, muss jetzt das Runge-Kutta verfahren her, und ich verstehe nicht ganze, wie ich das anstellen muss, wenn meine Integrationsvariable gar nicht mehr explizit in einer dieser Gleichungen drin steckt? Ich muss ja jetzt einen halben Integrationsschritt weiter, da die &quot;Steigung&quot; bestimmen und dann damit den ganzen Integrationsschritt gehen.<br />
Integriere ich eine &quot;normale&quot; Dgl, zb. eine Parabelgleichung oder sowas, dann ist das ja recht einfach, aber die ist ja von der Integrationsvariable auch abhängig. Diese DGLn hier ja nicht.</p>
<p>Hat jemand vllt. irgendwo ein Beispiel für so eine Fall in Petto, oder einen Link, in der so ein ähnliches Problem behandelt wird? Oder kann mir jemand von der Grundidee her sagen, wie ich hier zur Lösung kommen könnte?</p>
<p>Vielen Dank für die Hilfe!</p>
<p>Grüße,</p>
<p>der raeuberhotzenplotz</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1983404</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1983404</guid><dc:creator><![CDATA[raeuberhotzenplotz]]></dc:creator><pubDate>Sat, 20 Nov 2010 19:54:05 GMT</pubDate></item><item><title><![CDATA[Reply to Runge Kutta bei unabhängiger Variable? on Sat, 20 Nov 2010 22:43:49 GMT]]></title><description><![CDATA[<p>Integrieren ist beim Lösen von DGLs nicht wortwörtlich gemeint. Man integriert zwar formal über dx/dt aber praktisch verkettet man bei Runge-Kutta-Verfahren geschickt mehrere Euler-Schritte.</p>
<p>Schau beispielsweise hier: <a href="http://de.wikipedia.org/wiki/Klassisches_Runge-Kutta-Verfahren" rel="nofollow">http://de.wikipedia.org/wiki/Klassisches_Runge-Kutta-Verfahren</a>.</p>
<p>Ich würd an deiner Stelle auch die die DGL in eine Funktion packen, vielleicht so</p>
<pre><code class="language-cpp">void lotka_volterra( double *x , double *dxdt )
{
  dxdt[0] = ...
  dxdt[1] = ...
}
</code></pre>
<p>Und die Runge-Kutta Solver in eine eigene Funktion packen. Dann kannst Du auch Solver und DGL austauschen. Das wird z.B. in den <a href="http://www.nr.com" rel="nofollow">Numerical Recipes</a> beschrieben. Oder Du nimmst was vorgefertigtes: <a href="http://www.codeproject.com/KB/recipes/odeint.aspx" rel="nofollow">odeint</a> (um mal ein bisschen Werbung zu machen).</p>
<p>Ich hoffe dass hilft Dir weiter.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1983492</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1983492</guid><dc:creator><![CDATA[headmyshoulder]]></dc:creator><pubDate>Sat, 20 Nov 2010 22:43:49 GMT</pubDate></item><item><title><![CDATA[Reply to Runge Kutta bei unabhängiger Variable? on Sun, 21 Nov 2010 00:27:45 GMT]]></title><description><![CDATA[<p>Hm, nein so ganz verstehe ich das nicht.</p>
<p>Ich verstehe glaube ich das ganze Prinzip nicht.</p>
<p>Vllt. kannst du mir ja mal kurz weiterhelfen, ich habe mir jetzt ein extrem einfaches Problem zurechtgestrickt.</p>
<p>die DGL x'(t)= t/x(t)</p>
<p>Nach Euler habe ich das ganze jetzt so gelöst :</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std; 

double f(const double t, const double x) {
 return t/x;

}

double h=0.001;

double x=0.5; 
double y=0.5;
double t=0;

int main(){

while (t&lt;5) {

  x+=h*f(t,x); 
  t+=h; 
}
cout &lt;&lt; x &lt;&lt; endl; 
}
</code></pre>
<p>Nach Runge Kutta 2. Ordnung sieht das ganze jetzt so aus:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std; 

double f(const double t, const double x) {
 return t/x;

}

double h=0.001;

double x=0.5; 
double y=0.5;
double t=0;

int main(){

while (t&lt;5) {

  x+=h*f(t+(h/2),x+h/2*f(t,x)); 
  t+=h; 
}
cout &lt;&lt; x &lt;&lt; endl; 
}
</code></pre>
<p>Hier klappt alles wunderbar. Ich kann das Verfahren direkt aus dem Lehrbuch übernehmen.</p>
<p>Wenn mir aber die explizite Zeitabhängigkeit fehlt, wie hier:</p>
<p>x'[t]= 1/ x[t]</p>
<p>Funktioniert das Euler verfahren genauso:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std; 

double f(const double x) {
 return 1/x;

}

double h=0.001;

double x=0.5; 
double y=0.5;
double t=0;

int main(){

while (t&lt;5) {

  x+=h*f(x); 
  t+=h; 
}
cout &lt;&lt; x &lt;&lt; endl; 
}
</code></pre>
<p>Wenn ich jetzt richtig liege, müsste das ganze doch jetzt so aussehen:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;
using namespace std; 

double f(const double x) {
 return 1/x;

}

double h=0.001;

double x=0.5; 
double y=0.5;
double t=0;

int main(){

while (t&lt;5) {

  x+=h*f(x+h/2*f(x)); 
  t+=h; 
}
cout &lt;&lt; x &lt;&lt; endl; 
}
</code></pre>
<p>Vom Wert her könnte es stimmen.</p>
<p>Wenn das stimmt, kannst du mir noch sagen, ob mein Euler-Ansatz im ersten Beitrag richtig ist? Ich hab das gefühl, vor lauter Wald die Bäume nicht mehr zu sehen ..</p>
<p>Danke für die Hilfe!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1983513</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1983513</guid><dc:creator><![CDATA[raeuberhotzenplotz]]></dc:creator><pubDate>Sun, 21 Nov 2010 00:27:45 GMT</pubDate></item><item><title><![CDATA[Reply to Runge Kutta bei unabhängiger Variable? on Sun, 21 Nov 2010 08:57:54 GMT]]></title><description><![CDATA[<p>raeuberhotzenplotz schrieb:</p>
<blockquote>
<p>Vom Wert her könnte es stimmen.</p>
<p>Wenn das stimmt, kannst du mir noch sagen, ob mein Euler-Ansatz im ersten Beitrag richtig ist? Ich hab das gefühl, vor lauter Wald die Bäume nicht mehr zu sehen ..</p>
<p>Danke für die Hilfe!</p>
</blockquote>
<p>Was Du über das 1D Beispiel schreibst ist fast richtig. Ich glaub Du musst nur <code>dt/2</code> im zweiten Schritt bei dem RK 2.ter Ordnung nehmen. Also</p>
<pre><code class="language-cpp">while (t&lt;5) {  
  x+=h/2*f(t+(h/2),x+h/2*f(t,x)); 
  t+=h; 
}
</code></pre>
<p>Auch dein Euler für das Lotka-Volterra-System ist richtig. Ich glaub Du hast das schon fast verstanden. Du musst halt bei dem RK2 und dem Lotka-Volterra einen Zwischenschritt explizit hinschreiben. Das geht in einer einzigen Zeile nicht, da w und k voneinander abhängen. Berechnen einfach erst f(x) und mach dann die einzelnen Schritte machen:</p>
<pre><code class="language-cpp">while( t &lt; tmax )
{
  double dk = k_punkt( w , k );
  double dw = w_punkt( w , k );
  k = k + dt / 2 * dk;
  w = w + dt / 2 * dw;
  dk = k_punkt( w , k );
  dw = w_punkt( w , k );
  k = k + dt / 2 * dk;
  w = w + dt / 2 * dw;
}
</code></pre>
<p>Das würd für höhere Ordnung übrigens nur noch komplizierter. Ich würde Dir auf jedenfall empfehlen, hier zwischen der DGL und dem Runge-Kutta-Solver trennen. Du kannst das obige Beispiel auch so schreiben:</p>
<pre><code class="language-cpp">void einfache_dgl( double* x , double *dxdt , double t )
{
  dxdt[0] = t / x[0];
}

void euler( double *x , double t , double dt , int n , void (*dgl)( double* , double* , double ) )
{
  double dxdt[n];
  dgl( x , dxdt , t );
  for( int i=0 ; i&lt;n ; ++i ) x[i] = x[i] + dt * dxdt[i];
}

void rk2( double *x , double t , double dt , int n , void (*dgl)( double* , double* , double ) )
{
  double dxdt[n];
  dgl( x , dxdt , t );
  for( int i=0 ; i&lt;n ; ++i ) x[i] = x[i] + dt * dxdt[i];
  dgl( x , dxdt , t + dt/2 );
  for( int i=0 ; i&lt;n ; ++i ) x[i] = x[i] + dt * dxdt[i];
}
</code></pre>
<p>und benutzt wird das dann so</p>
<pre><code class="language-cpp">double x[1] = 0.5;
euler( x , 0.5 , 0.5 , 1 , einfache_dgl );
</code></pre>
<p>oder für das Lotka Volterra System</p>
<pre><code class="language-cpp">double x[2] = ...;
double t = ...;
double dt = ...;
rk2( x , t , dt , 2 , lotka_volterra );
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1983537</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1983537</guid><dc:creator><![CDATA[headmyshoulder]]></dc:creator><pubDate>Sun, 21 Nov 2010 08:57:54 GMT</pubDate></item><item><title><![CDATA[Reply to Runge Kutta bei unabhängiger Variable? on Sun, 21 Nov 2010 13:02:40 GMT]]></title><description><![CDATA[<p>headmyshoulder schrieb:</p>
<blockquote>
<p>Was Du über das 1D Beispiel schreibst ist fast richtig. Ich glaub Du musst nur <code>dt/2</code> im zweiten Schritt bei dem RK 2.ter Ordnung nehmen.</p>
</blockquote>
<p>Sicher? Soweit ich das verstanden habe nehme ich bei RK2 den &quot;Steigungswert&quot; des halben Iterationsschritt, und iteriere damit dann aber einen ganzen Schritt, also h.<br />
Ich kann mich natürlich auch täuschen, aber bei h/2 kommt dann ein anderer Wert heraus, und ich hab den Wert mit Wolfram Alpha auch rausbekommen(also mit ganzem h).</p>
<p>Deinen Code :</p>
<pre><code class="language-cpp">void einfache_dgl( double* x , double *dxdt , double t )
{
  dxdt[0] = t / x[0];
}

void euler( double *x , double t , double dt , int n , void (*dgl)( double* , double* , double ) )
{
  double dxdt[n];
  dgl( x , dxdt , t );
  for( int i=0 ; i&lt;n ; ++i ) x[i] = x[i] + dt * dxdt[i];
}

void rk2( double *x , double t , double dt , int n , void (*dgl)( double* , double* , double ) )
{
  double dxdt[n];
  dgl( x , dxdt , t );
  for( int i=0 ; i&lt;n ; ++i ) x[i] = x[i] + dt * dxdt[i];
  dgl( x , dxdt , t + dt/2 );
  for( int i=0 ; i&lt;n ; ++i ) x[i] = x[i] + dt * dxdt[i];
}
</code></pre>
<p>Schaffe ich nicht zu 100% nachzuvollziehen. Sind das dxdt[n], x[1] etc. nicht arrays? Speichere ich dann damit alle iterationsschritte in dem Array ab und lass mir am Schluss nur den letzten ausgeben?</p>
<p>habe das ganze jetzt so weit umgeschrieben bei mir:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;cmath&gt;

using namespace std; 

double dw(const double w, const double k)
{ return w*(1-k); }

double dk (const double w, const double k)
{ return (-k)*(1-w);}

void euler ( double tmax, double w, double k, double t, double a, const double h) {
  while (t&lt;tmax)  {

    a +=h*dw(w,k);
    k +=h*dk(w,k);
    w=a;
    t+=h;
  }
cout &lt;&lt; &quot;Iteration nach Euler:&quot; &lt;&lt; endl; 
cout &lt;&lt; &quot;W(t=100) =&quot; &lt;&lt; w &lt;&lt; endl; 
cout &lt;&lt; &quot;K(t=100) =&quot; &lt;&lt; k &lt;&lt; endl; 

}

void rk2 (double tmax, double w, double k, double t, double a, const double h) {

  while (t&lt;tmax) {

   a +=h/2*dw(w,k); 
   k +=h/2*dk(w,k); 
   w=a; 
   a += h*dw(w,k);
   k += h*dk(w,k);
   w=a;
   t+=h;

  }
cout &lt;&lt; &quot;Iteration nach RK2:&quot; &lt;&lt; endl; 
cout &lt;&lt; &quot;W(t=100) =&quot; &lt;&lt; w &lt;&lt; endl; 
cout &lt;&lt; &quot;K(t=100) =&quot; &lt;&lt; k &lt;&lt; endl; 
   }

void rk4 (double tmax, double w, double k, double t, double a, const double h) {

  while (t&lt;tmax) {
    double w1= w + h/2 *dw(w,k);
    double k1= k + h/2 *dk(w,k); 
    double Kw1= dw(w1,k1);
    double Kk1= dk(w1,k1);
    double w2= w + h/2*dw(w1,k1);
    double k2= k + h/2*dk(w1,k1);

int main () {

euler(100, 0.5, 0.5, 0, 0.5, 0.001);
rk2 (100, 0.5, 0.5, 0, 0.5, 0.001);
}
</code></pre>
<p>Es funktioniert auch soweit (Ohne den RK4 - Teil, damit kämpfe ich gerade). Leider weichen die Werte von euler und rk2 soweit voneinander ab, dass ich nicht mehr weiß, ob ich überhaupt noch im Bereich des richtigen bin.</p>
<p>Ich arbeite schon das ganze Wochenende nur an dem Mist und bekomme gar nichts hin ... sehr deprimierend.</p>
<p>Danke auf jeden Fall für deine Hilfe!</p>
<p>Grüße!</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1983610</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1983610</guid><dc:creator><![CDATA[raeuberhotzenplotz]]></dc:creator><pubDate>Sun, 21 Nov 2010 13:02:40 GMT</pubDate></item><item><title><![CDATA[Reply to Runge Kutta bei unabhängiger Variable? on Sun, 21 Nov 2010 17:36:25 GMT]]></title><description><![CDATA[<p>raeuberhotzenplotz schrieb:</p>
<blockquote>
<p>Sicher? Soweit ich das verstanden habe nehme ich bei RK2 den &quot;Steigungswert&quot; des halben Iterationsschritt, und iteriere damit dann aber einen ganzen Schritt, also h.<br />
Ich kann mich natürlich auch täuschen, aber bei h/2 kommt dann ein anderer Wert heraus, und ich hab den Wert mit Wolfram Alpha auch rausbekommen(also mit ganzem h).</p>
</blockquote>
<p>Sry, Du hast recht. Da muss nur dt hin.</p>
<p>raeuberhotzenplotz schrieb:</p>
<blockquote>
<p>Schaffe ich nicht zu 100% nachzuvollziehen. Sind das dxdt[n], x[1] etc. nicht arrays? Speichere ich dann damit alle iterationsschritte in dem Array ab und lass mir am Schluss nur den letzten ausgeben?</p>
</blockquote>
<p>Ja, dxdt[n] sind arrays. Aber <code>n</code> ist die Dimension der DGL, also für das einfach Beispiel 1 und für Lotka-Volterra 2. In der Fkt. wird nur ein Schritt ausgeführt. Und man kann Euler und RK2 auch für andere DGLs benutzen. Darum gehts. Das solltest Du auch für RK4 machen. Stell Dir vor, Du willst morgen das Lorenz-System oder was anderes mit RK4 lösen. Dann kannst Du einfach die fertige RK4-Routine nehmen und musst nur eine neue Funktion schreiben, welche dx1/dt, dx2/dt, dx3/dt berechnet.</p>
<p>raeuberhotzenplotz schrieb:</p>
<blockquote>
<p>Es funktioniert auch soweit (Ohne den RK4 - Teil, damit kämpfe ich gerade). Leider weichen die Werte von euler und rk2 soweit voneinander ab, dass ich nicht mehr weiß, ob ich überhaupt noch im Bereich des richtigen bin.</p>
</blockquote>
<p>Jepp, euler und rk2 müssen was anderes liefern. Die Ergebnisse solten aber nicht zuweit auseinander sein. Wenn Du damit sehr viele Schritte machst, sollten die Kurven bei Lotka-Volterra fast übereinander liegen. Dass kannst Du ganz einfach plotten.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1983777</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1983777</guid><dc:creator><![CDATA[headmyshoulder]]></dc:creator><pubDate>Sun, 21 Nov 2010 17:36:25 GMT</pubDate></item></channel></rss>