Final exercice: Matrix class **************************** .. include:: ../BoutonGoogleTrad.rst L’objectif de cet exercice final est de développer une classe template pour gérer les matrices carrées :cpp:`square matrix`. Sa réalisation demande une bonne maîtrise des notions abordées dans les chapitres de cours précédents. .. warning:: :cppterm:`IA or not IA, that is the question.` Cet exercice est au programme de l'examen. Convention ========== .. image:: conv.png :scale: 40% :align: center Notations : * Une matrice :math:`M_{mn}` contient *m* lignes et *n* colonnes. * L'élément :math:`m_{ij}` se trouve sur la ligne *i* colonne *j*. * La notion :math:`m_{ij}` peut être contre-intuitive car en géométrie 2D, elle correspond à :math:`m_{yx}` et non :math:`m_{xy}` Partie I ======== Vous allez créer une classe générique :cpp:`SMatrix` pour représenter les matrices carrées. * Créez un fichier nommé :cpp:`SMatrix_base.cpp` * La classe :cpp:`SMatrix` doit être une classe template admettant comme paramètres : * Le type des données :cpp:`int, float, double...` * La largeur de la matrice * Pour stocker les valeurs, vous devez utiliser un ou plusieurs containers de la STL. * Les tableaux du C sont interdits * Plusieurs options sont possibles * Le containeur retenu doit être paramétré en utilisant les paramètres du template de la classe :cpp:`SMatrix` * Ce container sera déclaré :cpp:`private` * Fournissez l'accès à chaque élément par la syntaxe : :cpp:`M[i][j]` avec :cpp:`M` un objet :cpp:`SMatrix` : * En C++, peut-on créer directement un opérateur [][] ? * Cette syntaxe impose de choisir une modélisation adaptée : * Il faut choisir une modélisation pour la classe :cpp:`SMatrix` qui permette de la faire fonctionner. * Plusieurs options sont possibles et affectent directement le choix du container de données. * Pour cette classe, fournissez les fonctionnalités suivantes : * **Constructeur par défaut** : ne réalise aucune initialisation des éléments. * **Constructeur prenant une valeur** : initialise tous les éléments avec la valeur passée en paramètre. * **Constructeur par recopie** : reçoit un objet :cpp:`SMatrix` et recopie l’ensemble de ses valeurs. * :cpp:`size()` : retourne la largeur de la matrice. * :cpp:`get(i,j)` : retourne la valeur située à la position :cpp:`(i,j)` - on ne gère pas les indices hors plage * :cpp:`set(i,j, value)` : modifie la valeur située à la position :cpp:`(i,j)` - on ne gère pas les indices hors plage * :cpp:`print()` : affiche le contenu de la matrice sous la forme d'un tableau 2D * :cpp:`bool equals(const SMatrix & other)` : indique si l’objet courant contient les mêmes valeurs que l’objet passé en paramètre. * :cpp:`SMatrix& operator=(SMatrix other)` : copie le contenu d’un objet :cpp:`SMatrix` dans l’objet courant. * Fournissez un constructeur permettant d'initialiser les valeurs de la matrice à partir d'une liste de valeurs : * Exemple : :cpp:`SMatrix m({1, 2, 3, 4})` * Syntaxe permettant d’accepter une telle liste entre accolades : :cpp:`SMatrix(std::initializer_list values)` * Les valeurs doivent être placées ligne par ligne dans la matrice. * On supposera que le nombre de valeurs fournies correspond exactement au nombre d’éléments de la matrice. * L'utilisation du mot-clef :cpp:`const` doit être faite chaque fois que nécessaire. * Pour vérifier votre code, vous devez utiliser les tests suivants : :download:`test1.txt ` * Déposez votre fichier contenant la classe et les tests dans l'espace partagé Partie II ========= Opérateurs ---------- * Créez un fichier nommé :cpp:`SMatrix_operators.cpp` * Mettez en place les opérateurs externes suivants : * Addition et soustraction de deux matrices carrées * Multiplication entre deux matrices carrées * Multiplication d'une matrice par un nombre entier par la gauche et par la droite * Un opérateur externe est un opérateur déclaré comme une fonction et non comme une fonction membre * Créez une fonction :cpp:`t(...)` qui retourne la transposée de la matrice passée en argument friend keyword -------------- Comme nous créons des opérateurs externes (non membre de la classe), ils ne peuvent pas accéder aux données privées et doivent donc utiliser les accesseurs publics. Cependant, il est possible d'accéder aux données privées d'une classe depuis une fonction externe. Pour cela, il faut écrire la déclaration de cette fonction à l'intéreur de la classe et lui ajouter le qualificatif *friend* comme ceci : .. code-block:: cpp template ... class SMatrix { ... template ... friend ... operator+(...,...); }; Test final ---------- Vous devez pouvoir effectuer le calcul suivant en utilisant vos opérateurs : .. math:: A = A \cdot A^t + 2 \cdot A - A \cdot A Test ---- Vous devez pouvoir compiler et exécuter la ligne suivante : .. code-block:: cpp A = A * t(A) + 2 * A - A * A; Utilisez la matrice :cpp:`A= [ [1,2,3], [2,3,4], [3,4,5]]` pour tester votre résultat. Vous devez obtenir : .. code-block:: cpp >> 2 4 6 >> 4 6 8 >> 6 8 10 Travail sur l'espace partagé ---------------------------- * Le test demandé doit être présent dans le code * Uploadez le fichier :cpp:`SMatrix_operators.cpp` sur votre espace partagé