Bibm@th

Forum de mathématiques - Bibm@th.net

Bienvenue dans les forums du site BibM@th, des forums où on dit Bonjour (Bonsoir), Merci, S'il vous plaît...

Vous n'êtes pas identifié(e).

#1 15-03-2014 10:56:03

mar31
Membre
Inscription : 15-03-2014
Messages : 3

[C++] Calcul de valeurs propres

Bonjour,

J'ai besoin de calculer toutes les valeurs propres d'une matrice. Pour cela, j'ai besoin de deux algorithmes que j'ai écrits : la méthode de la puissance qui calcule une valeur propre et la méthode de la déflation qui calcule une autre valeur propre à partir d'une valeur propre et d'un vecteur propre déjà trouvés.

//Fonction calculant la valeur propre et le vecteur propre d'une matrice pour un vecteur de départ et une précision dpnnée. Retourne la valeur propre.
double MatriceCarree::methodePuissances(double* vCour,double epsilon)
{

  double * vSuiv = new double[n];
  vSuiv = MatriceCarree::initVecteur(vSuiv,n);
  double * vPrime = new double[n];
  int nbIteration = 0;
  double lambda = 0;
  double signe = 1;
  int i = 0;

    if (n<2)
    {
    vCour[1]=1;
    lambda=getMat(0,0);
    }
    else
    {
         do {

      if (nbIteration!=0)
      {
        // Echange de valeurs
        for (int j=0;j<n;j++)
          {vCour[j]=vSuiv[j];}
      }

      //(a)Calcul de v' = A*v(k)
      vPrime = multiplicationMatVect(n,vCour);

      //(b)Vérification que ||v'|| != 0
      if (normeMax(vPrime)==0)
        return 0;
      else
      {
        //(c.1)Recherche d'un i tel que vi != 0
        while (vCour[i]==0 && i<n)
        {i++;}

        //Signe de v'/v
        if (vPrime[i]!=0)
           signe = (vPrime[i]/vCour[i])/abs((vPrime[i]/vCour[i]));

        //(c.2)Calcul de lambda
        lambda = normeMax(vPrime) * signe;

        //(d)v = v' / ||v'||
        for (int l=0;l<n;l++)
        {
          vSuiv[l] = vPrime[l] / lambda;
        }

        nbIteration++;signe=0;
      }


    }while (normeMax(MatriceCarree::soustractionVect(n,vSuiv,vCour))>epsilon && nbIteration<100);//Condition d'arrêt
  }
    cout<<"\nValeur propre : "<<lambda<<"\n"<<endl;

  return lambda;
}

//Fonction calculant la valeur propre et le vecteur propre d'une matrice à partir d'un vecteur v et d'une valeur lambda. Retourne la nouvelle valeur propre.
double MatriceCarree::methodeDeflation(double* v,double lambda)
{
       if (n<2)
       {
            v[0]=1;
            return getMat(0,0);
       }
       else
       {

           MatriceCarree* b = new MatriceCarree(n);
           double mu=0;
           double* vectPropreA = new double[n];
           double* vCour = new double[n];
           double tmp=0;
           //init de vCour
           vCour=MatriceCarree::initVecteur(vCour,n);
           vCour[0]=1;
           int i=0;

           //recherche d'un i tq v(i) non nul
           while (i<n && v[i]==0)
           {i++;}

            //calcul de b
            for (int k=0;k<p;k++)
            {
                for(int l=0;l<n;l++)
                {
                    b->setMat(k,l,(getMat(k,l) - getMat(i,l)*v[k]*(1/v[i])));
                }
            }

            //Calcul du vecteur propre et de la valeur propre de b
            mu = b->methodePuissances(vCour,EPS);

          //Calcul du vecteur propre de A
          for (int k=0;k<n;k++)
            {
                tmp += getMat(i,k)*vCour[k];
            }

            for (int k=0;k<n;k++)
            {
                vectPropreA[k] = (mu - lambda)*vCour[k]+(1/v[i])*tmp*v[k];
            }

            for(int j=0;j<n;j++)
            {
                v[j]=vectPropreA[j];
            }
            return mu;
    }

Dans le main cela donne ça :
       

int main()
{
        double lambda;
        double t[9] = {5,-6,1,-9,-8,-2,2,-4,4};
        MatriceCarree * m = new MatriceCarree(3,t);
        m->afficher();
        int n=m->getDimension();
        double * v = new double[n]; MatriceCarree::initVecteur(v,n); v[0]=1; //Crée un vecteur de dimension n initialisé à 0 (sauf v[0])
        lambda = m->methodePuissances(v,10^(-6));
        for(int i=0;i<n-1;i++)
            lambda= m->methodeDeflation(v,lambda);
        system("PAUSE");
        return 0;
}

Les 2 premières valeurs propres sont bonnes mais ensuite le programme me trouve des valeurs propres identiques (ou presque) alternativement. Le résultat sera de la forme : {val1, val2, val1, val2...}.
Je n'arrive vraiment pas à régler ce problème donc si quelqu'un aurait la gentillesse de m'aiguiller ?

Merci

Dernière modification par yoshi (15-03-2014 11:06:25)

Hors ligne

#2 15-03-2014 22:16:26

Fred
Administrateur
Inscription : 26-09-2005
Messages : 7 035

Re : [C++] Calcul de valeurs propres

Bonjour,

  Je pense avoir compris le problème.
La première application de la méthode de la puissance te donne la première valeur propre [tex]\lambda_1[/tex] et le premier vecteur propre [tex]v_1[/tex].
Tu appliques ensuite la méthode de la déflation à [tex]A,\ \lambda_1,\ v_1[/tex] et tu obtiens une matrice [tex]B[/tex] à laquelle tu appliques la méthode de la puissance pour trouver [tex]\lambda_2,\ v_2[/tex].
Normalement, tu devrais encore appliquer la méthode de la déflation à [tex]B,\ \lambda_2,\ v_2[/tex], pour obtenir [tex]\lambda_3[/tex]. Mais  toi, je crois que tu repars de [tex]A[/tex], c'est-à-dire que tu appliques la méthode de la déflation à [tex]A,\ \lambda_2,\ v_2[/tex]. Mais ainsi, tu n'as pas "tué" la plus grande valeur propre, et c'est normal que tu retombes sur [tex]\lambda_1[/tex].

F.

Hors ligne

#3 16-03-2014 09:27:05

mar31
Membre
Inscription : 15-03-2014
Messages : 3

Re : [C++] Calcul de valeurs propres

Ah c'est exact je pense que le problème vient de là merci je vais tester ça !

edit : j'ai un autre problème : je ne sais pas si c'est normal mais la première ligne de B (souvent correspondant au i tq v(i) non nul) est toujours nulle, ce qui fait que les matrices b que je calcule sont toujours les mêmes (il ne reste plus que getMat(k,l)).

Dernière modification par mar31 (16-03-2014 10:08:15)

Hors ligne

#4 16-03-2014 21:36:00

Fred
Administrateur
Inscription : 26-09-2005
Messages : 7 035

Re : [C++] Calcul de valeurs propres

Je ne vois pas de raison pour que la première ligne de B soit toujours nulle.
C'est quoi ton p ligne 91???
La matrice est censée être carrée je crois....

Hors ligne

#5 07-04-2014 13:53:10

minimoack
Invité

Re : [C++] Calcul de valeurs propres

Bonjour,

J'ai le même exercice à faire. Pourrais-tu me dire à quoi correspond ta méthode initVecteur exactement?

Merci :)

Réponse rapide

Veuillez composer votre message et l'envoyer
Nom (obligatoire)

E-mail (obligatoire)

Message (obligatoire)

Programme anti-spam : Afin de lutter contre le spam, nous vous demandons de bien vouloir répondre à la question suivante. Après inscription sur le site, vous n'aurez plus à répondre à ces questions.

Quel est le résultat de l'opération suivante (donner le résultat en chiffres)?
cinquante et un moins trente neuf
Système anti-bot

Faites glisser le curseur de gauche à droite pour activer le bouton de confirmation.

Attention : Vous devez activer Javascript dans votre navigateur pour utiliser le système anti-bot.

Pied de page des forums