Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.73 KB | None | 0 0
  1. #include <cmath>        // pour les fonctions mathématiques
  2. #include <string>       // pour les string
  3. #include <sstream>      // pour les ostringstream
  4. #include <typeinfo>     // pour le typeid
  5. #include <iostream>     // pour les flux I/O
  6. #include <utility>
  7. using namespace std;
  8.  
  9. #include "CComplex.h"
  10.  
  11. // ----------------------------------------------------------------------------
  12. // Constructeurs / Desctructeur
  13. // ----------------------------------------------------------------------------
  14. /*
  15.  * Constructeur d'un complexe cartésien à partir de ses parties
  16.  * réelles et imaginaires
  17.  * @param r la partie réelle
  18.  * @param i la partie imaginaire
  19.  */
  20. template <class T>
  21. CComplex<T>::CComplex(const T r, const T i) // TODO Compléter la liste d'initialisation en n'oubliant pas de commencer par un des constructeurs de la classe mère
  22. {
  23.     this->NbInstances=this->NbInstances+1;
  24.     this->_real=r;
  25.     this->_imag=i;
  26.     this->_instanceNumber=this->NbInstances;
  27.  
  28.     clog << "CComplex<" << typeid(T).name() << ">[" << _instanceNumber
  29.         << "](" << r << ", " << i << ")";
  30.     clog << endl;
  31. }
  32.  
  33. /*
  34.  * Constructeur de copie d'un complexe cartésien
  35.  * @param c le complexe cartésien dont on doit copier les valeurs
  36.  */
  37. template <class T>
  38. CComplex<T>::CComplex(const Complex<T> & c) // TODO Compléter la liste d'initialisation en oubliant pas de commencer par un des constructeurs de la classe mère
  39. {
  40.     CComplex<T>(c.real(),c.imag());
  41.  
  42.     clog << "CComplex<" << typeid(T).name() << ">[" << _instanceNumber
  43.         << "](" << c << ")";
  44.     clog << endl;
  45. }
  46.  
  47. /*
  48.  * Constructeur de copie/conversion d'un complexe cartésien de nature différente
  49.  * @param c le complexe cartésien d'un autre type dont on doit
  50.  * copier les valeurs
  51.  */
  52. template <class T>
  53. template <class U>
  54. CComplex<T>::CComplex(const Complex<U> & c) // TODO Compléter la liste d'initialisation en oubliant pas de commencer par un des constructeurs de la classe mère
  55. {
  56.     /*
  57.      * NOTE pour caster on peut utiliser
  58.      * le cast de C ordinaire :
  59.      *  T1 v1 = ...
  60.      *  T2 v2 = (T2) v1;
  61.      * le static_cast du C++
  62.      *  T1 v1 = ...
  63.      *  T2 v2 = static_cast<T2>(v1);
  64.      */
  65.  
  66.     CComplex<T>((CComplex<T>) c);
  67.  
  68.  
  69.     clog << "CComplex<" << typeid(T).name() << ">[" << _instanceNumber << "]<"
  70.         << typeid(U).name() << ">(" << c << ")";
  71.     clog << endl;
  72. }
  73.  
  74. /*
  75.  * Véritable constructeur de copie d'un complexe cartésien de même type
  76.  * @param cc le complexe cartésien à copier
  77.  */
  78. template <class T>
  79. CComplex<T>::CComplex(const CComplex<T> & cc) // TODO Compléter la liste d'initialisation en oubliant pas de commencer par un des constructeurs de la classe mère
  80. {
  81.     CComplex<T>((CComplex<T>)cc);
  82.  
  83.     clog << "CComplex<" << typeid(T).name() << ">[" << _instanceNumber
  84.         << "](" << cc << ")";
  85.     clog << endl;
  86. }
  87.  
  88.  
  89. /*
  90.  * Constructeur de déplacement
  91.  * @param c le complexe à déplacer
  92.  * @post le nombre d'instances n'est pas changé
  93.  * @post le numéro d'instance de c a été copié dans this
  94.  */
  95. template <class T>
  96. CComplex<T>::CComplex(Complex<T> && c) :
  97.     Complex<T>(std::forward<Complex<T>>(c))
  98.     // TODO compléter la liste d'initialisation
  99. {
  100.  
  101.  
  102.     clog << "Move CComplex<" << typeid(T).name() << ">[" << _instanceNumber << "]"
  103.         << "(" << c << ")";
  104.     clog << endl;
  105.  
  106.     // TODO ne pas oublier de faire un reset sur c
  107. }
  108.  
  109.  
  110. template <class T>
  111. CComplex<T>::~CComplex()
  112. {
  113. //  clog << "~CComplex<" << typeid(T).name() << ">[" << _instanceNumber
  114. //      << "]";
  115. //  clog << endl;
  116. }
  117.  
  118. // ----------------------------------------------------------------------------
  119. // Propriétés des nombres complexes
  120. // ----------------------------------------------------------------------------
  121. /*
  122.  * partie réelle (accesseur en lecture seule)
  123.  * @return la partie réelle du nombre complexe
  124.  */
  125. template <class T>
  126. T CComplex<T>::real() const
  127. {
  128.     return this->_real;
  129. }
  130.  
  131. /*
  132.  * partie réelle (accesseur en lecture/écriture)
  133.  * @return une référence vers la partie réelle du nombre complexe
  134.  */
  135. template <class T>
  136. T & CComplex<T>::real()
  137. {
  138.     return (this->_real);
  139. }
  140.  
  141. /*
  142.  * Partie imaginaire (accesseur en lecture seule)
  143.  * @return la partie imaginaire du nombre complexe
  144.  */
  145. template <class T>
  146. T CComplex<T>::imag() const
  147. {
  148.     return this->_imag;
  149. }
  150.  
  151. /*
  152.  * Partie imaginaire (accesseur en lecture/écriture)
  153.  * @return une référence vers la partie imaginaire du nombre complexe
  154.  */
  155. template <class T>
  156. T & CComplex<T>::imag()
  157. {
  158.     return (this->_imag);
  159. }
  160.  
  161. /*
  162.  * Norme du nombre complexe dans le plan complexe
  163.  * @return la norme du nombre dans le plan complexe
  164.  */
  165. template <class T>
  166. T CComplex<T>::abs() const
  167. {
  168.     // TODO remplacer par l'implémentation
  169.     return sqrt(((this->_real)*(this->_real))+((this->_imag)*(this->_imag)));
  170. }
  171.  
  172. /*
  173.  * L'angle du nombre dans le plan complexe.
  174.  * a > 0            ==> theta = atan(b/a) ou atan2(b,a)
  175.  * a < 0 & b >= 0   ==> theta = atan(b/a) + PI
  176.  * a < 0 & b < 0    ==> theta = atan(b/a) - PI
  177.  * a = 0 & b > 0    ==> PI/2
  178.  * a = 0 & b < 0    ==> -PI/2
  179.  * a = 0 & b = 0    ==> indéterminé
  180.  * @return l'angle du nombre dans le plan complexe
  181.  */
  182. template <class T>
  183. double CComplex<T>::arg() const throw (ComplexException)
  184. {
  185.     if(this->_real>0){
  186.         return atan(this->_imag/this->_real);
  187.     }
  188.     else if(this->_real<0){
  189.         if(this->imag()>=0){
  190.             return atan(this->_imag/this->_real)+M_PI;
  191.         }
  192.         else{
  193.             return atan(this->_imag/this->_real)-M_PI;
  194.         }
  195.     }
  196.     else {
  197.         if(this->_imag>0){
  198.             return M_PI/2;
  199.         }
  200.         else if(this->_imag<0){
  201.             return -M_PI/2;
  202.         }
  203.         else {
  204.             return 0.0;
  205.         }
  206.     }
  207. }
  208.  
  209. // ----------------------------------------------------------------------------
  210. // Self Operations
  211. // ----------------------------------------------------------------------------
  212. /*
  213.  * Opérateur de copie à partir de n'importe quel complexe
  214.  * @param la référence d'un autre nombre complexe
  215.  * @return la référence vers le nouveau nombre complexe
  216.  */
  217. template <class T>
  218. template <class U>
  219. Complex<T> & CComplex<T>::operator =(const Complex<U> & c)
  220. {
  221.     return *this;
  222. }
  223.  
  224. /*
  225.  * Opérateur de copie à partir d'un complexe cartésien
  226.  * @param la référence d'un autre nombre complexe à copier
  227.  * @return la référence vers le nouveau nombre complexe
  228.  * @note Cette méthode est redondante avec celle définie juste au dessus
  229.  * mais étant donné qu'elle était définie dans la classe abstraite
  230.  * Complex<T> elle DOIT être implémentée ici, quitte à utiliser
  231.  * la méthode ci-dessus dans son corps.
  232.  */
  233. template <class T>
  234. Complex<T> & CComplex<T>::operator =(const Complex<T> & c)
  235. {
  236.     /*
  237.      * TODO Remplacer par
  238.      * Réutilisation de l'opérateur ci-dessus en précisant le paramètre de
  239.      * type <T>
  240.      */
  241.     return *this;
  242. }
  243.  
  244. /*
  245.  * Véritable opérateur de copie à partir d'un complexe cartésien
  246.  * @param c la référence vers le complex à coller
  247.  * @return la référence vers le nombre complexe courant
  248.  * @post le contenu du complex c est copié dans le complex courant
  249.  */
  250. template <class T>
  251. Complex<T> & CComplex<T>::operator =(const CComplex<T> & c)
  252. {
  253.     // TODO Compléter ...
  254.  
  255.     return *this;
  256. }
  257.  
  258. /*
  259.  * Opérateur de déplacement à partir d'un complexe
  260.  * @param c la référence d'un autre nombre complexe à déplacer
  261.  * @return la référence vers le nombre complexe courant
  262.  * @post le nombre d'instances n'a pas été changé
  263.  * @post le numéro d'instance de c a été copié dans this en utilisant
  264.  */
  265. template <class T>
  266. Complex<T> & CComplex<T>::operator =(Complex<T> && c)
  267. {
  268.     // TODO Compléter (sans oublier de faire un reset sur c) ...
  269.  
  270.     return *this;
  271. }
  272.  
  273. /*
  274.  * Opérateur de self addition.
  275.  * @param c le complexe à ajouter au complexe courant
  276.  * @return une référence vers le complexe courant
  277.  */
  278. template <class T>
  279. Complex<T> & CComplex<T>::operator +=(const Complex<T> & c)
  280. {
  281.     // TODO Compléter ...
  282.  
  283.     return *this;
  284. }
  285.  
  286. /*
  287.  * Opérateur de self soustraction.
  288.  * @param c le complexe à soustraire au complexe courant
  289.  * @return une référence vers le complexe courant
  290.  */
  291. template <class T>
  292. Complex<T>& CComplex<T>::operator -=(const Complex<T> & c)
  293. {
  294.     // TODO Compléter ...
  295.  
  296.     return *this;
  297. }
  298.  
  299. /*
  300.  * Opérateur de self multiplication.
  301.  * @param c le complexe à multiplier au complexe courant
  302.  * @return une référence vers le complexe courant
  303.  */
  304. template <class T>
  305. Complex<T>& CComplex<T>::operator *=(const Complex<T> & c)
  306. {
  307.     // (a+ ib)*(c +id) = (ac-bd) + i(bc+ad)
  308.     // TODO Compléter ...
  309.  
  310.     return *this;
  311. }
  312.  
  313. /*
  314.  * Opérateur de self division.
  315.  * @param c le complexe qui divise le complexe courant
  316.  * @return une référence vers le complexe courant
  317.  */
  318. template <class T>
  319. Complex<T> & CComplex<T>::operator /=(const Complex<T> & c)
  320. {
  321.     // (a + ib)      ac + bd         bc - ad
  322.     // -------- =  ----------- + i -----------
  323.     // (c + id)     c^2 + d^2       c^2 + d^2
  324.     // TODO Compléter ...
  325.  
  326.     return *this;
  327. }
  328.  
  329. // ----------------------------------------------------------------------------
  330. // Operations
  331. // ----------------------------------------------------------------------------
  332. /*
  333.  * Opérateur d'addition de deux nombres complexes.
  334.  * @param la référence vers un autre nombre complexe
  335.  * @return un nouveau nombre complexe résultant de l'addition
  336.  */
  337. template <class T>
  338. CComplex<T> CComplex<T>::operator +(const CComplex<T> & c) const
  339. {
  340.     CComplex<T> newComplex(*this);
  341.  
  342.     // TODO Compléter (voir sujet p4) ...
  343.  
  344.     return newComplex;
  345. }
  346.  
  347. /*
  348.  * Opérateur d'addition de deux nombres complexes quelconques
  349.  * @param c la référence vers un autre nombre complexe
  350.  * @return un poiteur vers un nouveau nombre complexe résultant de
  351.  * l'addition (La classe Complex<T> étant abstraite, elle ne peut pas
  352.  * avoir d'instances, il faut donc utiliser soit des références, soit
  353.  * des pointeurs)
  354.  */
  355. template <class T>
  356. Complex<T> * CComplex<T>::operator +(const Complex<T> & c) const
  357. {
  358.     Complex<T> * newComplex = new CComplex<T>(*this);
  359.  
  360.     // TODO Compléter (voir sujet p4) ...
  361.  
  362.     return newComplex;
  363. }
  364.  
  365. /*
  366.  * Opérateur de soustraction de deux nombres complexes
  367.  * @param la référence vers un autre nombre complexe
  368.  * @return un nouveau nombre complexe résultant de l'addition
  369.  */
  370. template <class T>
  371. CComplex<T> CComplex<T>::operator -(const CComplex<T> & c) const
  372. {
  373.     CComplex<T> newComplex(*this);
  374.  
  375.     // TODO Compléter (voir sujet p4) ...
  376.  
  377.     return newComplex;
  378. }
  379.  
  380. /*
  381.  * Opérateur de soustraction de deux nombres complexes quelconques
  382.  * @param c la référence vers un autre nombre complexe
  383.  * @return un pointeur vers un nouveau nombre complexe résultant de
  384.  * la soustraction
  385.  */
  386. template <class T>
  387. Complex<T> * CComplex<T>::operator -(const Complex<T> & c) const
  388. {
  389.     Complex<T> * newComplex = new CComplex<T>(*this);
  390.  
  391.     // TODO Compléter (voir sujet p4) ...
  392.  
  393.     return newComplex;
  394. }
  395.  
  396. /*
  397.  * Opérateur de multiplication de deux nombres complexes
  398.  * @param la référence vers un autre nombre complexe
  399.  * @return un nouveau nombre complexe résultant de l'addition
  400.  */
  401. template <class T>
  402. CComplex<T> CComplex<T>::operator *(const CComplex<T> & c) const
  403. {
  404.     CComplex<T> newComplex(*this);
  405.  
  406.     // TODO Compléter (voir sujet p4) ...
  407.  
  408.     return newComplex;
  409. }
  410.  
  411. /*
  412.  * Opérateur de multiplication de deux nombres complexes quelconques
  413.  * @param c la référence vers un autre nombre complexe
  414.  * @return un pointeur vers un nouveau nombre complexe résultant de
  415.  * la multiplication
  416.  */
  417. template <class T>
  418. Complex<T> * CComplex<T>::operator *(const Complex<T> & c) const
  419. {
  420.     Complex<T> * newComplex = new CComplex<T>(*this);
  421.  
  422.     // TODO Compléter (voir sujet p4) ...
  423.  
  424.     return newComplex;
  425. }
  426.  
  427. /*
  428.  * Opérateur de division de deux nombres complexes
  429.  * @param la référence vers un autre nombre complexe
  430.  * @return un nouveau nombre complexe résultant de l'addition
  431.  */
  432. template <class T>
  433. CComplex<T> CComplex<T>::operator /(const CComplex<T> & c) const
  434. {
  435.     CComplex<T> newComplex(*this);
  436.  
  437.     // TODO Compléter (voir sujet p4) ...
  438.  
  439.     return newComplex;
  440. }
  441.  
  442. /*
  443.  * Opérateur de division de deux nombres complexes quelconques
  444.  * @param c la référence vers un autre nombre complexe
  445.  * @return un pointeur vers un nouveau nombre complexe résultant de
  446.  * la division
  447.  */
  448. template <class T>
  449. Complex<T> * CComplex<T>::operator /(const Complex<T> & c) const
  450. {
  451.     Complex<T> * newComplex = new CComplex<T>(*this);
  452.  
  453.     // TODO Compléter (voir sujet p4) ...
  454.  
  455.     return newComplex;
  456. }
  457.  
  458. /*
  459.  * Inverse d'un complexe cartésien.
  460.  * \f[ \frac{1}{a + ib} = \frac{a - ib}{a^2 + b^2} \f]
  461.  * @return le complexe inversé
  462.  * @throw ComplexException si l'on tente de créer un complexe inverse
  463.  * à partir d'un complexe de parties réelle et imaginaire nulle ce
  464.  * qui entraine une division par zéro.
  465.  */
  466. template <class T>
  467. Complex<T> * CComplex<T>::inverse() const throw (ComplexException)
  468. {
  469.     CComplex<T> * newComplex  = NULL;
  470.  
  471.     //     1       a - ib
  472.     // -------- = ---------
  473.     // (a + ib)   a^2 + b^2
  474.  
  475.     /*
  476.      * TODO Compléter ...
  477.      * En commençant par le calcul du dénominateur car si celui ci est nul
  478.      * il faudra lever une exception comme vous l'avez déjà fait dans
  479.      * Complex<T>::computeArgument
  480.      */
  481.  
  482.     return newComplex;
  483. }
  484.  
  485. /*
  486.  * Complexe conjugué.
  487.  * \f[ \overline{a + ib} = a - ib \f]
  488.  * @return une référence vers le complexe conjugué
  489.  */
  490. template <class T>
  491. Complex<T> * CComplex<T>::conjugate() const
  492. {
  493.     // conjugate(a+ib) = a-ib
  494.     // TODO remplacer par l'implémentation
  495.     return NULL;
  496. }
  497.  
  498. // ----------------------------------------------------------------------------
  499. // Affichage
  500. // ----------------------------------------------------------------------------
  501. /*
  502.  * Chaine de caractères représentant l'objet
  503.  * @return une chaine de caractères représentant le Complexe
  504.  */
  505. template <class T>
  506. string CComplex<T>::toString() const
  507. {
  508.     // ostringstream s'utilise comme un flux de sortie
  509.     ostringstream outstring;
  510.  
  511.     /*
  512.      * TODO Compléter par l'ajout dans outstring en utilisant les
  513.      * opérateurs de sortie standard (<<) des différents éléments
  514.      * format à respecter pour les tests : (real + i imag)[instanceNumber]
  515.      */
  516.  
  517.     outstring << "(" << this->_real  << " + i " << this->_imag << ")[" << this->_instanceNumber << "]";
  518.  
  519.     return outstring.str();
  520. }
  521.  
  522. /*
  523.  * Opérateur d'entrée à partir d'une référence.
  524.  * @pre le Complexe doit déjà exister et est remplit avec les valeurs
  525.  * lue sur le flux d'entrée : on lit d'abord la partie réelle puis la partie
  526.  * imaginaire
  527.  * @param in le flux d'entrée à partir duquel on lit
  528.  * @param c référence vers le Complexe à remplir
  529.  * @return une référence vers le flux d'entrée de manière à pouvoir
  530.  * cumuler les opérateurs
  531.  */
  532. template <class T>
  533. istream & operator >>(istream & in, CComplex<T> & c)
  534. {
  535.     in >> c._real;
  536.     in >> c._imag;
  537.  
  538.     return in;
  539. }
  540.  
  541. // ----------------------------------------------------------------------------
  542. // Opérateurs de conversion vers d'autres types de contenus
  543. // ----------------------------------------------------------------------------
  544.  
  545. /*
  546.  * Opérateur de conversion générique d'un CComplex<T> en CCompplex<U>
  547.  * @return une instance de CComplex<U>
  548.  */
  549. template <class T>
  550. template <class U>
  551. CComplex<T>::operator CComplex<U>() const
  552. {
  553.     // TODO Remplacer par l'implémentation
  554.     return CComplex<U>();
  555. }
  556.  
  557. /*
  558.  * Remise à zéro d'une instance de complexe déplacé
  559.  * @post le numéro d'instance est remis à 0 et les parties réelles
  560.  * et imaginaires sont remises à Complex<T>::ZERO
  561.  */
  562. template <class T>
  563. void CComplex<T>::reset()
  564. {
  565.     /*
  566.      * TODO Compléter par :
  567.      *  - reset parent
  568.      *  - remise à ZERO des parties réelles et imaginaires
  569.      */
  570. }
  571.  
  572. // ----------------------------------------------------------------------------
  573. // Instanciations et spécialisations
  574. // ----------------------------------------------------------------------------
  575. // proto instanciation du template CComplex pour les double
  576. template class CComplex<double>;
  577. // proto instanciation des méthodes templatisées
  578. template CComplex<double>::CComplex(const Complex<int> &); // int --> double
  579. template CComplex<double>::CComplex(const Complex<float> &); // float --> double
  580. template Complex<double> & CComplex<double>::operator =(const Complex<int> &);
  581. template Complex<double> & CComplex<double>::operator =(const Complex<float> &);
  582. template CComplex<double>::operator CComplex<int>() const;
  583. template CComplex<double>::operator CComplex<float>() const;
  584.  
  585. // proto instanciation du template CComplex pour les float
  586. template class CComplex<float>;
  587. // proto instanciation des méthodes templatisées
  588. template CComplex<float>::CComplex(const Complex<double> &); // double --> float
  589. template CComplex<float>::CComplex(const Complex<int> &); // int --> float
  590. template Complex<float> & CComplex<float>::operator =(const Complex<int> &);
  591. template Complex<float> & CComplex<float>::operator =(const Complex<double> &);
  592. template CComplex<float>::operator CComplex<int>() const;
  593. template CComplex<float>::operator CComplex<double>() const;
  594.  
  595. // proto instanciation du template CComplex pour les int
  596. template class CComplex<int>;
  597. // proto instanciation des méthodes templatisées
  598. template CComplex<int>::CComplex(const Complex<double> &); // double --> int
  599. template CComplex<int>::CComplex(const Complex<float> &); // float --> int
  600. template Complex<int> & CComplex<int>::operator =(const Complex<float> &);
  601. template Complex<int> & CComplex<int>::operator =(const Complex<double> &);
  602. template CComplex<int>::operator CComplex<double>() const;
  603. template CComplex<int>::operator CComplex<float>() const;
  604.  
  605. // instanciation des opérateurs externes sur les templates protoinstanciés
  606. template istream & operator >>(istream &, CComplex<double> &);
  607. template istream & operator >>(istream &, CComplex<float> &);
  608. template istream & operator >>(istream &, CComplex<int> &);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement