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

Boost C++ Discussion :

classe avec membre matrix de taille 2*2


Sujet :

Boost C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut classe avec membre matrix de taille 2*2
    Bonjour!
    Voilà, j'ai une classe M, dont le seul membre est une matrix de boost. Ces matrices sont toujours de taille 2*2

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    class M{
    private:
    	boost::numeric::ublas::matrix<double> m_M;
    };
    J'aimerais pouvoir spécifier quelque part directement la taille de la matrix, histoire d'avoir un constructeur du type

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    M::M(){
    for (i=0;i<2;i++)
    for (j=0;j<2;j++)
    m_M(i,j) =0;
    }
    C'est à dire qu'en gros, à chaque fois que je crée un objet M, il faudrait qu'il sache déjà que la matrix de boost est de taille 2*2.

    Merci beaucoup par avance

  2. #2
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Bonjour,
    Euuu, as-tu jeté un coup d'oeil à la doc ?
    Le tout premier exemple est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    int main () {
        using namespace boost::numeric::ublas;
        matrix<double> m (3, 3);
        for (unsigned i = 0; i < m.size1 (); ++ i)
            for (unsigned j = 0; j < m.size2 (); ++ j)
                m (i, j) = 3 * i + j;
        std::cout << m << std::endl;
    }
    Donc apparement, on peut fixer les dimensions d'une matrice dans son constructeur...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    M::M() : m_M(2,2)
    {
       for (i=0;i<2;i++)
       for (j=0;j<2;j++)
       m_M(i,j) =0;
    }

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Attention, la classe de boost n'a pas été crée avec des petites matrices de taille fixe en tête. En terme de performances, il y a probablement de bien meilleures solutions à considérer.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Alp
    Alp est déconnecté
    Expert confirmé

    Avatar de Alp
    Homme Profil pro
    Inscrit en
    Juin 2005
    Messages
    8 575
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Juin 2005
    Messages : 8 575
    Par défaut
    Un boost::array< <boost::array< double, N>, M > serait peut-être une meilleure représentation, au fait près qu'il faudrait réécrire toutes les routines de travail sur les matrices

  5. #5
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Oui on évite au moins l'allocation dynamique, mais je pensais à un truc comme les tinymatrix de blitz (mais le site web correspondant a l'air d'avoir été abandonné).
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    ->arzar: Merci bien pour ta réponse... Effectivement, ça m'était sorti de la tête qu'on pouvait écrire la chose comme ça... Désolé, mais je débute.

    -> Les autres: Merci pour le conseil des array, je vais l'utiliser, j'avais déjà réécris les fonctionnalité dont j'avais besoin, ça ne sera pas trop long!

    En fait, au début, je faisais un vector< vector<double> >, mais effectivement, ce n'est pas super performant!
    J'ai essayé aussi la solution tableau de tableau de double, mais c'était super compliqué de les passer en arguments à des fonctions. Il fallait faire des pointeurs de pointeurs, enfin, quelque chose qui me semblait être une usine à gaz!
    Donc, en résumé, la solution array <array <double> >vous paraît plutôt bonne?
    Pour tout dire, je fais plutôt des maths et écris un programme pour trianguler des surfaces. Les matrices en questions, ce sont les sommets des triangles que je construis, donc il va y en avoir beaucoup... (je représente les points par des matrices). je dirais entre 1000 et 10000 à chaque exécution du programme. Et je pense les stocker dans un vector.

    Suis ravis de tout commentaire!
    En tout cas, merci beaucoup pour ces messages, je ne trouve personne autour de moi pour passer 5 min à me répondre, et sur ce site, ça va tout seul, c'est formidable!

    PS: boost::array< <boost::array< double, N>, M > le N et le M correspondent bien à la taille de chacune des array, n'est-ce-pas?

  7. #7
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    En effet, pour gérer plein de petits points, il faut éviter à tout prix une allocation dynamique ! Donc une solution à base de tableaux de taille fixe semble de rigueur. Après, array<array<double, 2>, 2> ou array<double, 4>, je ne sais pas trop, il faudrait faire des tests.

    Un autre point où il est possible de gagner du temps avec les petites matrices, c'est en déroulant la boucles. C'est je crois ce ue faisait blitz, mais le site est mort. Si tu as moyen de te procurer C++ template, the complete guide (Jossutis et Vandevorde), la technique est démontrée.

    Les autres choses qu'une telle solution peut apporter, c'est une vérification à la compilation des tailles de matrices, éventuellement les expression templates peuvent aussi faire gagner un peu de temps, mais moins que pour les grosses matrices, je pense.

    Je viens de rechercher s'il existe des bibliothèques du genre de blitz++, mais encore vivantes, car pour tirer tous les avantages du C++ en terme d'expressivité et de performance, ça demande de mettre en oeuvre des techniques avancées. J'ai trouvé http://tvmet.sourceforge.net/introduction.html je ne sais pas ce que ça vaut, le projet a l'air à l'arrêt depuis quelque temps aussi.


    Autrement, je n'ai pas trop compris pourquoi représenter les points par des matrices et non des vecteurs ?
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Merci pour ton message.

    "Dérouler la boucle" pour gagner du temps... Là, je n'ai pas compris...

    Pourquoi je représente les matrices par des points? Comme j'ai dit, je fais des maths, et je travaille sur des surfaces hyperboliques. Et il se trouve que la représentation des sommets par des matrices simplifie beaucoup de problèmes mathématiques... mais complique la programmation

    J'imagine que le plus simple (rapide) serait de faire des tableaux de tableaux 2*2 (l'avantage étant d'avoir accès aux éléments par tab[][]), le gros problème, c'est, mais peut-être pourrais-je faire tout simplement un tableau à 4 éléments et faire attention dans la définition du produit matriciel, etc...

  9. #9
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Citation Envoyé par Alp Voir le message
    Un boost::array< <boost::array< double, N>, M > serait peut-être une meilleure représentation, au fait près qu'il faudrait réécrire toutes les routines de travail sur les matrices
    Pour être sûr d'être contigu, pourquoi pas un array de taille N*N ?
    Citation Envoyé par JolyLoic Voir le message
    Oui on évite au moins l'allocation dynamique, mais je pensais à un truc comme les tinymatrix de blitz (mais le site web correspondant a l'air d'avoir été abandonné).
    Blitz est malheureusement plus maintenu. Eigen semble vouloir prendre le relai, mais je ne sais pas s'il ya des petites matrices.
    Citation Envoyé par JolyLoic Voir le message
    En effet, pour gérer plein de petits points, il faut éviter à tout prix une allocation dynamique ! Donc une solution à base de tableaux de taille fixe semble de rigueur. Après, array<array<double, 2>, 2> ou array<double, 4>, je ne sais pas trop, il faudrait faire des tests.

    Un autre point où il est possible de gagner du temps avec les petites matrices, c'est en déroulant la boucles. C'est je crois ce ue faisait blitz, mais le site est mort. Si tu as moyen de te procurer C++ template, the complete guide (Jossutis et Vandevorde), la technique est démontrée.

    Les autres choses qu'une telle solution peut apporter, c'est une vérification à la compilation des tailles de matrices, éventuellement les expression templates peuvent aussi faire gagner un peu de temps, mais moins que pour les grosses matrices, je pense.

    Je viens de rechercher s'il existe des bibliothèques du genre de blitz++, mais encore vivantes, car pour tirer tous les avantages du C++ en terme d'expressivité et de performance, ça demande de mettre en oeuvre des techniques avancées. J'ai trouvé http://tvmet.sourceforge.net/introduction.html je ne sais pas ce que ça vaut, le projet a l'air à l'arrêt depuis quelque temps aussi.


    Autrement, je n'ai pas trop compris pourquoi représenter les points par des matrices et non des vecteurs ?
    Pas de performances, malheureusement. Le C++ restera à ce niveau plus lent que le C et le Fortran.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par manitor Voir le message
    "Dérouler la boucle" pour gagner du temps... Là, je n'ai pas compris...
    Si par exemple tu fais le produit de deux matrices 2x2 c=a*b, tu vas écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    for(int i=0;i<2;i++) 
         for(int j=0;j<2;j++) {
              c[i][j]=0;
              for(int k=0;k<2;k++) c[i][j]+=a[i][k]*b[k][j];
         }
    Mais tu iras plus vite en écrivant "en clair"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    for(int i=0;i<2;i++) 
         for(int j=0;j<2;j++) {
              c[i][j]=a[i][0]*b[0][j]+a[i][1]*b[1][j];
         }
    Tu viens là de "dérouler" la boucle centrale, tu peux faire pareil pour les deux autres. Ca ira généralement plus vite, parce que cela élimine les tests à la fin des boucles for. Ceci dit, pour de toutes petites boucles comme celles ci, je pense que ton compilateur le fait automatiquement : compile en mode release, et regarde le code produit, avant de passer une heure à tout faire à la main...

    Citation Envoyé par manitor Voir le message
    J'imagine que le plus simple (rapide) serait de faire des tableaux de tableaux 2*2 (l'avantage étant d'avoir accès aux éléments par tab[][]), le gros problème, c'est, mais peut-être pourrais-je faire tout simplement un tableau à 4 éléments et faire attention dans la définition du produit matriciel, etc...
    Tu peux conserver les accès [][] aux éléments en définissant ta matrice comme un tableau 2*2... Par exemple en faisant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    double data[2*2]; // données de ton tableau
    double *tab[2];
    tab[0]=&data[0];
    tab[1]=&data[2];
    Tu pourras encore écrire tab[0][0], et tab[1][0], ou data[i] qui devrait aller plus vite. En jouant sur ces deux représentations, tu peux avoir à la fois la représentation tab[][] quand c'est nécessaire (pour des raisons de lisibilité, par exemple), et la représentation en tableau[] dans les fonctions ou tu dois aller vite.

    Francois
    Dernière modification par Invité ; 06/06/2009 à 10h28.

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Merci François, ta solution me plaît bien!

    Dernière question, si je définis ma classe comme suit, j'ai laissé un exemple typique de contructeur, c'est bien comme cela que marche?
    De plus, j'aurais besoin de pouvoir accéder aux membre de la fonction, et cela dans des méthodes dont la HG_Matrix est déclarée const, typiquement:
    void HG_Matrix::Affiche() const qui m'affiche la matrice en question. Mais je n'ai aucune idée de la façon dont je pourrais écrire les Getdata et GetMat correspondant. En fait, il me semble que ce n'est pas possible parce que m_Mat[i][j] permet toujours d'accéder et modifier la valeur du double vers lequel il pointe. Enfin, je dis ça, mais je marche sur des oeufs

    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
    class HG_Matrix
    {
    private :
    double m_data[2*2];
    double *m_Mat[2];
    
    public:
    HG_Matrix();
    retour????? HG_Matrix::GetMat() const {return m_Mat ????;};
    };
    
    HG_Matrix :: HG_Matrix()
    {
    	m_Mat[0] = &m_data[0];
    	m_Mat[1] = &m_data[2];
    	m_Mat[0][0] = 0;
    	m_Mat[0][1] = 1;
    	m_Mat[1][0] = -1;
    	m_Mat[1][1] = 0;
    }

  12. #12
    Invité
    Invité(e)
    Par défaut
    Je ne suis pas certain de comprendre ce que tu cherche à faire, mais voici comment je ferais...

    Pour les accès, je définirais ma classe un peu comme ca

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    const int nlig=2;
    const int ncol=2;
     
    struct Matrice {
        double data[nlig*ncol];
        double *operator[](int lig) {return &data[lig*ncol];}
    }:
    de cette façon, tu peux écrire mat[0][0], et mat[1][0]. (et ca marche avec des matrices de taille fixe, mais quelconque)

    j'aurais aussi tendance à laisser publiques les données de la classe (c'est pour cela que j'utilise un struct). Si tes fonctions de calcul spécialisé ont besoin d'un tableau de 4 double, tu leur passeras directement mat.data...

    Tu peux bien sur les garder privées, et définir quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    double *GetMat(void) {return &data[0];}
    mais je n'en vois pas bien l'intérêt.

    Tu n'as pas besoin d'un constructeur pour l'allocation, mais il peut être souhaitable d'en écrire un pour initialiser data...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Matrice() {for(int i=0;i<nlig*ncol;i++) data[i]=0;}
    En revanche, le constructeur de copie et l'opérateur d'affectation n'ont pas besoin d'être écrits. Ton compilateur comprendra correctement du code comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    matrice m;
    m[1][1]=m[0][0]=1;
    matrice n=m;
    n[1][0]=2;
    m=n;
    (ce ne serait pas le cas si tu avais défini explicitement une variable membre double *lignes)

    Enfin, pour écrire/afficher, il te faudra probablement quelque chose comme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    ostream &operator<<(ostream &s,matrice &m)
    {
    for(int i=0;i<nlig;i++) {
       for(int j=0;j<ncol;j++) s<<m[i][j]<<" ";
       s<<endl;
    }
    return s;
    }
    Note que ceci n'est pas, loin s'en faut, d'une "bonne" classe de matrice. Le principal problème, à mon avis, est l'absence de gestion des colonnes. Pour allez plus loin, regarde les valarray de la Librairie Standard C++, et notamment la notion de slice.

    Francois
    Dernière modification par Invité ; 06/06/2009 à 14h21.

Discussions similaires

  1. Classe avec membres const dans un vecteur
    Par PilloBuenaGente dans le forum Langage
    Réponses: 17
    Dernier message: 18/04/2013, 14h27
  2. Réponses: 20
    Dernier message: 06/02/2013, 00h17
  3. Pb avec membre d'une classe
    Par omdafer dans le forum Windows Forms
    Réponses: 17
    Dernier message: 26/05/2007, 20h44
  4. probleme compilation classe avec Borland c++ compiler 5.5
    Par softblue dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 17/06/2004, 15h16
  5. Objets/Classes avec un SGBD
    Par tiboleo dans le forum Décisions SGBD
    Réponses: 13
    Dernier message: 09/11/2003, 16h04

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