Exercice C++ méthode de jacobi

Exercice C++ méthode de jacobi - C++ - Programmation

Marsh Posté le 18-03-2014 à 14:23:42    

Bonjour,
 
j'ai un exercice à faire en C++. j'ai commencé, mais je suis bloquée avec la méthode de jacobi. je ne comprends pas trop, est-ce que quelqu'un pourrait m'expliquer svp?
 

Citation :

L'objectif de cette séance est d'implémenter en C++ le début d'une classe « matrice » : les champs qui définissent chaque matrice, deux constructeurs, une méthode d'affichage, ainsi qu'une méthode permettant de résoudre, avec la méthode de Jacobi, un système d'équations linéaires.
 
Les champs de la classe « matrice »
Chaque matrice est définie par : ses dimensions et un tableau contenant les éléments de la matrice.
Constructeurs
 
Pour pouvoir facilement tester vos programmes sur des petites matrices, il vous faut au moins un constructeur prenant en paramètre un tableau contenant tous les éléments de la matrice. Ainsi, pour tester vos programmes sur la matrice ci-contre, vous devriez pouvoir écrire des lignes de code qui ressemblent à :
double T[9] = {10,-1,0,-1,10,-2,0,1,-10} ;
matrice * A = new matrice(3,3,T) ;
 
Méthodes de base
Il est pratique d'avoir des méthodes pour lire un élément de la matrice et modifier un élément de la matrice, appelées par exemple get et set. Il est aussi recommandé d'avoir une méthode permettant un affichage simple, ligne par ligne, d'une matrice de petite taille.
 
Méthode de Jacobi
Pour résoudre un système d'équations linéaires de la forme Ax=b, où A est une matrice carrée de dimension n, b un vecteur de taille n, on calcule une suite récurrente définie par :
r^(k+1) = D^(-1) * ( b - (L+U) * r^(k))
 
Écrivez une méthode, prenant en paramètre le vecteur b (un vecteur est une matrice n × 1), permettant de calculer simplement cette suite : il suffit d'exprimer le terme r(k+1)j en fonction des r(k)ij, des Aij et des bj.
 
Comme pour la méthode de la sécante vue en TDs, il faut deux variables, contenant la valeur courante du vecteur r et la valeur suivante, soit par exemple rcour et rsuiv ; alors la i-ème composante de r est mise à jours comme suit :
rsuiv(i) = (b(i) - sum{0 <= m < n} à {m <> i} (A(im) * rcour(m))) / A(ii)


 
Voilà ce que j'ai fait pour l'instant :  

Code :
  1. Matrices.h
  2. #pragma once
  3. #include <iostream>
  4. using namespace std;
  5. class Matrices
  6. {
  7. private :
  8. // Dimensions de la matrice
  9. int nbLignes, nbColonnes;
  10. //Tableau de valeurs
  11. double * tab;
  12. public :
  13. //Destructeur
  14. ~Matrices(void);
  15. //Constructeur
  16. Matrices(int=0, int=0, double * =NULL);
  17. //Constructeur par recopie
  18. Matrices(const Matrices & );
  19. void Afficher();
  20. int getLigne();
  21. int getColonne();
  22. double getTableau();
  23. double setTableau(double *, int, double);
  24. };


 

