Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1159 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  Exercice C++ méthode de jacobi

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Exercice C++ méthode de jacobi

n°2222547
minimoack
Posté le 18-03-2014 à 14:23:42  profilanswer
 

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
mood
Publicité
Posté le 18-03-2014 à 14:23:42  profilanswer
 

n°2222549
rufo
Pas me confondre avec Lycos!
Posté le 18-03-2014 à 14:44:05  profilanswer
 

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
n°2222550
minimoack
Posté le 18-03-2014 à 14:46:48  profilanswer
 

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
n°2222551
rufo
Pas me confondre avec Lycos!
Posté le 18-03-2014 à 15:18:46  profilanswer
 

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
n°2222552
minimoack
Posté le 18-03-2014 à 15:23:59  profilanswer
 

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. }

n°2222553
minimoack
Posté le 18-03-2014 à 15:26:22  profilanswer
 

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

n°2222554
minimoack
Posté le 18-03-2014 à 15:27:07  profilanswer
 

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

n°2222560
rufo
Pas me confondre avec Lycos!
Posté le 18-03-2014 à 16:01:29  profilanswer
 

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
n°2222565
minimoack
Posté le 18-03-2014 à 16:14:50  profilanswer
 

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

n°2222569
minimoack
Posté le 18-03-2014 à 16:25:07  profilanswer
 

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. }

mood
Publicité
Posté le 18-03-2014 à 16:25:07  profilanswer
 

n°2222571
minimoack
Posté le 18-03-2014 à 16:27:27  profilanswer
 

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
n°2222585
minimoack
Posté le 18-03-2014 à 17:58:16  profilanswer
 

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

n°2222877
vckbm
tu destroye tout le monde
Posté le 22-03-2014 à 15:16:05  profilanswer
 

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
n°2227751
Joel F
Real men use unique_ptr
Posté le 11-05-2014 à 22:36:33  profilanswer
 

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.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  Exercice C++ méthode de jacobi

 

Sujets relatifs
Qt & C++Methode DoCmd.Setwarnings
[C] redirection gauche[HELP] Programme en C !
Language C Polynome[C++] manipulation de tableau a l'aide des references ?
Visual C++ 2010 Express et SDLC# Problème de clé absente du dictionnaire
[HELP] Visual C++ 
Plus de sujets relatifs à : Exercice C++ méthode de jacobi


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR