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(); } } }
Partager