Code :
  1. Matrices.cpp
  2. #include "StdAfx.h"
  3. #include "Matrices.h"
  4. #include <iostream>
  5. #include <math.h>
  6. using namespace std;
  7. Matrices::~Matrices()
  8. { delete[] tab; }
  9. Matrices::Matrices(int l, int c, double t[])
  10. {
  11. nbLignes = l;
  12. nbColonnes = c;
  13. tab = newdouble[nbLignes*nbColonnes];
  14. for (int i = 0; i < nbLignes*nbColonnes; i++)
  15. {
  16.  tab[i] = t[i];
  17. }
  18. }
  19. //Constructeur par recopie
  20. Matrices::Matrices(const Matrices &m)
  21. {
  22. nbLignes = m.nbLignes;   
  23. nbColonnes = m.nbColonnes;   
  24. tab = newdouble [nbLignes*nbColonnes];   
  25. for (int i = 0; i < nbLignes*nbColonnes; i++)   
  26. {
  27.  tab[i] = m.tab[i];   
  28. }
  29. }
  30. void Matrices ::  Afficher()
  31. {
  32. int compteur = 1;
  33. cout<<"Voici la matrice : "<<endl;
  34. for (int i = 0; i < nbColonnes*nbLignes; i++)
  35. {
  36.  if (compteur == nbColonnes+1)
  37.  {
  38.   cout<<"\n";
  39.   cout<<tab[i]<<" ";
  40.   compteur = 2;
  41.  }
  42.  else
  43.  {
  44.  cout<<tab[i]<<" ";
  45.  compteur++;
  46.  }
  47. }
  48. cout<<"\n";
  49. }
  50. int Matrices :: getLigne()
  51. {
  52. return nbLignes;
  53. }
  54. int Matrices :: getColonne()
  55. {
  56. return nbColonnes;
  57. }
  58. double Matrices :: getTableau()
  59. {
  60. return *tab;
  61. }
  62. double setTableau(double * tab, int i, double n)
  63. {
  64. tab[i] = n;
  65. return *tab;
  66. }


 

Code :
  1. LesMatrices.cpp
  2. #include "stdafx.h"
  3. #include "Matrices.h"
  4. int_tmain(int argc, _TCHAR* argv[])
  5. {
  6. double T[9] = {10,-1,0,-1,10,-2,0,1,-10} ;
  7. Matrices * A = new Matrices(3,3,T) ;
  8. A->Afficher();
  9. system("PAUSE" );
  10. return 0;
  11. }


 
:jap:


Message édité par minimoack le 18-03-2014 à 19:56:02
Reply

Marsh Posté le 18-03-2014 à 14:23:42   

Reply

Marsh Posté le 18-03-2014 à 14:44:05    

Je comprends pas pourquoi ta fonction setTableau prend en 1er paramètre une variable membre de la classe :??:


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-03-2014 à 14:46:48    

ah oui effectivement, c'est plutôt :  
void setTableau(int i, double n)
{
 tab[i] = n;
}
 
non?


Message édité par minimoack le 18-03-2014 à 14:54:08
Reply

Marsh Posté le 18-03-2014 à 15:18:46    

oui, c'est ce que j'aurais fait, avec une vérification tout de même sur la valeur de n : >=0 et < à la taille allouée de la matrice.
Si n est < 0, tu lèves une erreur, mais si > à la taille de la matrice, tu pourrais proposer de faire une réalloc automatique afin d'agrandir la matrice... ;)
 
Edit : au passage, pour une question de lisibilité du programme, même si la matrice est stockée sous forme d'un tableau à une dimension, j'aurais plutôt fait des méthodes set() et get() prenant en paramètres "ligne" et "colonne" plutôt qu'un simple entier.
set(int Lig, int Col, double val)
get(int Lig, int Col)
 
Le calcul matriciel reposant beaucoup sur les indices de lignes et colonnes je pense que ça sera plus facile de travailler avec des méthodes, elles aussi à base de Lig et Col plutôt qu'un simple entier :/


Message édité par rufo le 18-03-2014 à 15:23:44

---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-03-2014 à 15:23:59    

ok merci, et est-ce que tu aurais une idée sur l'histoire de jacobi? il me semble juste qu'il faut récupérer la matrice diagonale, la matrice inférieure à la diagonale ainsi que la matrice supérieure à la diagonale, mais c'est tout, et je ne vois pas vraiment comment les récupérer vu comment j'ai fais mon tableau/matrice... je suis un peu perdue ^^
 

Code :
  1. void setTableau(int i, double n)
  2. {
  3. if (i >= O && i < nbLignes)
  4.       { tab[i] = n; }
  5. else
  6.       { cout<<"erreur" ; }
  7. }

Reply

Marsh Posté le 18-03-2014 à 15:26:22    

Mais c'est un tableau à une dimension... donc du coup je le modifie en 2 dimensions?

Reply

Marsh Posté le 18-03-2014 à 15:27:07    

et pour les get, il n'y a pas besoin de paramètres si?

Reply

Marsh Posté le 18-03-2014 à 16:01:29    

Code :
  1. void setTableau(int i, double n)
  2. {
  3.    if ((i >= 0) && (i < nbLignes))
  4.          { tab[i] = n; }
  5.    else
  6.          { cout<<"erreur" ; }
  7.    }


Mon set et get, c'est pour récupérer un seul élément de la matrice, pas pour toute une ligne ou colonne ;)
 
Et non, tu peux rester en 1 dimension pour le stockage mais avoir 2 paramètres pour l'accès.
Position d'un élément = ((NumLig - 1) * nbcolonnes) + (NumCol - 1)
Avec NumLig appartient à [1..nblignes] et NumCol à [1..nbcolonnes].


---------------
Astres, outil de help-desk GPL : http://sourceforge.net/projects/astres, ICARE, gestion de conf : http://sourceforge.net/projects/icare, Outil Planeta Calandreta : https://framalibre.org/content/planeta-calandreta
Reply

Marsh Posté le 18-03-2014 à 16:14:50    

ah ok c'est pas les mêmes get et set que les miens ! ok je vais essayer merci, je post dès que je l'ai fait

Reply

Marsh Posté le 18-03-2014 à 16:25:07    

Code :
  1. void setValeur(int ligne, int colonne, double valeur)
  2. {
  3.      if ((ligne >= 0) && (ligne < nbLignes) && (colonne >= 0) && (colonne < nbColonnes)) 
  4.      {
  5.           tab[((ligne - 1) * nbColonnes) + (colonne - 1)] = valeur;
  6.      }
  7.      else
  8.      {   cout<<"erreur"; }
  9. }

Reply

Marsh Posté le 18-03-2014 à 16:25:07   

Reply

Marsh Posté le 18-03-2014 à 16:27:27    

Code :
  1. double getValeur(int ligne, int colonne)
  2. {
  3.      if ((ligne >= 0) && (ligne < nbLignes) && (colonne >= 0) && (colonne < nbColonnes))
  4.      {
  5.          return tab[((ligne - 1) * nbColonnes) + (colonne - 1)];
  6.      }
  7.      else
  8.      {   cout<<"erreur"; }
  9. }


Message édité par minimoack le 18-03-2014 à 16:27:56
Reply

Marsh Posté le 18-03-2014 à 17:58:16    

et pour le truc de jacobi, une idée?

Reply

Marsh Posté le 22-03-2014 à 15:16:05    

salut déjà la matrice est carrée donc pas la peine d'utiliser lignes et colonnes, juste une matrice carré de taille n

Code :
  1. private:
  2. unsigned int size;


stocker une matrice comme un vecteur est une bonne chose pour la rapidité d'execution il me semble
 
à ta place j'utiliserai la classe standard vector

Code :
  1. #include <vector>
  2. vector<double> matrix;
  3. et les données membres suivantes:
  4. vector<double> get_upper_matrix();
  5. vector<double> get_lower_matrix();
  6. vector<double> get_diagonal_matrix();


définies de la façon suivante:

Code :
  1. vector<double> get_lower_matrix()
  2. {
  3. vector<double> lower_matrix = matrix;
  4. for (unsigned int i=0; i<size; i++)
  5. {
  6. if ( i%sqrt(size) > (i - i%sqrt(size))/sqrt(size) ) // != et > pour diagonale et l'autre matrice
  7.     lower_matrix[i] = 0.;
  8. }
  9. return lower_matrix;
  10. }
  11. %% j'ai pas testé ce code, juste une indication


Message édité par vckbm le 22-03-2014 à 15:22:12

---------------
A Vendre
Reply

Marsh Posté le 11-05-2014 à 22:36:33    

if dans un for et modulo/division sont des drames de performances, mieux faut faire une chtite boucle sur i/j et linearisez l'index d'access.

Reply

Sujets relatifs:

Leave a Replay

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