ChronoMath, une chronologie des MATHÉMATIQUES
à l'usage des professeurs de mathématiques, des étudiants et des élèves des lycées & collèges

Méthode itérative de Jacobi pour les systèmes linéaires
      @ Programme JavaScript

Considérons un système linéaire n × n (n équations à n inconnues xi, i=1,...,n).

Ainsi se crée une suite xi(n) convergeant vers la solution, moyennant certaines conditions sur le système initial. On remarquera que c'est une méthode de fausse position.

Illustrons la méthode par l'exemple d'un système 2 × 2 : soit à résoudre le système :

On exprime x en fonction de y et y en fonction de x :

On part d'une solution "approchée" (xo,yo), disons xo = 1, yo = 1, que l'on reporte dans (s2). Les valeurs obtenues constituent une nouvelle solution approchée (x1,y1) que nous reportons dans (s2) afin d'obtenir une nouvelle approximation (x2,y2) de la solution (x,y). Et ainsi de suite. L'algorithme est facilement programmable :

Programmation en JavaScript de la méthode :

<SCRIPT LANGUAGE=JavaScript>
a=3;b=1;c=5;a1=1;b1=2;c1=1;x=1;y=1;n=0
function jacobi()
{
a=prompt("Première équation ax + by = c. Donnez a :",a)
if (a==null) {return} else {a=eval(a)}
b=prompt("Donnez b :",b)
if (b==null) {return} else {b=eval(b)}
c=prompt("Donnez c :",c)
if (c==null) {return} else {c=eval(c)}
a1=prompt("Seconde équation a'x + b'y = c'. Donnez a' :",a1)
if (a1==null) {return} else {a1=eval(a1)}
b1=prompt("Donnez b' :",b1)
if (b1==null) {return} else {b1=eval(b1)}
c1=prompt("Donnez c' :",c1) // ligne 20
if (c1==null) {return} else {c1=eval(c1)}
x=prompt("Entrez maintenant la solution approchée initiale (xo,yo). Donnez xo :",x)
if (x==null) {return} else {x=eval(x)}
y=prompt("Donnez yo :",y)
if (y==null) {return} else {y=eval(y)}

xn=x+1;yn=y+1;        // initialisation permettant de lancer la boucle de calcul
while(Math.abs(x-xn)>1e-6 || Math.abs(y-yn)>1e-6)
{
n=n+1;xn=x;yn=y;x=(c-b*y)/a;y=(c1-a1*x)/b1
if (!confirm("Itération n°"+n+" : x="+x+" , y="+y)) return // ligne 30
}
alert("x="+arrondi(x)+" , y="+arrondi(y)+" . Erreur <"+1e-6)
}
function arrondi(x)  
   
// fonction d'arrondi à 10-6 près
{
sgn=1;if(x<0){sgn=-1}
return sgn*Math.floor(Math.abs(x)*1e6+.5)/1e6
}

</SCRIPT>

 

La première partie grisée du programme correspond aux données du système :

ax + by = c
a'x + b'y = c'

xn et yn sont les valeurs de x et de y obtenues à chaque itération. On a fixé la précision des calculs à 10-6 près : les calculs se poursuivent tant que |x - xn| < 10-6 ou |y - yn| < 10-6, c'est à dire :

while(Math.abs(x-xn) > 1e-6 || Math.abs(y-yn)>1e-6)

Exemple d'exécution :

Avec les données par défaut du système (s1), le procédé converge rapidement vers x = 1,8 et y = -0,4.  On vérifiera une "bien moins bonne" convergence avec le système :

2x + 3y = 5
3x + 5y = 1

Et le procédé diverge avec le système :

x + 3y = 5
3x + 5y = 1

 

Quelques explications théoriques :

Si X désigne la matrice colonne (xi) de la solution, comme on le constate dans l'exemple ci-dessus, exprimer les xi en fonction des xj pour j ≠ i revient à écrire matriciellement :

X = MX + C       (1)

où M est une matrice dont la diagonale principale est nulle et C une matrice colonne de constantes : on est en présence d'un phénomène récurrent du type :

Xn = MXn-1 + C  avec Xo donné autre que la solution X     (2)

Cette écriture rappelle les études classiques de suites numériques et le théorème du point fixe.

Par soustraction (2) - (1) et en posant Yn = Xn - X, on obtient :

Yn = MYn-1

et finalement Yn = MnYo. La suite Xn convergera vers X à condition que Yn converge vers 0. On démontre assez facilement qu'une condition nécessaire et suffisante de convergence est que toutes les valeurs propres de M soient de module strictement inférieur à 1. Une condition suffisante étant qu'une norme euclidienne de M (on peut en définir plusieurs, lesquelles sont équivalentes) soit inférieure à 1.


© Serge Mehl - www.chronomath.com