Algo récursif du pivot de gauss

Algo récursif du pivot de gauss - Algo - Programmation

Marsh Posté le 15-04-2005 à 22:40:41    

Bonjour
 
Je cherche un algorithme récursif de la méthode de résolution des systèmes linéaires par pivot de Gauss, est ce que qqn aurait ça sous la main ??
 
J'ai trouvé la version itérative sur le net (il yen a plein) mais impossible de trouver la version récursive, alors que je sais qu'elle existe !
 
Merci beaucoup


Message édité par Zipo le 15-04-2005 à 22:47:42

---------------
- mon feed-back
Reply

Marsh Posté le 15-04-2005 à 22:40:41   

Reply

Marsh Posté le 15-04-2005 à 22:47:43    

Zipo a écrit :

Je cherche un algorithme récursif de la méthode de résolution des systèmes linéaires par pivot de Gauss, est ce que qqn aurait ça sous la main ??


La récursion, c'est esthétique, intello et tout, mais c'est très casse-gueule... Un pétage de mémoire automatique (aka 'pile' sur la plupart des implémentations) est toujours à craindre si la récursion s'enfonce un peu trop...


Message édité par Emmanuel Delahaye le 15-04-2005 à 22:48:43

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 15-04-2005 à 22:49:53    

Emmanuel Delahaye a écrit :

La récursion, c'est esthétique, intello et tout, mais c'est très casse-gueule... Un pétage de mémoire automatique (aka 'pile' sur la plupart des implémentations) est toujours à craindre si la récursion s'enfonce un peu trop...


oui je sais mais c'est justement pour comparer la version récusive avec l'itérative ;)


---------------
- mon feed-back
Reply

Marsh Posté le 16-04-2005 à 04:47:49    

Emmanuel Delahaye a écrit :

La récursion, c'est esthétique, intello et tout, mais c'est très casse-gueule... Un pétage de mémoire automatique (aka 'pile' sur la plupart des implémentations) est toujours à craindre si la récursion s'enfonce un peu trop...


 
C'est sur si on prend un language imperatif qui ne trouve rien de mieux que de passer en iteratif ...
 
Je pensais au fait qu'une structure de boucle generale (while par exemple) était équivalente à un simple appel recursif de la fonction sur elle meme en incrementant un certain i ...  :whistle: et en faisant un return quand ce fameux i atteignai une certaine valeur.


---------------
Scheme is a programmable programming language ! I heard it through the grapevine !
Reply

Marsh Posté le 19-04-2005 à 18:21:36    

personne n'a de réponse ? :(
 
:bounce:


---------------
- mon feed-back
Reply

Marsh Posté le 19-04-2005 à 19:17:58    

tu viens de l'avoir [:spamafote]


---------------
uptime is for lousy system administrators what Viagra is for impotent people - mes unixeries - github me
Reply

Marsh Posté le 19-04-2005 à 19:39:19    

Ah vous voulez que je récursive manuellement la version itérative ? ouai pas con mais ça risque d'être super chaud non?
 
j'ai trouvé une version C++ itérative que j'ai traduite en C comme ça :
 

Code :
  1. #include <stdio.h>
  2. int main(){
  3. int a, af, i, ligne, n, p, sol, t, x, y=0;
  4. double e[11][10], s[10];
  5. double temp, var1=0,var2=0;
  6. printf("programme de résolution utilisant le pivot de gauss\nEntrez le nombre d'équations à traiter\nN= " );
  7. scanf("%d", &n);
  8. printf("\n" );
  9. for (i=0; i<n; i++){
  10.         printf("equation %d\n", i+1);
  11.         for (p=0; p<n; p++){
  12.                 printf("var %d = ", p+1);
  13.                 scanf("%lf", &e[p][i]);
  14.         }
  15. printf("\nequation %d = ", i+1);
  16. scanf("%lf", &e[n][i]);
  17. printf("\n" );
  18. }       
  19. // on a donc saisi les facteurs des equations dans la matrice e
  20. for(x=0; x<n-1; x++){               
  21.         for(a=1+x; a<n; a++){
  22.        
  23.                 temp=e[x][a];
  24.        
  25.                 for (t=x; t<n+1; t++){
  26.                
  27.                         // On triangularise le système
  28.                         e[t][a] = e[t][a] * e[x][x] - e[t][x] * temp;
  29.        
  30.                 }
  31.         }
  32. }
  33. // On remplace
  34. s[n-1] = e[n][n-1] / e[n-1][n-1];
  35. e[n][n-1]=0;
  36. e[n-1][n-1]=0;
  37. for (ligne=1; ligne<=n; ligne++){
  38.         for (sol=2; sol<=n; sol++){
  39.                 e[n-ligne][n-sol] *= s[n-ligne];
  40.                 e[n][n-sol] -= e[n-ligne][n-sol];
  41.                 e[n-ligne][n-sol]=0;
  42.         }
  43.         s[n-(ligne+1)] = e[n][n-(ligne+1)] / e[n-(ligne+1)][n-(ligne+1)];
  44. }
  45. // Affichage
  46. printf("*** RESOLUTION ***\n\nLes solutions du système sont:\n" );
  47. for (af=0; af<n; af++)
  48.         printf("\n\tvar %d = %lf", af+1, s[af]);
  49. printf("\n" );
  50. getchar();
  51. return 0;
  52. }


 
la récursivation me semble assez chaude à faire non? [:gm_superstar]


Message édité par Zipo le 19-04-2005 à 19:39:47

---------------
- mon feed-back
Reply

Marsh Posté le 27-04-2005 à 08:19:44    

:hello:  Salut!
 
Beurk ton code !  :ouch:  
Précautions, ça te dit quelques chose?  :D  
Quelques manques de précaution évidents :
- si un pivot est nul, adieu la résolution ( tu peux remplacer les pivots nuls par des epsilons très petits, ta solution devient approximative )
- les divisions par zéro!!!!! (l.54)
- tu peux aussi faire un test pour savoir si le système admet une solution, cela t'évitera des surprises désagréables (calcul du rang de la matrice associée au système, calcul du déterminant, des trucs comme ça)
 
Pour la récursion, cela ne me semble pas très difficile puisque la méthode du pivot est une méthode récursive :
Avec N = nombre d'équations de départ et n = nombre d'équations restant après une étape de la méthode du pivot  
 
ResolRecur(n,N)
   - Si n=1 alors fin (trouver les solutions)
   - Sinon appliquer la méthode du pivot sur la sous matrice de taille n*(n+1) et ResolRecur(n-1,N)
 
Ainsi à chaque étape ton système est réduit d'une équation et d'une variable jusqu'à n=1. Voili, N est en paramètre uniquement pour savoir la taille de la matrice.
Bonne chance!  :hello:

Reply

Marsh Posté le 28-04-2005 à 10:44:00    

Je viens de traduire en récursif, j'obtiens ça :
ça vous parait correct ?
 

