Résolution d'un système d'équations linéaires à n inconnues

Description

Voici une application non graphique de calcul matriciel qui utilise l'objet MatWV contenu dans le fichier 'MatWV.js'. (voir l'article "Vecteurs et matrices: outils graphiques utiles")

Le programme permet de:
- Choisir N (pratiquement de 1 à 100).
- Résoudre un système d'équations linéaires (1er degré);
le temps de calcul est alors indiqué.
- Commuter le système: V = M*X ==> X = Inv(M)*V
- Importer et exporter les valeurs à l'aide de presse-papier.
- Remplir la matrice de valeurs aléatoires.

Les méthodes pour le presse-papier se trouvent dans le fichier 'MatWV-Cb.js' qui augmente l'objet MatWV. Dans 'Str' les valeurs sont arrondies pour 'faciliter la visibilité', mais vous pouvez les enlever ou les ajouter à d'autres places.

Utilisez le petit exemple 'Mat44.txt' à l'aide du presse-papier.

J'ai placé ce code (qui ne contient pas de <form>) dans la catégorie Formulaire car le programme est présenté sous la forme d'un "formulaire" de taille dynamique.
A partir de N=50, la gestion de l'affichage commence à traîner. Si vous désirez faire des tests avec des matrices plus grandes, consultez l'article cité ci-dessus.

Petite histoire
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
Vers les années 1950, un de mes profs (avec deux de ses collègues) a été chargé par l'industrie de résoudre un système de 50 équations à 50 inconnues (basé sur une matrice symétrique définie positive).
A trois, et à la règle à calcul, ils ont mis trois semaines pour le faire (avec une précision de 2 à 4 chiffres significatifs) !

En 1974-1975, à l'EPFL de Lausanne, il y avait le "super ordinateur" Cyber de CDC (voir http://en.wikipedia.org/wiki/CDC_Cyber), qui occupait toute une maison climatisée. Il était 'entretenu' par plus de 20 personnes spécialisées et valait de 10 à 20 millions de francs (SFR de l'époque).
Sur cet ordi, à l'aide de la routine 'IMGC' écrite en 'Fortran', il fallait quelques dixièmes de seconde pour inverser une matrice quelconque 50?50, et avec une précision nettement meilleure !
Mon voisin, à qui j'avais essayé d'expliquer cela, m'a toujours pris pour un blagueur.

Et certains 'rêveurs' osaient même prédire que dans quelques années, chacun pourrait avoir l'équivalent d'une "Cyber-CDC" sur son bureau !

Aujourd'hui (sept 2011), malgré les performances médiocres de Javascript, mon petit portable de 10" (environ 160 ?) met 12 à 18 ms pour faire l'inversion d'une matrice de 50?50 !

Source / Exemple :


<!DOCTYPE html>
<html>
<head>
  <title>Résolution d'un système d'équations de taille quelconque</title>
  <meta name='Author' content='William VOIROL, Switzerland, Sep 2011'/>
  <style type='text/css'>
    .inp {text-align:center; width:72px;}
    .res {text-align:center; width:72px; background-color:#7F7}
  </style>
  <script type='text/javascript' src='MatWV.js'></script>
  <script type='text/javascript' src='MatWV-Cb.js'></script>
  <script type="text/javascript">
  //<![CDATA[
    var N=3;
    function M2I(m) { // Copie la matrice m dans le tableau input M
      for (var l=0,k=0;l<m.nL;l++)
        for (var c=0;c<m.nC;c++) document.getElementById('M'+l+'_'+c).value=m.M[k++];
    }
    function I2M() { // Crée une matrice correspondant au tableau input M
      var m=new MatWV(N,N);
      for (var l=0,k=0;l<N;l++)
        for (var c=0;c<N;c++) m.M[k++]=document.getElementById('M'+l+'_'+c).value;
      return m;
    }
    function V2I(m,v) { // Copie la matrice m dans le tableau input v = 'V' ou 'X'
      for (var l=0;l<m.nL;l++) document.getElementById(v+l).value=Math.round(m.M[l]*1E13)/1E13;
    } // enlevez l'arrondi pour des résultats plus précis: Math.round(x*1E13)/1E13
    function I2V(v) { // Crée une matrice correspondant au tableau input v = V ou X
      var m=new MatWV(1,N);
      for (var l=0;l<N;l++) m.M[l]=document.getElementById(v+l).value;
      return m;Rnd
    }
    function GetM() { // Copie le presse-papier dans le tableau input M
      var m=new MatWV(N,N);
      m.GetCb(); M2I(m);
    }
    function GetV(v) { // Copie le presse-papier dans le tableau input v = 'V' ou 'X'
      var m=new MatWV(1,N);
      m.GetCb(); V2I(m,v);
    }
    function Clr() { // Annule (clear) les valeurs calculées
      for (var c=0;c<N;c++) document.getElementById('X'+c).value='';
      document.getElementById('Z').innerHTML='&nbsp';
    }
    function Cal() { // V=M×X   calcule X
      var v=I2V('V'),m=I2M(),x,ms=(new Date()).getTime();
      if (!m.Invert()) {alert('matrice non inversible'); return;}
      document.getElementById('Z').innerHTML='temps: '+((new Date()).getTime()-ms)+' ms';
      x=m.Prod(v); V2I(x,'X');
    }
    function Com() { // Commutation:  V=M×X ==> X=Inv(M)×V
      var v=I2V('V'),m=I2M(),x=I2V('X');
      if (m.Invert()) {V2I(x,'V'); M2I(m); V2I(v,'X');} else alert('matrice non inversible');
    }
    function Chn(f) { // Change la dimension N
      var n=parseInt(f.value);
      if ((n>=1)&&(n<=100)) {N=n; Dim()} else alert('introduisez un nombre entre 1 et 100');
      f.value=N;
    }
    function Dim() { // Construit les tableaux du système d'équations selon la dimension N
      var c,l,k=Math.floor((N-1)/2),s="<table>";
      dT=document.getElementById('T').innerHTML=
        "<h3>Système linéaire de "+N+" équations à "+N+" inconnues:</h3>";
      s+="<tr><td class='inp'>V</td><td> </td>";
      for (c=0;c<N;c++) s+=((c==k)?"<td class='inp'>M":"<td>")+"</td>";
      s+="<td></td><td class='inp'>X</td></tr>";
      for (l=0;l<N;l++) {
        s+="<tr><td><input class='inp' type='text' id='V"+l+"' onchange='Clr()'/></td>";
        s+="<td>"+((l==k)?"=":"")+"</td>";
        for (c=0;c<N;c++)
          s+="<td><input class='inp' type='text' id='M"+l+'_'+c+"' onchange='Clr()'/></td>";
        s+="<td>"+((l==k)?"×":"")+"</td>";
        s+="<td><input class='res' type='text' id='X"+l+"' readonly='readonly'/></td></tr>";
      }
      document.getElementById('S').innerHTML=s+"</table>";
      M2I(MatWV.Uni(N));
      for (var l=0;l<N;l++) document.getElementById('V'+l).value=l+1;
    }
  //]]>
  </script>
</head>
<body style='background-color:#BBBBBB' onload='Dim(3)'>
  <div id='T'></div>
  <div>
    Nombre d'inconnues: N =
    <input type='text' style='width:24px; text-align:center' onchange='Chn(this)' value='3'/>
    &nbsp; &nbsp; &nbsp; <input type ='button' value='Calcul' onclick='Cal()'/>
    &nbsp; &nbsp; &nbsp; <input type ='button' value='Commutation' onclick='Com()'/>
    <br/><div id='Z' style='width:300px; text-align:right; color:blue'>&nbsp</div>
    Presse-papier:<br/>
    <input type ='image' title='Copie les valeurs du presse-papier dans V'
      src='cbO.jpg' onclick='GetV("V")'/> V
    <input type ='image' title='Ecrit les valeurs de V dans le presse-papier' src='cbI.jpg'
      onclick='I2V("V").SetCb()'/> &nbsp; &nbsp; &nbsp; &nbsp;
    <input type ='image' title='Copie les valeurs du presse-papier dans M'
      src='cbO.jpg' onclick='GetM()'/> M
    <input type ='image' title='Ecrit les valeurs de M dans le presse-papier' src='cbI.jpg'
      onclick='I2M().SetCb()'/> &nbsp; &nbsp; &nbsp; &nbsp; X
    <input type ='image' title='Ecrit les valeurs de X dans le presse-papier' src='cbI.jpg'
      onclick='I2V("X").SetCb()'/> &nbsp; &nbsp; &nbsp; &nbsp;  &nbsp; &nbsp;
    <input type ='button' style='position:relative; bottom:10px'
      value='Random' onclick='M2I(MatWV.Rnd(N,N,4,0))'/>
  </div>
  <div id='S'></div>
  <h6>Par William Voirol, Switzerland, Sep 2011</h6>
  <!--La suite du code n'est pas indispensable-->
  <div>
    Wikipédia: <a href='http://fr.wikipedia.org/wiki/%C3%89quation_lin%C3%A9aire'>
      Equations linéaires</a><br/><br/>
    <a href='http://www.william-voirol.ch/Prog/Transformations/Equations.zip'>Zip du code</a>
  </div>
</body>
</html>

Conclusion :


Faites directement un test: (observez la remarque ci-dessous)
http://www.william-voirol.ch/Prog/Transformations/Equations

Remarque: de temps en temps, des espaces (caractères blancs) s'immiscent
dans certains textes. (CodeS-SourceS est au courant du problème).
Si c'était le cas ici, enlevez les espaces avant d'utiliser l'adresse Web ci-dessus.

L'exemple complet se trouve sur le fichier zip.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.