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

SL & STL C++ Discussion :

STL et les matrices...


Sujet :

SL & STL C++

  1. #1
    Membre éclairé Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Par défaut STL et les matrices...
    Bonjour,

    Quelle est la meilleure méthode à adopter pour coder des matrices?
    Je m'explique, je pourrais me contenter d'un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    double* a = new double[n][n];
    mais cela n'est pas "secure". Je souhaiterais utiliser la STL pour éviter les fuites mémoires.
    Je pensais à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::vector <std::vector <double> >
    mais ce n'est pas très pratique pour les resizes (à faire sur chaque ligne...)

    Si je pouvais déclarer mes matrices comme cela:
    Ce serait génial.

    Note importante: je n'ai pas besoin des opérations de base car il s'agit plus d'un conteneur qu'autre chose...

    Auriez-vous une idée et/ou des conseils?

    Cordialement,
    Rodrigue

  2. #2
    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
    Effectivement, ce n'est pas le mieux, de plus l'espace mémoire n'est pas contigu.
    Soit tu prends une bibliothèque existante à la boost::uBLAS, MTL, Blitz++, ... soit tu te fais une classe perso avec une surcharge de l'opérateur () qui prend 2 unsigned int et te renvoie le bon élément.

  3. #3
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Salut !

    perso, pour les matrices, j'utilise généralement des map< pair<unsigned, unsigned>, T>
    (où T est le type des éléments de la matrice)
    C'est pas forcément le plus clean... mais en tous cas, c'est la version qui me parait la plus tranquile d'utilisation
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  4. #4
    Membre éclairé Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Par défaut
    Swöög: je ne sais pas si c'est très performant d'utiliser des map ?

    Miles: c'est vrai que je pourrais développer une telle classe... je vais essayer!

  5. #5
    Expert confirmé
    Avatar de Swoög
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    6 045
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 6 045
    Par défaut
    Citation Envoyé par Rodrigue
    Swoög: je ne sais pas si c'est très performant d'utiliser des map ?
    bah, ça fait de la STL quand même...

    et puis l'avantage, c'est que seuls les cases utilisées de la matrices sont allouées
    Rédacteur "éclectique" (XML, Cours PHP, Cours JavaScript, IRC, Web...)
    Les Règles du Forum - Mon Site Web sur DVP.com (Développement Web, PHP, (X)HTML/CSS, SQL, XML, IRC)
    je ne répondrai à aucune question technique via MP, MSN ou Skype : les Forums sont là pour ça !!! Merci de me demander avant de m'ajouter à vos contacts sinon je bloque !
    pensez à la balise [ code ] (bouton #) et au tag :resolu: (en bas)

  6. #6
    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 Swoög
    Salut !

    perso, pour les matrices, j'utilise généralement des map< pair<unsigned, unsigned>, T>
    (où T est le type des éléments de la matrice)
    C'est pas forcément le plus clean... mais en tous cas, c'est la version qui me parait la plus tranquile d'utilisation
    C'est bien, mais pour des matrices creuses

  7. #7
    Membre éclairé Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Par défaut
    Bonjour,

    C'est fait! Une classe template Matrix basée sur une autre classe template Row. J'ai surchargé les opérateurs [] pour ces deux classes.
    Je sais créer une matrice comme ceci:
    et accéder aux éléments très facilement:
    Cordialement,
    Rodrigue

  8. #8
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    J'ai surchargé les opérateurs [] pour ces deux classes.
    Déconseillé.

    http://www.parashift.com/c++-faq-lit...html#faq-13.11

  9. #9
    Membre éclairé Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Par défaut
    Je ne suis pas totalement convaincu
    Car dans le type d'implémentation (,), à chaque accès à un élément on a une multiplication ... Tandis que dans le type d'implémentation [][], on renvoie un pointeur sur la ligne et ensuite on lit la case dans cette ligne...

    Alors je comprends que si on doit lire la matrice en fonction des colonnes, on obtienne des performances médiocres (à chaque fois, il faut renvoyer le pointeur sur la ligne suivante). Je pense que c'est au programmeur à le savoir et à s'arranger pour que son algorithme lise ligne par ligne la matrice ... de cette manière, on renvoie un pointeur sur la ligne et on la parcoure etc.
    OU implémenter sa matrice en fonction des colonnes (si son algo est prévu pour...).

    Le mieux (et je vais y réfléchir) serait d'avoir une classe de matrice qui permettrait d'obtenir des pointeurs sur les lignes et sur les colonnes ... A mon avis, cela demanderait une duplication des données ... ou alors faire une sorte de tableau de colonne dont les éléments sont des pointeurs sur les cases des lignes (on calcule les multiplications une seule fois)... ça ferait deux pointeurs par éléments.

    Hum

    Cordialement,
    Rodrigue

  10. #10
    Membre émérite

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2005
    Messages
    634
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Suisse

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2005
    Messages : 634
    Par défaut
    La même remarque en français dans notre FAQ

    http://c.developpez.com/faq/cpp/?pag...E_matrix_array

    Avec un exemple à la question/réponse juste au-dessus.

  11. #11
    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 loufoque
    C'est normal, mais si pour lui, le goulot d'étranglement n'est pas là, on s'en fout.

  12. #12
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Car dans le type d'implémentation (,), à chaque accès à un élément on a une multiplication ... Tandis que dans le type d'implémentation [][], on renvoie un pointeur sur la ligne et ensuite on lit la case dans cette ligne...
    Mauvaise déduction.
    p[n*i+j] est plus rapide que p[i][j] car
    - les processeurs (type Intel) ont des instructions spéciales pour coder p[n*i+j]
    - p[i][j] fait 2 accès mémoire (operation lente), alors que p[n*i+j] n'en fait qu'un seul
    - faire un vecteur de vecteurs est très constraignant pour l'allocation et la désallocation

    Si maintenant tu veux encore oprimiser l'accès sur une ligne il faut précalculer le décalage, et faire quelque chose du genre
    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
     
    class MatrixRow
    {
      ...
      MatrixRow(Matrix &X, int i) : p(&X(i,0)) {}
     
      value_type       &operator[](int i)       { return p[i]; }
      const value_type &operator[](int i) const { return p[i]; }
    };
     
    class Matrix
    {
      ...
     
      MatrixRow row(int i) { return MatrixRow(*this,i); }
     
      value_type       &operator()(int i,int j)       { return p[n*i+j]; }
      const value_type &operator()(int i,int j) const { return p[n*i+j]; }
    };

  13. #13
    Membre éclairé Avatar de Rodrigue
    Inscrit en
    Août 2002
    Messages
    487
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 487
    Par défaut
    Ok, ok, je me rends ... !
    Mauvaise déduction.
    p[n*i+j] est plus rapide que p[i][j] car
    - les processeurs (type Intel) ont des instructions spéciales pour coder p[n*i+j]
    - p[i][j] fait 2 accès mémoire (operation lente), alors que p[n*i+j] n'en fait qu'un seul
    - faire un vecteur de vecteurs est très constraignant pour l'allocation et la désallocation
    J'ai appris quelque chose ... Merci!

    Donc en résumé, il vaut mieux que je prenne pour mes matrices l'implémentation qui est donnée dans la FAQ: http://c.developpez.com/faq/cpp/?pag...E_matrix_index

    L'implémentation est 2x plus facile que ma classe actuelle (ça me dégoûte ...)

    Merci à tous pour vos réponses très instructives!

  14. #14
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Encore une précision.
    Un vecteur de pointeurs peut quand-même être une solution intéressante dans le cas (peu probable) où ton programme échangerait très souvent la place des lignes. Une fonction membre swap n'aurait alors qu'à permuter les pointeurs.
    Et alors l'encapsulation rend tout le mécanisme interne transparent pour l'utilisateur.

  15. #15
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    permuter des pointeurs ou permuter des doubles c'est kif-kif.
    Et utiliser des pointeurs aménerait tout un tas d'autres problèmes. (en plus le vector alloue intelligemment tout en même temps, si tu passes par des new ça va être plus lent)

  16. #16
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    237
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 237
    Par défaut
    Utiliser des pointeurs prend de la place ! Une adresse prend 8 octets de mémoire

  17. #17
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Il suffirait de permuter 2 pointeurs pour permuter toute une ligne.
    Donc c'est pas kif-kif.
    J'ai bien dit que cette technique ne serait rentable que rarement.
    Et j'ai bien conseillé dans le cas général de ne pas utiliser cette structure de données.

    Je crois plutôt que sur une machine 32 bits:
    -sizeof(void*)=4
    -sizeof(double)=8

  18. #18
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Avril 2006
    Messages
    237
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2006
    Messages : 237
    Par défaut
    Je crois plutôt que sur une machine 32 bits:
    -sizeof(void*)=4
    -sizeof(double)=8
    Cela dépend de la machine, du systéme d'exploitation...

    La norme ne préconise aucune valeur fixe

  19. #19
    Inactif  
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    743
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 743
    Par défaut
    Cela dépend de la machine, du systéme d'exploitation...
    C'est bien pour ça que j'ai précisé sur une machine 32 bits.
    De toute façon là n'est pas le problème car:
    -1 pointeur = 1 registre
    -échanger 2 pointeurs sera toujours plus rapides que de permuter le contenu de 2 vecteurs
    -le volume mémoire occupés par les pointeurs sera négligeable comparé aux données, car il n'y aurait qu'un seul pointeur par ligne de la matrice
    -et pourquoi se contenter de doubles? ça pourrait être une matrice de grosses structures

  20. #20
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    -échanger 2 pointeurs sera toujours plus rapides que de permuter le contenu de 2 vecteurs
    std::vector::swap ne fait que permuter les pointeurs, il ne s'amuse pas à copier les données. Bon il y a également permutation des tailles, mais on peut considérer ça comme négligeable...

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Les matrices
    Par countag dans le forum Algorithmes et structures de données
    Réponses: 16
    Dernier message: 12/05/2006, 23h25
  2. Les matrices
    Par countag dans le forum C++
    Réponses: 6
    Dernier message: 12/05/2006, 20h41
  3. Les matrices
    Par Mathieu008_67 dans le forum DirectX
    Réponses: 17
    Dernier message: 24/10/2005, 14h02
  4. Comprendre les matrices 3D
    Par tavman dans le forum Algorithmes et structures de données
    Réponses: 5
    Dernier message: 11/09/2005, 13h18
  5. Opérations sur les matrices...
    Par aokiseiichiro dans le forum C
    Réponses: 32
    Dernier message: 28/07/2005, 17h10

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