Bonjour,

Voici un ensemble de classe qui permet de résoudre une équation différentielle du type : dy/dx = f(x,y) par la méthode de Runge-Kutta.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
 
 
/*
 * Cette interface permet de representer la fonction f
 * dans les équations différentielles que permet de résoudre Runge-Kutta,
 * à savoir : dy/dx = f(x,y)
 * Afin d'avoir un comportement générique, il suffit d'implémenter cette classe
 * avec la fonction adéquate
 */
public interface FonctionEqn {
  public double evaluer(double  X, double Y);
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
 * Clase offrant les possibilités de résoure une équation différentielle
 * du type dy/dx = f(x,y) par la méthode de Runge-Kutta
 */
class RungeKutta {
  private FonctionEqn _f;
  private double _dx;
  private double _x_current;
  private double _y_current;
 
  /* Constucteur
   * @param FonctionEqn correspond à la fonction définissant l'équation différentielle
   * @param deltax correspond au pas de discrétisation en x
   * @param y0 correspond à la condition initales en y
   * @param x0 définie où commence la résolution
   */
  public RungeKutta(FonctionEqn f, double deltax, double y0, double x0) {
     _f = f;
     _dx = deltax;
     _y_current = y0;
     _x_current = x0;	
  }	
 
  /*
   * La méthode permet de calculer le prochain couple (x,y) qui correspond
   * à l'itération suivante
   */
  public void calculerSuivant() {
    double k1;
    double k2;
    double k3;
    double k4;
 
    k1 = _f.evaluer(_x_current, _y_current) * _dx;
    k2 = _f.evaluer(_x_current + _dx / 2.0, _y_current+k1/2.0) *_dx;
    k3 = _f.evaluer(_x_current + _dx/2.0, _y_current+k2/2.0) *_dx;
    k4 = _f.evaluer(_x_current + _dx, _y_current+ k3) *_dx;
 
    _y_current += 1.0/6.0 * (k1 + 2.0*k2 + 2.0*k3 + k4);
    _x_current += _dx;
  }
 
  /*
   * Retourne le x courant
   */
  double lireX() {
    return _x_current;
  }
 
  /*
   * Retourne le y courant
   */
  double lireY() {
    return _y_current;
  }
}


Et ensuite, pour les tests et montrer comment ça marche :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
 
/*
 * Cette classe implémente une fonction servant à définir
 * une équation différentielle révoluble par Runge-Kutta
 * Ici, on définit dy/dx = f(x,y) avec f(x,y) = -2xy
 */
class TestFonctionEqn implements FonctionEqn{
  public double evaluer(double  X, double Y) {
    return (-2*X*Y);  
  }
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.lang.Math;
 
class Test {
  static public void main(String[] s) {
     double x0 = 0.0;
     double y0 = 1.0;
     double dx = 0.1;
 
     /****
      * On résout l'équation différentielle :
      *  dy/dx = -2x*y (y0 = 1 et x0 = 0)
      *  Donc de solution : y = exp(-x²)
      ****/
      RungeKutta eqn = new RungeKutta(new TestFonctionEqn(), dx, y0, x0);
 
      for(int i=0; i<20;i++)
      {
       System.out.println("Solution par RungeKutta : " + eqn.lireY() + ", solution analytique" + Math.exp(-eqn.lireX() * eqn.lireX()));
        eqn.calculerSuivant();
      }
 
    }
}