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

C++ Discussion :

Probleme Inversion matrice avec Eigen


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 51
    Points : 34
    Points
    34
    Par défaut Probleme Inversion matrice avec Eigen
    Bonjour,

    J'utilise la bibliotheque Eigen pour faire un calcul matriciel.
    Je mets a jour Un certain nombre de matrices de maniere iterative. Probelem, au bout de la second boucle, la matrice ne s'inverse plus et j'obtiens des NAN partout. J'ai implementer le meme calcul sous matlab, pourtant la matrice s'inverse.

    Un aperçu de mon code (en gros ce qui se passe):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    for(int i=0; i<50; i++) //iterations
    {
    //mise a jour de toutes les autres matrices
    .....
    //equations normales
    Eigen::MatrixXd S(24,12);
    S=(Qll*G.transpose())*(G*Qll*G.transpose()).inverse(); //endroit de l'inversion
    }
    Toutes les autres matrices se mettent correctement a jour, sauf l'inversion de S...

    Merci d'avance pour votre aide

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    533
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2008
    Messages : 533
    Points : 1 086
    Points
    1 086
    Par défaut
    Question bête, est-ce que l'expression (Qll*G.transpose())*(G*Qll*G.transpose()) produit une matrice inversible ?

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 51
    Points : 34
    Points
    34
    Par défaut probleme inversion de matrices eigen c++
    bonjour,

    merci de votre réponse.
    le produit que vous venez de citer produit une matrice, mais qu'on ne peut pas inverser car la matrice n'est pas carrée.

    J'ai un peu changé depuis :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
                  Eigen::MatrixXd s1(24,12); s1.setZero();//matrice temporaire
                  s1=Qll*G.transpose();
                  Eigen::MatrixXd s2(12,12); s2.setZero();//matrice temporaire
                  s2=G*s1;
     
                  Eigen::MatrixXd id(12,12); id.setIdentity();
     
                  Eigen::MatrixXd s3(12,12); s3.setZero();
                  Eigen::HouseholderQR<Eigen::MatrixXd> qr(s2);
                  s3=qr.solve(id); //s3=s2^-1 * id
     
                  Eigen::MatrixXd S(24,12); S.setZero();
                  S=s1*s3;
    mais toujours le même problème, la matrice s'inverse pour la première itération mais au bout de la second itération, j'obtiens que des NaN dans la matrice S. Pourtant sous Matlab la matrice s'inverse bien au bout de 2, 3, ...n itérations.

    Merci de votre aide

  4. #4
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Hello,

    Place des points d'arrêts et lance le debug, tu sauras exactement à quel moment la matrice obtient des mauvaises valeurs. Ça peut aider à comprendre le problème. Par exemple, es-tu sur que les matrices s1, s2 et s3 sont correctes ?

    Ce n'est pas un problème de durée de vie des variables sinon ?

    edit : Ya pas une division par zéro quelques part ?

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Janvier 2013
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Janvier 2013
    Messages : 51
    Points : 34
    Points
    34
    Par défaut probleme inversion de matrices eigen c++
    bonjour,

    merci encore pour votre reponse.
    Je regarde un peu plus pres ce qui se passe.
    lors du second passage de la boucle, je trouve que des 0 dans la matrice du coup effectivement la matrice S qui suit ne s'inverse pas. Toutefois ce n'est pas normal qu'il trouve que des 0 ! lors de la premiere boucle, il trouve bien les bonnes valeurs ... c'est bizarre.
    Concernant votre seconde remarque, c'est possible que le probleme viennent de cela. je ne suis pas expert en gestion de variables mais voici comment je procede :

    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
    //declaration des variables qui vont se mettre a jour
               float tx=0;
               for (int m=0; m<20; m++) //iterations pour la convergence
              {
                  .//la nouvelle valeur de tx sert a calculer s1, s2, s3, S
                  .
                  . 
                  //calcul matriciel
                  Eigen::MatrixXd s1(24,12); s1.setZero();//matrice temporaire
                  s1=Qll*G.transpose();
                  Eigen::MatrixXd s2(12,12); s2.setZero();//matrice temporaire
                  s2=G*s1;
     
                  Eigen::MatrixXd id(12,12); id.setIdentity();
     
                  Eigen::MatrixXd s3(12,12); s3.setZero();
                  Eigen::HouseholderQR<Eigen::MatrixXd> qr(s2);
                  s3=qr.solve(id); //s3=s2^-1 * id
     
                  Eigen::MatrixXd S(24,12); S.setZero();
                  S=s1*s3;
                  .
                  .
                  .
                  //mise a jour de la valeur tx;
                  -----> tx prend une nouvelle valeur
               }
    je ne sais pas si c'est la bonne méthode pour faire.
    tx est modifiée dans la boucle for, mais déclarée a l’extérieure de la boucle.
    toutes les matrices de calcules sont déclarées dans la boucle for, mais changent, car la valeur de tx change aussi...

    merci encore pour votre aide.

  6. #6
    Expert confirmé
    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
    Points : 4 442
    Points
    4 442
    Par défaut
    Pas de problèmes de durée de vie a priori.

    s1 prend des mauvaises valeurs, il faut donc vérifier Qll et G.transpose(), et ainsi de suite jusqu’à trouver l'origine du problème.

    Si tu ne mets pas à jour tx dans ta boucle (tu calcules donc 20 fois la même chose), est-ce que le problème disparaît ?

    Si oui, c'est que tx prend une mauvaise valeur ou est mal traité (erreur d'unité par exemple).

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 31
    Points : 16
    Points
    16
    Par défaut
    Ce que tu veux c'est calculer une pseudo inverse, il y a plusieurs méthodes, dont SVD , avec Eigen tu peux ecrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    A= B.jacobiSvd(ComputeThinU | ComputeThinV).solve( MatrixXd::Identity(B.rows(),B.rows()) );
    A est alors la pseudo inverse de B au sens des moindre carrés.

  8. #8
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 612
    Points : 30 612
    Points
    30 612
    Par défaut
    Citation Envoyé par med.doc Voir le message
    bonjour,

    merci encore pour votre reponse.
    Je regarde un peu plus pres ce qui se passe.
    lors du second passage de la boucle, je trouve que des 0 dans la matrice du coup effectivement la matrice S qui suit ne s'inverse pas. Toutefois ce n'est pas normal qu'il trouve que des 0 ! lors de la premiere boucle, il trouve bien les bonnes valeurs ... c'est bizarre.
    Concernant votre seconde remarque, c'est possible que le probleme viennent de cela. je ne suis pas expert en gestion de variables mais voici comment je procede :

    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
    //declaration des variables qui vont se mettre a jour
               float tx=0;
               for (int m=0; m<20; m++) //iterations pour la convergence
              {
                  .//la nouvelle valeur de tx sert a calculer s1, s2, s3, S
                  .
                  . 
                  //calcul matriciel
                  Eigen::MatrixXd s1(24,12); s1.setZero();//matrice temporaire
                  s1=Qll*G.transpose();
                  Eigen::MatrixXd s2(12,12); s2.setZero();//matrice temporaire
                  s2=G*s1;
     
                  Eigen::MatrixXd id(12,12); id.setIdentity();
     
                  Eigen::MatrixXd s3(12,12); s3.setZero();
                  Eigen::HouseholderQR<Eigen::MatrixXd> qr(s2);
                  s3=qr.solve(id); //s3=s2^-1 * id
     
                  Eigen::MatrixXd S(24,12); S.setZero();
                  S=s1*s3;
                  .
                  .
                  .
                  //mise a jour de la valeur tx;
                  -----> tx prend une nouvelle valeur
               }
    je ne sais pas si c'est la bonne méthode pour faire.
    tx est modifiée dans la boucle for, mais déclarée a l’extérieure de la boucle.
    toutes les matrices de calcules sont déclarées dans la boucle for, mais changent, car la valeur de tx change aussi...

    merci encore pour votre aide.
    Attention à la durée de vie de tes objets...

    Lorsque tu crées des objets dans une boucle, comme s1, s2, id ou surtout qr, ils sont créés au moment de leur déclaration et détruits quand tu atteints l'accolade fermante "}" qui correspond à la fin de la boucle, et ce, à chaque itération.

    Déjà, cela signifie que, tu vas créer et détruire 20 fois tous ces objets, ce qui n'est très clairement pas le plus efficace en terme de performances (la création et la destruction d'objets prend du temps, surtout s'il s'agit de matrices), mais, en plus, cela signifie que, par défaut, il faut remplir ces matrices à chaque fois dans la boucle si tu veux qu'elles contiennent des valeurs.

    Es tu sur que c'est ce qui est fait par le code que tu as supprimé de cette boucle

    Si ce n'est pas le cas, il y a très certainement intérêt à sortir certains de ces objets (ceux pour lesquels le contenu doit rester d'une itération à l'autre) de ta boucle
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Réponses: 4
    Dernier message: 22/11/2011, 12h35
  2. Inverse de matrice avec paramètre
    Par feynman dans le forum Fortran
    Réponses: 13
    Dernier message: 26/10/2007, 16h51
  3. Calculer un inverse de matrice avec boost?
    Par Clad3 dans le forum Bibliothèques
    Réponses: 6
    Dernier message: 02/06/2005, 18h38
  4. Réponses: 12
    Dernier message: 23/10/2002, 11h56
  5. Probleme d'impression avec la méthode TForm->Print()
    Par Kid Icarus dans le forum C++Builder
    Réponses: 13
    Dernier message: 31/07/2002, 14h26

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