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

Modules Perl Discussion :

Math::MatrixDecomposition::Eigen : argument invalide


Sujet :

Modules Perl

  1. #1
    Nouveau membre du Club
    Math::MatrixDecomposition::Eigen : argument invalide
    Bonjour à tous,

    j'essaye d'utiliser ce module mais il me renvoie tout le temps "Invalid argument".

    La doc (assez peu bavarde) : http://search.cpan.org/~ralph/Math-M...ition/Eigen.pm

    Voici un script avec 3 méthodes qui sont toutes un échec :
    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
    use strict;
    use Math::Matrix;
    use Math::MatrixDecomposition::Eigen;
     
    my $eigen;
    my $A11 = 2.;
    my $A12 = 1.;
    my $A13 = 5.;
    my $A22 = 1.;
    my $A23 = 7.;
    my $A33 = -1.;
    #matrice carree symetrique
    my @A = ([$A11,$A12,$A13],
             [$A12,$A22,$A23],
             [$A13,$A23,$A33]);
     
    #essai 1 : utilisation d une reference de @A
    $eigen = Math::MatrixDecomposition::Eigen->new(\@A);
     
    #essai 2 : test d une autre forme equivalente 
    #          d apres la doc de Math::MatrixDecomposition::Eigen
    $eigen = Math::MatrixDecomposition::Eigen->new;
    $eigen->decompose (\@A);
     
    #essai 3 : en passant par Math::Matrix
    my $ref_A = new Math::Matrix (@A);
    $eigen = Math::MatrixDecomposition::Eigen->new($ref_A);


    merci d'avance pour votre aide

  2. #2
    Rédacteur/Modérateur

    Bonjour,

    je ne connais pas ce module, mais essaie peut-être avec les modifications suivantes:

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    my $c = [ [$A11,$A12,$A13],
             [$A12,$A22,$A23],
             [$A13,$A23,$A33] ]; # créer directement un array ref
     
    $eigen = Math::MatrixDecomposition::Eigen->new($A = $c);


    Cela ressemblerait plus à la syntaxe recommandée dans la documentation du module.

    Il faut probablement prédéclarer $A.

    Essaie aussi d'ajouter:
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
     
    use warnings;

    Il se peut que ça te donne des informations complémentaires utiles.

  3. #3
    Nouveau membre du Club
    le test suivant ne marche pas non plus :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    my $C = [[$A11,$A12,$A13],
             [$A12,$A22,$A23],
             [$A13,$A23,$A33]];
     
    my $A;
    $eigen = Math::MatrixDecomposition::Eigen->new($A = $C);


    "use warnings" ne donne pas d'infos supplémentaires.

  4. #4
    Rédacteur/Modérateur

    Du coup, je ne sais pas, et, désolé, mais je n'ai pas le temps d'installer le module et de faire des tests pour l'instant.

  5. #5
    Nouveau membre du Club
    Citation Envoyé par Lolo78 Voir le message
    Du coup, je ne sais pas, et, désolé, mais je n'ai pas le temps d'installer le module et de faire des tests pour l'instant.
    no problemo. Bizarre que google soit aussi silencieux à propos de ce module. Il y a rien de rien, ni exemples ni sujets forum.

  6. #6
    Nouveau membre du Club
    j'ai pas eu le réflexe d'aller enquêter dans le fichier .pm du module. En fait, le module s'attend à des matrices sous forme de liste. Etrange mais pas un si mauvais choix de leur part (les performances de Perl se dégradent si on utilise des tableaux double indices. Encore pire avec des tableaux triple indices, etc...)

    Le code suivant ne renvoie pas d'erreur :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    use strict;
    use warnings;
    use Math::MatrixDecomposition::Eigen;
     
    my $eigen;
    my $A11 = 2.;
    my $A12 = 1.;
    my $A22 = 1.;
    #matrice carree symetrique 2x2
    my @A = ($A11,$A12,$A12,$A22);
     
    $eigen = Math::MatrixDecomposition::Eigen->new(\@A);

  7. #7
    Rédacteur/Modérateur

    Ah oui? Un peu surprenant tout de même. Surprenant surtout que ce ne soit apparemment pas documenté...

    Le problème est résolu, alors?

  8. #8
    Nouveau membre du Club
    oui, c'est résolu. ça marche et ça donne le bon résultat

    ci-joint un script de test si ça sert un jour à quelqu'un :
    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
    use strict;
    use warnings;
    use Math::MatrixDecomposition::Eigen;
     
    #doc du package : http://search.cpan.org/~ralph/Math-MatrixDecomposition-1.01/lib/Math/MatrixDecomposition/Eigen.pm
     
     
    #creation d une matrice carree symetrique 3x3
    my $A11 = 2.;
    my $A12 = 1.;
    my $A13 = 5.;
    my $A22 = 1.;
    my $A23 = 7.;
    my $A33 = -1.;
    my @A = ($A11,$A12,$A13,$A12,$A22,$A23,$A13,$A23,$A33);
    print "\n";
    print "matrice :\n";
    print "     | $A11  $A12  $A13 |\n";
    print " A = | $A12  $A22  $A23 |\n";
    print "     | $A13  $A23 $A33 |\n";
     
    #la methode "decompose" est l action par defaut de "new"
    my $eigen = Math::MatrixDecomposition::Eigen->new(\@A);
    #  => equivalent a :
    #    my $eigen = Math::MatrixDecomposition::Eigen->new;
    #    $eigen->decompose(\@A);
     
    my @lambda = $eigen->values;
    print "\nValeurs propres  :\n";
    for(my $i=0; $i<=2; $i++) {
      print "  > lambda_$i = $lambda[$i]\n";
    }
     
    my @vec = $eigen->vectors;
    print "\nVecteurs propres  :\n";
    for(my $i=0; $i<=2; $i++) {
      print "  > u_$i = @{$vec[$i]}\n";
    }
     
    my @A_mat = ([$A11,$A12,$A13],
                 [$A12,$A22,$A23],
                 [$A13,$A23,$A33]);
     
     
    my ($no_lambda, @A_u, @lambda_u);
     
    print "\nVerification (A*u = lambda*u  avec u = vecteur propre) :\n";
    for(my $no_lambda = 0; $no_lambda<=2; $no_lambda++) {
      print "  > valeur propre $no_lambda et vecteur propre $no_lambda :\n";
      for(my $i=0; $i<=2; $i++) {
        $A_u[$i] = 0.;
        for(my $j=0; $j<=2; $j++) {
          $A_u[$i] += $A_mat[$i][$j]*$vec[$no_lambda][$j];
        }
        $lambda_u[$i] = $vec[$no_lambda][$i]*$lambda[$no_lambda];
      }
      print "      A*u_$no_lambda        = @A_u\n";
      print "      lambda_$no_lambda*u_$no_lambda = @lambda_u\n";
    }
    print "\n";
     
     
    print "Verification (vecteurs propres orthogonaux => u_i.u_j = 0) :\n";
    my $prod_scal = 0.;
    for(my $i=0; $i<=2; $i++) {
      $prod_scal += $vec[0][$i]*$vec[1][$i];
    }
    print "  > produit scalaire u_0.u_1 = $prod_scal\n";
    $prod_scal = 0.;
    for(my $i=0; $i<=2; $i++) {
      $prod_scal += $vec[0][$i]*$vec[2][$i];
    }
    print "  > produit scalaire u_0.u_2 = $prod_scal\n";
    $prod_scal = 0.;
    for(my $i=0; $i<=2; $i++) {
      $prod_scal += $vec[1][$i]*$vec[2][$i];
    }
    print "  > produit scalaire u_1.u_2 = $prod_scal\n";
    print "\n";