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 :

Boost.uBlas et sous-vecteur de matrice


Sujet :

Boost C++

  1. #1
    Membre confirmé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 186
    Points : 604
    Points
    604
    Par défaut Boost.uBlas et sous-vecteur de matrice
    Bonjour à tous !

    Je cherche à accéder à un sous-vecteur d'une matrice en utilisant uBlas de Boost et je ne m'en sors pas avec les matrix_vector_range. Pour montrer mon problème, prenons un exemple simple :

    Soit la matrice suivante :

    | 0 1 2 |
    | 3 4 5 | = M
    | 6 7 8 |

    Je cherche à obtenir le sous-vecteur de la deuxième colonne, de la ligne 2 à la ligne 3, c'est-à-dire :

    v = (4 ; 7)

    Il me semble que ce qui est approprié pour ce faire est la structure matrix_vector_range. J'ai donc fait le code suivant :

    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
     
    #include <boost/numeric/ublas/matrix.hpp>
    #include <boost/numeric/ublas/matrix_proxy.hpp>
    #include <boost/numeric/ublas/io.hpp>
     
    int main (int argc, char **argv) {
      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;
     
      matrix_vector_range<matrix<double> > v (M, range (1, 3), range (1, 1));
      std::cout << v << std::endl;
     
      return 0;
    }  // main
    Tout compile sans problème. Par contre, j'obtiens le résultat suivant à l'exécution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Assertion failed in file /usr/include/boost/numeric/ublas/matrix_proxy.hpp at line 970:
    size1 == size2
    Donc, visiblement, je m'emmêle les pinceaux dans l'utilisation de range. Le seul truc, c'est que je n'arrive pas à comprendre comment je devrais m'y prendre normalement. Est-ce que quelqu'un à une idée ?

    À bientôt.

    Le Farfadet Spatial

  2. #2
    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 : 50
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Telles que je comprends les choses, range (1, 1) est un range vide...

  3. #3
    Membre confirmé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 186
    Points : 604
    Points
    604
    Par défaut
    Salut à tous !

    En effet, range (1, 1) est un range vide. Cependant, en fait, ce n'est pas le code que j'avais tapé, toutes mes excuses. Voici donc le code corrigé :

    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
     
    #include <boost/numeric/ublas/matrix.hpp>
    #include <boost/numeric/ublas/matrix_proxy.hpp>
    #include <boost/numeric/ublas/io.hpp>
     
    int main (int argc, char **argv) {
      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;
     
      matrix_vector_range<matrix<double> > v (M, range (1, 3), range (1, 2));
      std::cout << v << std::endl;
     
      return 0;
    }  // main
    Enfin, « corrigé » est un bien grand mot, vu qu'il produit la trace d'exécution donnée dans mon premier message.

    À bientôt.

    Le Farfadet Spatial

  4. #4
    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 : 50
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Après quelques tests, il semblerait que le vecteur qu'il essaye d'extraire est le vecteur diagonal de la sous matrice définie, qui doit donc du coup être carrée, ce qui n'est pas ton cas.

    Pour ce que tu veux, je partirais plus vers soit un matrix_range de dimention 1*n, soit un vector_range issu d'un matrix_row.

  5. #5
    Membre confirmé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 186
    Points : 604
    Points
    604
    Par défaut
    Salut à tous !

    Oups ! Toutes mes excuses pour n'avoir pas posté dans la bonne section.

    Citation Envoyé par JolyLoic Voir le message
    Pour ce que tu veux, je partirais plus vers soit un matrix_range de dimention 1*n, soit un vector_range issu d'un matrix_row.
    Très bien, mauvais choix de ma part. Au niveau performances, que me conseillerais-tu entre un matrix_range et un vector_range issu d'un matrix_row ?

    À bientôt.

    Le Farfadet Spatial

  6. #6
    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 : 50
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Aucune idée, je n'ai pas une expérience pratique de cette bibliothèque...

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    410
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 410
    Points : 361
    Points
    361
    Par défaut
    je pense que pour ce genre d'opérations à la fortran style, la libraire Blitz serait la plus adaptée. Perso en ce qui concerne le calcul numérique je n'ai pas l'impression que boost soit une solution intéressante (malheureusement)...

  8. #8
    Membre confirmé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 186
    Points : 604
    Points
    604
    Par défaut
    Salut à tous !

    Citation Envoyé par reptils Voir le message
    Perso en ce qui concerne le calcul numérique je n'ai pas l'impression que boost soit une solution intéressante (malheureusement)...
    Ah ? Je suis intéressé, sur quoi te bases-tu pour dire ça ? Des tests de performances ? Après tout, uBlas est fortement inspirée de Blitz.

    À bientôt.

    Le Farfadet Spatial

  9. #9
    Membre confirmé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 186
    Points : 604
    Points
    604
    Par défaut
    Salut à tous !

    En attendant, dans la mesure où ensuite j'ai besoin d'un vector_expression, j'ai opté pour un vector_range issu d'un matrix_column. Voici le code qui fait ce que je veux :

    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
     
    #include <boost/numeric/ublas/matrix.hpp>
    #include <boost/numeric/ublas/matrix_proxy.hpp>
    #include <boost/numeric/ublas/io.hpp>
    #include <boost/numeric/ublas/vector.hpp>
    #include <boost/numeric/ublas/vector_proxy.hpp>
     
    int main (int argc, char **argv) {
      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;
      vector<double> M1 = matrix_column< matrix<double> > (M, 1);
      vector_range< vector<double> > v (M1, range (1, 3));
      std::cout << v << std::endl;
     
      return 0;
    }  // main
    Problème résolu, même si je suis toujours preneur des explications de Reptils.

    À bientôt.

    Le Farfadet Spatial

  10. #10
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Hello,

    Le vector_range d'un matrix_column ou un matrix_range auront à peu près les mêmes perfs. Il ne s'agit que de proxy dont toutes les méthodes sont inline, donc à priori une fois ton code compilé, c'est comme si tu avais codé un accès direct aux éléments.

    En ce qui concerne les perfs de Boost par rapport aux librairies Fortran, les différences ne sont pas énormes et dépendent pas mal de la taille des objets manipulés.

    Pour avoir implémenter un système de calcul qui ressemble à uBlas (donc basé sur les expressions template) et comparer les perfs à CLAPACK + Blas, globalement certaines fonctions sont plus rapides dans la version C++ (là je pense qu'il s'agit surtout de choix d'algo), d'autres équivalentes, d'autres plus lentes, on ne peut pas conclure que c'est globalement plus lent.

    Pour les fonctions de base, il y a effectivement une pénalité en C++, mais cette pénalité devient vite négligeable avec l'augmentation de la taille des vecteurs / matrices utilisés.

    La doc de uBlas fournit un Benchmark par rapport à une implémentation C, de mémoire les différences de perfs sont sensiblement identiques à celles entre une librairie Fortran et uBlas. Après à voir si le code est suffisamment critique pour nécessiter l'utilisation de librairies Fortran ou pas.

  11. #11
    Membre confirmé
    Avatar de Le Farfadet Spatial
    Homme Profil pro
    En cours de précision…
    Inscrit en
    Avril 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : En cours de précision…

    Informations forums :
    Inscription : Avril 2008
    Messages : 186
    Points : 604
    Points
    604
    Par défaut
    Salut à tous !

    Merci Bolhrak pour ces précisions. Cela dit... Je suis déjà au fait de ces choses. Ma question ne porte pas sur les préférences entre Fortran, C et C++ --- depuis le temps, il vaut mieux pour moi d'avoir quelques idées là-dessus.

    C'est beaucoup plus simple : pourquoi Reptils considère-t-il que Blitz++ --- qui est une bibliothèque C++ basée sur les modèles d'expressions, en fait c'est plus ou moins par elle que les modèles d'expressions ont été découverts --- est plus appropriée que uBlas pour ce genre de manipulations. Parce que c'est plus simple ? Parce qu'elle est plus performantes dans ces cas-là ?

    Si c'est pour une raison de commodité, l'extrême portabilité de Boost et la forte réactivité de sa communauté me fera quand même préférer uBlas, parce que parfois les calculateurs utilisés sont un peu exotique. Si c'est pour une raison de performances, cela vaut la peine de réfléchir un peu plus à utiliser Blitz++.

    Cela dit, j'apprécie sincèrement que tu aies essayé de m'apporter de l'aide, donc encore merci.

    À bientôt.

    Le Farfadet Spatial

  12. #12
    Membre averti
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Points : 444
    Points
    444
    Par défaut
    Erf j'ai lu trop vite, en fait j'ai lu que Reptils mentionnait blas, donc j'ai pensé à la lib fortran

    Désolé pour le HS

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/10/2011, 08h59
  2. Réponses: 8
    Dernier message: 18/05/2007, 17h33
  3. [BOOST] utilisation de boost uBLAS non compile avec visual c++
    Par le_voisin dans le forum Autres éditeurs
    Réponses: 5
    Dernier message: 06/09/2006, 22h03
  4. Boost et Jamfile sous Eclipse
    Par afec++ dans le forum Bibliothèques
    Réponses: 2
    Dernier message: 04/07/2006, 14h25
  5. probleme boost::ublas
    Par p_moiret dans le forum Bibliothèques
    Réponses: 4
    Dernier message: 19/12/2005, 16h10

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