Code :
  1. #include <stdio.h>
  2. double e[11][10], s[10];
  3. int ERROR;
  4. void Triang2(double temp, int x, int n, int a, int t)
  5. {
  6. if(t<n+1){
  7. e[t][a] = e[t][a] * e[x][x] - e[t][x] * temp;
  8. Triang2(temp, x, n, a, t+1);
  9. }
  10. }
  11. void Triangularisation(int x, int n, int a)
  12. {
  13. double temp; int t;
  14. if(x<n-1){
  15. if(a<n){
  16.  temp=e[x][a];
  17.  Triang2(temp, x, n, a, x);
  18.  Triangularisation(x, n, a+1);
  19. }
  20. else
  21.  Triangularisation(x+1, n, 0);
  22. }
  23. }
  24. void RemplaceLigne(int n, int ligne, int sol)
  25. {
  26. if(ligne<=n){
  27. if(sol<=n){
  28.  e[n-ligne][n-sol] *= s[n-ligne];
  29.  e[n][n-sol] -= e[n-ligne][n-sol];
  30.  e[n-ligne][n-sol]=0;
  31.  RemplaceLigne(n, ligne, sol+1);
  32. }
  33. else{
  34.  if( e[n-(ligne+1)][n-(ligne+1)] != 0){
  35.   s[n-(ligne+1)] = e[n][n-(ligne+1)] / e[n-(ligne+1)][n-(ligne+1)];
  36.   RemplaceLigne(n, ligne+1, 0);
  37.  }
  38.  else{
  39.   printf("DIVISION PAR ZERO!!!\n\n" );
  40.   ERROR=1;
  41.  }
  42. }
  43. }
  44. }
  45. void Remplace(int n)
  46. {
  47. s[n-1] = e[n][n-1] / e[n-1][n-1];
  48. e[n][n-1]=0;
  49. e[n-1][n-1]=0;
  50. RemplaceLigne(n, 1, 2);
  51. }
  52. void Affichage(int af, int n)
  53. {
  54. if(af<n){
  55. printf("\n\tvar %d = %lf", af+1, s[af]);
  56. Affichage(af+1, n);
  57. }
  58. else{
  59. printf("\n" );
  60. getchar();
  61. }
  62. }
  63. int main(){
  64. int i, n, p;
  65. ERROR=0;
  66. printf("programme de résolution utilisant le pivot de gauss\nEntrez le nombre d'équations à traiter\nN= " );
  67. scanf("%d", &n);
  68. printf("\n" );
  69. for (i=0; i<n; i++){
  70. printf("equation %d\n", i+1);
  71. for (p=0; p<n; p++){
  72.  printf("var %d = ", p+1);
  73.  scanf("%lf", &e[p][i]);
  74. }
  75. printf("\nequation %d = ", i+1);
  76. scanf("%lf", &e[n][i]);
  77. printf("\n" );
  78. }
  79. // on a donc saisi les facteurs des equations dans la matrice e
  80. // RESOLUTION ET AFFICHAGE DES SOLUTIONS
  81. Triangularisation(0, n, 1);
  82. Remplace(n);
  83. if(!ERROR){
  84. printf("*** RESOLUTION ***\n\nLes solutions du système sont:\n" );
  85. Affichage(0, n);
  86. }
  87. }


 
j'ai mis un test pour les divisions par 0 apocalypse, par contre pourrai-tu m'expliquer + en détail l'histoire du epsilon ? mon prof nous en a parlé mais j'ai pas tout compris :/


Message édité par Zipo le 28-04-2005 à 10:56:48

---------------
- mon feed-back
Reply

Marsh Posté le 28-04-2005 à 17:53:20    

Salut zipo!  :hello:  
Alors deux choses :  
 
- pour ton programme :
 
il est pas super clair et optimisé  :o  surtout pour la résolution après triangularisation :
* le tableau s est inutile, tu peux stocker tes réponses dans la n+1 ième colonne.
* en général dans un tableau à deux dimensions : la première représente les lignes et la deuxième les colonnes...
* est-ce que ça serait pas plus simple de faire ceci : une fois une solution trouvée, disons la première, ligne n-1, colonne n dans ton pg. Tu soustrais pour toutes les lignes i telles que i<(n-1) (simple boucle) au terme de la colonne n (derrière le =) c*s[n-1] où c est le coeffiscient de la ligne i qui correspond à la variable dont tu viens de trouver la solution. Et après tu peux remplacer ce coef par zéro (même si c'est pas utile puisque tu ne les regardera plus :) ). Comme ça quand tu passes à la ligne suivante (du dessus) tu n'as plus rien à faire qu'une division. (si tu comprends pas je te ferai un exemple).
 
- pour l'histoire des coeffiscients nuls et des epsilons :
En général lorsqu'on résout un système de manière systématique, on suit cet ordre :
* vérification que le système a une solution et une seule (déterminant non nul je crois)
* on applique le pivot de gauss
Mais le problème est que même si le système a une solution, selon dans quel ordre les équations sont rentrées il se peut qu'un pivot soit nul et donc la résolution foire alors qu'il y a une solution. Il y a alors deux possibilités :
* changer l'ordre des équations ou des variables en priant d'en trouver un dans lequel le pb ne se représente pas, c'est certainement la meilleure solution. Elle est expliquée à cette adresse :  http://gershwin.ens.fr/vdaniel/Doc [...] ode90.html  
un lien sympa et très clair avec exemple : http://www.dil.univ-mrs.fr/~garret [...] /Pb_01.pdf  
 
* méthode des epsilons qui abouti à une solution approximative. Je ne sais pas ton niveau en maths et j'ai peur de t'embrouiller et de devoir faire cinq pages de commentaires. Si tu vraiment intéressé je repotasserai mes cours de DEUG et j'essayerai de te synthétiser ça.
 
Bonne chance!  :hello:

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed