IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Des retours sur mon implémentation d'une classe Matrix


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Profil pro
    Spleen
    Inscrit en
    Mai 2013
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Spleen

    Informations forums :
    Inscription : Mai 2013
    Messages : 78
    Par défaut Des retours sur mon implémentation d'une classe Matrix
    Bonjour à vous !

    Je tenais d'abord à remercier les participants de ce forum pour toute l'entraide dont ils font part tout les jours.
    J'essaye aussi souvent que faire se peut d' apporter aussi mon aide. C'est la première fois, de mémoire, que je demande un avis sur mon travail sur dvp.com.

    Passons au vif du sujet : j'implémente depuis plusieurs semaines une classe Matrix, comme ça pour le fun ; une classe Matrix qui n'a pas pour but de concurrencer OpenBLAS ou Eigen au niveau des perfs, mais qui tient tout de même la route au niveau des performances. Je n'étais pas prêt à faire des compromis au niveau de la compréhension du code et n'est donc pas, volontairement, ajouté l'utilisation des registres SSE/AVX, ni de choses trop... exotiques.
    Je souhaitais juste une bibliothèque facile à lire, qui gère tout contenu numérique, Coplien et qui gère un maximum d'opérations sur les matrices.
    Il me reste encore :
    - Inverse d'une matrice
    - Déterminant d'une matrice
    - Proposer une transposition inplace qui ne crée pas de nouvelle matrice

    Hier soir je suis passé en mode template, avec un tpp, mais j'ai préféré tout rajouter dans le header, par commodité uniquement (désolé mais avec les templates je ne m'en sortais plus, beaucoup font cela apparemment, juste un .h)

    Voici le code (bonne lecture).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    /*
    *   Created by N.Richard
    *   Date de création : 5 mai 2014
    *   Date de version : 14 mai 2014
    *   Version 1.0
    *   Principe : Bibliothèque simple pour la gestion de matrices (forme coplien)
    */
     
    #ifndef MATRIX_H
    #define MATRIX_H
     
    #include "Utilities.h"
    #ifdef _OPENMP
        #include <omp.h>
    #endif //_OPENMP
    #include <iostream>
    #include <stdexcept>
    #include <string.h>
     
    template <typename T>
    class Matrix {
     
    public:
        //Constructors
        Matrix (int nbrows, int nbcolumns): _rows(nbrows), _cols(nbcolumns), _values(NULL)
        {
            if (nbrows <= 0 || nbcolumns <= 0)
                throw std::domain_error("Matrix can't have a zero size");
            _values = new T[nbrows * nbcolumns]();
        }
     
        Matrix(const Matrix& mat) : _rows(mat.getNbRows()), _cols(mat.getNbCols()), _values(NULL)
        { 
     
            if (mat._values != NULL) {
                    _values = new T[_rows*_cols]();
                    memcpy(_values,mat._values, _rows*_cols * sizeof(T));
            }
        } 
     
        //Operators override
        Matrix& operator= (const Matrix &mat)
        {
            if (this != &mat){
     
                Matrix tmp (mat);
     
                _rows = tmp._rows; 
                _cols = tmp._cols; 
                std::swap(_values, tmp._values); 
            }
            return *this;
        }
     
        bool operator== (const Matrix& mat)
        {
            if ((_rows != mat._rows)
                || (_cols != mat._cols))
                return false;
     
            for(int i=0; i < _rows*_cols ; ++i)
                if (!equal(_values[i], mat._values[i]))
                    return false;
     
            return true;
        }
     
        bool operator!= (const Matrix& mat) const
        {
            return !(*this == mat);    
        }
     
        bool operator!() const 
        {
            return isNull();
        }
     
        Matrix operator~() const 
        {
            return transpose();
        }
     
        T& operator() (int nbrows, int nbcolumns)
        {
            #ifndef NDEBUG
            if (nbrows >= _rows || nbcolumns >= _cols
                || nbrows < 0 || nbcolumns < 0)
                throw std::out_of_range("const Matrix subscript out of bounds");
            #endif  //NDEBUG
            return _values[_cols*nbrows + nbcolumns];
        }   
     
        T operator() (int nbrows, int nbcolumns) const
        {
            #ifndef NDEBUG
            if (nbrows >= _rows || nbcolumns >= _cols
                || nbrows < 0 || nbcolumns < 0)
                throw std::out_of_range("const Matrix subscript out of bounds");
            #endif  //NDEBUG
            return _values[_cols*nbrows + nbcolumns];
        }
     
        Matrix transpose() const
        {
            Matrix transposeMat (_cols, _rows);
     
            for(int i=0 ; i < _cols ; ++i)
                for(int j=0 ; j < _rows ; ++j)
                    transposeMat.set(i,j,at(j,i));
     
            return transposeMat;
        }
     
        Matrix add(const Matrix& mat) const
        {
            if(_cols != mat._cols || _rows != mat._rows)
                throw std::domain_error("Matrix type not compatible for addition. Both matrices must have the same number of rows and columns"); 
     
            Matrix addMat (_rows, _cols); 
     
            #ifdef _OPENMP
            #pragma omp parallel for
            #endif //_OPENMP
            for (int i = 0; i < _rows; ++i)
                for (int j = 0; j < _cols; ++j)
                    addMat(i,j) = at(i,j) + mat(i,j);
     
            return addMat;
        }
     
        Matrix mult(const Matrix& mat) const
        {
            if(_cols != mat._rows || _rows != mat._cols)
                throw std::domain_error("Matrix type not compatible for multiplication"); 
     
            Matrix multMat (_rows, _cols);
     
            #ifdef _OPENMP
            #pragma omp parallel for
            #endif //_OPENMP
            for (int i = 0; i < _rows; ++i)
                for(int k = 0; k < _rows; ++k)
                    for(int j = 0; j < _cols; ++j)
                        multMat(i,j) += at(i,k) * mat(k,j);
     
            return multMat;
        }
     
        template <typename NumericType> 
        Matrix mult (const NumericType op) const
        {
            Matrix multMat (_rows, _cols);
     
            #ifdef _OPENMP
            #pragma omp parallel for
            #endif //_OPENMP
            for (int i = 0; i < _rows; ++i)
                for(int j = 0; j < _cols; ++j)
                    multMat(i,j) += at(i,j) * op;
     
            return multMat;
        }
     
        Matrix pow (const int p) const
        {
            if(!isSquare())
                throw std::domain_error("Matrix type not compatible for pow operation. Matrix must be square"); 
     
            if (p == 0)
                return Matrix::identity (_rows, _cols);
            else if (p == 1)
                return *this;
            else if (p%2 == 0){
                Matrix powmat(_rows, _cols, false);
                powmat = pow(p/2);
                return powmat*powmat;
            }
            else if (p%2 == 1){
                Matrix powmat(_rows, _cols, false);
                powmat = pow (p/2);
                return powmat*powmat**this;
            }
            else 
                throw std::domain_error("For the moment, this library don't manage negative or float pow. As soon as possible !"); 
     
            return *this;
        }
     
        static Matrix identity(const int nbrows, const int nbcolumns)
        {
            if(nbrows != nbcolumns)
                throw std::domain_error("Matrix type not compatible for identity. Matrix must be square"); 
     
            Matrix identityMat (nbrows, nbcolumns); 
     
            for (int i = 0; i < nbrows; ++i)
                identityMat.set(i, i, static_cast<T>(1));
     
            return identityMat;
        }
     
        void clear(T value = 0)
        {
            for(int i=0 ; i < _cols ; ++i)
                for(int j=0 ; j < _rows ; ++j)
                    set(i,j,value);
        }
     
        //Getters & Setters
        T at(int i, int j) const
        {
            return operator()(i,j);
        }
     
        void set(const int i, const int j, T value)
        {
            operator()(i,j) = value;
        }
     
        int getNbRows() const
        {
            return _rows;
        }
     
        int getNbCols() const
        {
            return _cols;
        }
     
        static int getCoutWidth()
        {
            return Matrix::COUTWIDTH;
        }
     
        static void setCoutWidth(const int width)
        {
            Matrix::COUTWIDTH = width+1;
        }
     
        bool isSquare () const
        {
            return (_cols == _rows);
        }
     
        bool isIdentity() const
        {
            if (!isDiagonal())
                return false;
     
            for(int i=0; i < _rows; ++i)
                if(!equal(at(i,i),1))
                    return false;
     
            return true;
        }
     
        bool isDiagonal() const
        {
            if (!isSquare())
                return false;
     
            for(int i=0; i < _rows; ++i)
                for(int j=0; j < _cols; ++j)
                    if (i!=j && !equal(at(i,j),0))
                        return false;
     
            return true;
        }
     
        bool isNull() const
        {
            for(int i=0; i < _rows; ++i)
                for(int j=0; j < _cols; ++j)
                    if (!equal(at(i,j), 0))
                        return false;
     
            return true;
        }
     
        bool isUpperTriangular() const
        {
            if (!isSquare())
                return false;
     
            for(int i = 1; i < _rows; ++i)
                for (int j = 0; i != j && j < _cols ; ++j)
                    if (!equal(at(i,j), 0))
                        return false;
     
            return true;
        }
     
        bool isLowerTriangular() const
        {
            if (!isSquare())
                return false;
     
            for(int i = 0; i < _rows; ++i)
                for (int j = i+1; j < _cols ; ++j)
                    if (!equal(at(i,j), 0))
                        return false;
     
            return true;
        }
     
        //Matrix display
        void show () const
        {
            std::cout <<*this;    
        }
     
        //Destructor
        ~Matrix()
        {
            delete[] _values;
        }
     
        static int COUTWIDTH;
     
    private:
        int _rows, _cols;
        T* _values;
     
    };
     
    template<typename T>
    int Matrix<T>::COUTWIDTH = 8;
     
    template<typename T, typename NumericType> 
    Matrix<T> operator* (const NumericType op, const Matrix<T>& mat)
    {
        return mat.mult(op);
    }
     
    template<typename T, typename NumericType> 
    Matrix<T> operator* (const Matrix<T>& mat, const NumericType op)
    {
        return mat.mult(op);
    }
     
    template<typename T, typename U>
    Matrix<T> operator* (const Matrix<T>& mat1, const Matrix<U>& mat2)
    {
        return mat1.mult(mat2);
    }
     
    template<typename T, typename NumericType> 
    Matrix<T>& operator*= (const NumericType op, Matrix<T>& mat)
    {
        return (mat = mat.mult(op));
    }
     
    template<typename T, typename NumericType> 
    Matrix<T>& operator*= (Matrix<T>& mat,const NumericType op)
    {
        return (mat = mat.mult(op));
    }
     
    template<typename T, typename U>
    Matrix<T>& operator*= (Matrix<T>& mat1, const Matrix<U>& mat2)
    {
        return (mat1 = mat1.mult(mat2));
    }
     
    template<typename T, typename U>
    Matrix<T> operator+ (const Matrix<T>& mat1, const Matrix<U>& mat2)
    {
        return mat1.add(mat2);
    }
     
    template<typename T, typename U>
    Matrix<T>& operator+= (Matrix<T>& mat1, const Matrix<U>& mat2)
    {
        return (mat1 = mat1.add(mat2));
    }
     
    template <typename T>
    std::ostream& operator << (std::ostream& out, const Matrix<T>& mat)
    {
        out <<"Matrix " <<mat.getNbRows() <<"x" <<mat.getNbCols() <<std::endl;
     
        for(int i=0 ; i <= mat.getNbCols()*Matrix<T>::COUTWIDTH+1; ++i)
                out <<"=";
        out <<std::endl;   
     
        for(int i=0 ; i < mat.getNbRows(); ++i)
        {
            out <<"|";
            out.width(Matrix<T>::COUTWIDTH);
            out <<mat(i, 0);
     
            for(int j=1 ; j < mat.getNbCols(); ++j)
            {
                out.width(Matrix<T>::COUTWIDTH);
                out << std::right <<mat(i,j);
            }
            out <<"|" <<std::endl;
        }
     
        return out;
    }
     
    #endif //MATRIX_H
    J'écouterai toutes les remarques constructives. N'hésitez surtout pas.
    Je sais que beaucoup verront des choses qui leurs feront saigner les yeux. C'est justement ça que je veux corriger
    Merci à tous et à toutes

  2. #2
    Membre chevronné
    Inscrit en
    Décembre 2010
    Messages
    290
    Détails du profil
    Informations forums :
    Inscription : Décembre 2010
    Messages : 290
    Par défaut
    Salut et bravo pour ton code, l'idée est intéressante.

    Quelques suggestions, en vrac:
    - Jette un oeil à OpenCV, qui possède une classe cv::Mat hyper complète, pour des suggestions de fonctionnalités.

    - Pour des matrices de petite taille (genre 3x3 ou 4x3) dont les dimensions sont connues à la compilation, tu pourrais aussi proposer un template similaire mais sans allocation mémoire dynamique.
    ça revient un peu à remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Matrix {
    ...
        T* _values;
    };
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Matrix {
    ...
        T _values[width*height];
    };
    Un peu à la manière du nouveau type std::array en C++11.
    Un des avantages c'est que tu évites une allocation mémoire dynamique, ce qui peut être coûteux.

    - Je ne sais pas quels sont tes besoins, mais tu pourrais proposer des itérateurs pour se balader dans la matrice. Tu pourrais même définir plusieurs types d'itérateurs, pour des accès dans un ordre particulier ou par exemple juste un sous-ensemble (une ligne ou une colonne).

  3. #3
    Membre émérite

    Homme Profil pro
    Non disponible
    Inscrit en
    Décembre 2012
    Messages
    478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Non disponible

    Informations forums :
    Inscription : Décembre 2012
    Messages : 478
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    La fonction show() determine UN moyen d'affichage, le mieux serait, comme l'a dit phi1981, d'utiliser des itérateurs pour séparer le system d'affichage de la matrice.

    L'operateur d'égalité pourrait ce contenter d'une boucle pour comparer les tableaux.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class Matrix {
    ...
        T _values[width*height];
    };
    Il possible de passer la taille en paramètre de template.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    template<typename Type, size_t width, size_t height>
    class Matrice{ .... };
    Mais cela implique de connaître la taille à la compilation.

  4. #4
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Salut !

    C’est courageux de jeter son code en pâture aux loups qui vont s’empresser de se jeter dessus pour émettre de très nombreuses critiques, en tout cas, félicitations pour ta démarche !

    Et sinon, puisqu’on parle de critiques, en voici quelques unes :

    - c’est un choix de design, mais je trouve qu’il y a beaucoup trop de fonctions membres. Des fonctions comme « transpose » n’ont pas de raison d’être membres. Idem pour mult, add, etc, qui sont membres mais pourraient plutôt être statiques ou libres.
    - Ta méthode identity a un paramètre en trop : tu forces l’égalité entre les deux paramètres au runtime : autant ne garder qu’un seul paramètre, ça t’évitera des erreurs et le contrat sera le même.
    - Dans un autre domaine, il me semble qu’il est interdit (enfin, déconseillé) d’utiliser des noms de variables commençant par _, mieux vaut donc le mettre à la fin, ou le faire précéder de m : m_cols, m_rows…
    - L’implémentation d’operator= pourrait vérifier que le buffer actuel est assez grand pour contenir l’autre matrice et ne pas réallouer dans ce cas (si on travaille sur des grosses matrices, en allouer une temporaire n’est pas forcément une bonne idée, surtout si on peut s’en passer).
    - L’opérateur == devrait, pour des raisons de perfs, utiliser memcmp, ou en tout cas travailler directement sur le buffer sans passer par les operator(x,y) qui vont recalculer l’index à chaque fois ce qui est inutile.
    - les opérateurs () ont des paramètres mal nommés.
    - là encore, c’est un choix, mais à mon sens, appeler isDiagonal() sur une matrice non carrée ne doit pas renvoyer faux car c’est une violation de contrat --> exception puisque c’est comme ça que tu l’as géré ailleurs.
    - ta matrice devrait être itérable (idéalement, de différentes manières).

    Et bien sûr, tout ce qui a déjà été dit par les autres .

  5. #5
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Je rajouterai:
    - Les opérateurs binaires devraient être libres (même si pour les matrices il n'y devrait pas y avoir de grosse différence), et const-correct!
    - l'opérateur d'affectation n'a pas à tester l'auto-affectation : tu impactes les performances pour rien (il est rare que l'on écrive a=a; )
    - Les tests de bornes devraient être des assertions. Elles sont faites pour tester les erreurs de programmation. Elles sont bien plus efficaces à ce jeu que la programmation défensive.
    - J'aurai posé pour invariant de la classe que (m!)._values n'est jamais nul.
    - J'aurai défini un fonction offset, cela sert toujours.
    - Plein de fonctions (add, mult, ..) qui ne devraient pas exister. Si tu les as déjà croisées, c'est la faute à des cours qui prennent trop leur temps pour présenter la surcharge des opérateurs.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  6. #6
    Membre actif
    Profil pro
    Spleen
    Inscrit en
    Mai 2013
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Spleen

    Informations forums :
    Inscription : Mai 2013
    Messages : 78
    Par défaut
    Citation Envoyé par phi1981 Voir le message
    Salut et bravo pour ton code, l'idée est intéressante.
    Merci beaucoup ! Je suis un amoureux du beau code et surtout du C/C++ ; j'essaye de m'imprégner de toutes les bonnes idées et plus j'en apprends dessus plus je me rends compte du chemin astronomique qu'il me reste ^^'

    Citation Envoyé par phi1981 Voir le message
    Quelques suggestions, en vrac:
    - Jette un oeil à OpenCV, qui possède une classe cv::Mat hyper complète, pour des suggestions de fonctionnalités.
    Mon frère connait très bien les méandres d'OpenCV, je vais lui demander !

    Citation Envoyé par phi1981 Voir le message
    - Pour des matrices de petite taille (genre 3x3 ou 4x3) dont les dimensions sont connues à la compilation, tu pourrais aussi proposer un template similaire mais sans allocation mémoire dynamique.
    ça revient un peu à remplacer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Matrix {
    ...
        T* _values;
    };
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    class Matrix {
    ...
        T _values[width*height];
    };
    Un peu à la manière du nouveau type std::array en C++11.
    Un des avantages c'est que tu évites une allocation mémoire dynamique, ce qui peut être coûteux.

    - Je ne sais pas quels sont tes besoins, mais tu pourrais proposer des itérateurs pour se balader dans la matrice. Tu pourrais même définir plusieurs types d'itérateurs, pour des accès dans un ordre particulier ou par exemple juste un sous-ensemble (une ligne ou une colonne).
    Oui effectivement mais là je vois pas comment m'y prendre à part créer des classes Matrix3f, Matrix4f, Matrix3i, etc... ce qui peut être très laborieux (et pas forcément sexy je trouve).
    Je sèche complètement sur les itérateurs. Je n'ai clairement pas l'habitude de les utiliser, je veux bien un lien.

    Citation Envoyé par Iradrille Voir le message
    Rhoo, c'est le plus intéressant pourtant.
    C'est ajouter à la TODOLIST une fois que j'aurai une version satisfaisante esthétiquement
    Citation Envoyé par Iradrille Voir le message
    Il y à quelques variables qui ont des noms qui prêtent à confusion
    C'est corrigé, effectivement
    Citation Envoyé par Iradrille Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef Matrix<float> matf;
    typedef Matrix<double> matd;
     
    matf f(4, 4);
    matd d(4, 4);
     
    auto m = f * d; // devrait être possible et retourner une matd
    auto m = matd(f) * d; // ou éventuellement comme ça
    Est-ce que cela suffit ?
    template<typename T, typename U>
    Matrix<T> operator* (const Matrix<T>& mat1, const Matrix<U>& mat2)
    {
    return mat1.mult(mat2);
    }

    Citation Envoyé par Iradrille Voir le message
    Petit détail, le #include <omp.h> devrait lui aussi être entouré de #ifdef _OPENMP / #endif.
    Ajouté !
    Citation Envoyé par Iradrille Voir le message
    Et ton operateur<< devrait appeler show.
    J'ai fait l'inverse : show est spécialisé pour le renvoyé dans la sortir standard.
    L'erreur était dû à un qq ajouts antérieur dans show ^^
    Citation Envoyé par PilloBuenaGente Voir le message
    L'operateur d'égalité pourrait ce contenter d'une boucle pour comparer les tableaux.
    CHECK ! Même si, j'ai oublié de préciser que j'étais en -O3 (déroulement de boucles) avec toutes les options sympathiques de g++.
    Citation Envoyé par PilloBuenaGente Voir le message
    d'utiliser des itérateurs pour séparer le system d'affichage de la matrice.
    Je ne vois pas trop.
    Citation Envoyé par PilloBuenaGente Voir le message
    Il possible de passer la taille en paramètre de template.
    Ces paramètres deviendront obligatoire si je fais ça. Je peux les créer moi-même (réponse précédente) à ce moment-là ?

    Merci vraiment pour tous vos retours !

    Je corrige le code de mon premier post en prenant en compte vos avis. Histoire que l'étudiant passant sur mon post trouve directement de quoi le sustenter.

  7. #7
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Citation Envoyé par Spleeen Voir le message
    Je n'étais pas prêt à faire des compromis au niveau de la compréhension du code et n'est donc pas, volontairement, ajouté l'utilisation des registres SSE/AVX, ni de choses trop... exotiques.
    Rhoo, c'est le plus intéressant pourtant.

    2/3 commentaires :
    Effectivement une version sans allocation dynamique pour les matrices de petites tailles pourrait être un plus.

    Il y à quelques variables qui ont des noms qui prêtent à confusion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Matrix mult(const Matrix& mat) const
    {
    	if(_cols != mat._rows || _rows != mat._cols)
    		throw std::domain_error("Matrix type not compatible for multiplication"); 
     
    	Matrix mult (_rows, _cols);
    	...
    }
    Nommer une variable mult, dans une fonction mult
    En survolant le code, j'ai cru à un appel de fonction.

    Permettre des opérations sur des types compatibles (ou au minimum la conversion) peut être utile aussi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    typedef Matrix<float> matf;
    typedef Matrix<double> matd;
     
    matf f(4, 4);
    matd d(4, 4);
     
    auto m = f * d; // devrait être possible et retourner une matd
    auto m = matd(f) * d; // ou éventuellement comme ça
    Petit détail, le #include <omp.h> devrait lui aussi être entouré de #ifdef _OPENMP / #endif.

    Et ton operateur<< devrait appeler show.

Discussions similaires

  1. [Débutant] integrer des methodes (implémentées dans une classe cs) a un web service
    Par mimi-imene-91 dans le forum Services Web
    Réponses: 0
    Dernier message: 29/11/2012, 14h28
  2. Réponses: 3
    Dernier message: 28/01/2007, 19h25
  3. Réponses: 2
    Dernier message: 04/04/2006, 23h22
  4. Conseil du compilo sur un destructeur d'une classe
    Par okparanoid dans le forum Langage
    Réponses: 2
    Dernier message: 20/07/2005, 20h11
  5. Réponses: 12
    Dernier message: 01/07/2004, 11h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo