Forum de mathématiques - Bibm@th.net
Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#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.
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 :
{
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
#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 :)
Pages : 1