0

Ich begann vor kurzem mit C++ und ich gerade eine Klasse, die die Integration eines benutzerdefinierten System der Ode des erlaubt. Es verwendet zwei verschiedene Integratoren, um seine Leistung zu vergleichen. Hier ist der allgemeine Aufbau des Codes:C++ numerische Integratoren Systeme ode des lösen

class integrators { 
    private: 
     double ti; // initial time 
      double *xi; // initial solution 
      double tf; // end time 
      double dt; // time step 
      int  n; // number of ode's 

     public: 
      // Function prototypes 
      double f(double, double *, double *); // function to integrate 
      double rk4(int, double, double, double, double *, double *); 
      double dp8(int, double, double, double, double *, double *); 
     }; 

     // 4th Order Runge-Kutta function 
     double integrators::rk4(int n, double ti, double tf, double dt, double *xi, double *xf) { 
      // Function statements 
     } 

     // 8th Order Dormand-Prince function 
     double integrators::dp8(int n, double ti, double tf, double dt, double *xi, double *xf) { 
      // Function statements 
     } 

     // System of first order differential equations 
     double integrators::f(double t, double *x, double *dx) { 
      // Function statements 
     } 

     int main() { 
      // Initial conditions and time related parameters 
      const int n = 4; 
      double t0, tmax, dt; 
      double x0[n], xf[n]; 

      x0[0] = 0.0;       
      x0[1] = 0.0;       
      x0[2] = 1.0;    
      x0[3] = 2.0;    

      // Calling class integrators 
      integrators example01; 
      integrators example02; 

      // First integrator 
      example02.dp8(n, t0, tmax, dt, x0, xf); 

      // Second integrator 
      example01.rk4(n, t0, tmax, dt, x0, xf); 
     } 

Das Problem besteht darin, dass das Array den Anfangsbedingungen x0 enthält in Haupt, ändert, nachdem der erste Integrator der Ausführung und kann nicht die gleichen Anfangsbedingungen für den zweiten Integrator verwenden, es sei denn, Ich definiere ein weiteres Array mit den gleichen Anfangsbedingungen (x0_rk4 und x0_dp8). Gibt es eine professionellere Methode, dieses Array konstant zu halten, um es in beiden Integratoren zu verwenden?

Antwort

1

Nein, nicht wirklich. Aber es gibt eine elegantere Lösung:

std::array<double, n> x0_rk4 = { 0.0, 0.0, 1.0, 2.0 }; 
auto x0_dp8 = x0_rk4; // copy! 

Sie haben x0_rk4.data() zu verwenden, um die zugrunde liegende Array zuzugreifen. Beachten Sie, dass es besser wäre, wenn Sie und andere moderne C++ - Funktionen anstelle von rohen Zeigern und dergleichen verwenden würden.

+0

Vielen Dank @ Rakete1111! Ich denke, ich muss meine C++ Bücher aktualisieren. Das Problem, das ich bisher hatte, ist, neue C++ - Bücher zu finden, die auf numerische Methoden angewendet werden. – Leonel

2

Der einfachste Weg besteht darin, eine lokale Kopie des Arrays innerhalb der Integrationsfunktionen zu erstellen.

Ändern Sie die Art und Weise, wie Sie 'n' übergeben, um zu 'const int n' zu funktionieren, so können Sie zB double currentSolution[n]; einfügen und Elemente vom ursprünglichen Array in ein neues kopieren. Bei dieser Methode wird das ursprüngliche Array intakt gespeichert, es sei denn, Sie ändern es "versehentlich".

Um diese Wahrscheinlichkeit eines Unfalls Änderung verhindern wir müssen tiefer gehen und eine der stl Behälter verwenden. Ich denke, Sie werden mit std::valarray<T> in Ordnung sein.

die Art und Weise ändern Sie es const std::valarray<double>& sind vorbei und wieder nicht konstante lokale Kopie machen.

+0

Vielen Dank! Ich muss wirklich anfangen mit Vektor, Array und Valarray zu arbeiten – Leonel