Résolution équation troisième degré
Réponses à toutes vos questions après le Bac (Fac, Prépa, etc.)
-
sylvain231
- Membre Relatif
- Messages: 301
- Enregistré le: 07 Avr 2020, 13:20
-
par sylvain231 » 24 Juin 2023, 15:46
Bonjour je cherche à coder la résolution d'une équation du troisième degré en C++
mais ça ne marche pas sur ces exemples :
https://fr.wikiversity.org/wiki/%C3%89q ... degr%C3%A9voici mon code je l'ai relu et relu je pense que Wikipédia s'est trompé
- Code: Tout sélectionner
*
double racine_cubique(double d) {
if (d > 0)
return pow(d, 1.0 / 3);
else
return -pow(-d, 1.0 / 3);
}
//ax^3+bx^2+cx+d=0
//https://www.lucaswillems.com/fr/articles/58/equations-troisieme-degre
//https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Cardan
//https://proofwiki.org/wiki/Cardano's_Formula
vector<double> resoutEquationTroisiemeDegre(double a, double b, double c,double d) {
double p = (3 * a * c - pow(b, 2)) / (3 * pow(a, 2));
double q =(2*pow(b,3)-9*a*b*c+27*pow(a,2)*d)/(27*pow(a,3));
complex<double> Q ( ((3 * a * c) - pow(b, 2)) / (9 * pow(a, 2)),0);
complex<double> R ( (9 * a * b * c - 27 * pow(a, 2) * d - 2 * pow(b, 3)) / (54 * pow(a, 3)),0);
double tiers = 1.0 / 3.0;
complex<double> S = pow(R + sqrt(pow(Q, 3) + pow(R, 2)), tiers);
complex<double> T = pow(R - sqrt(pow(Q, 3) + pow(R, 2)), tiers);
cout << "p=" << p << " q=" << q << endl;
double Delta = -(4 * pow(p, 3) + 27 * pow(q, 2));
cout << "Delta=" << Delta << endl;
complex<double> j = complex<double>(-0.5, sqrt(3) / 2);
vector<double> res;
if (Delta < 0) {
double u = racine_cubique((-q + sqrt(-Delta / 27)) / 2);
double v = racine_cubique((-q - sqrt(-Delta / 27)) / 2);
cout << "u=" << u << " v=" << v << endl;
res.push_back(u + v);
}
else
if (Delta == 0) {
if (p == 0 && q == 0)
res.push_back(0);
else {
res.push_back(3 * q / p);
res.push_back(-3 * q / (2 * p));
}
}
else if (Delta > 0) {
/* for (int k = 0; k <= 2; k++) {
complex<double> u = pow(j, k) * pow(complex<double>(0.5, 0) * (complex<double>(-q, 0) +
sqrt(complex<double>(-Delta, 0) / complex<double>(27,0))), 1.0 / 3);
complex<double> v = pow(j,-k)*pow(complex<double>(0.5, 0) * (complex<double>(-q, 0) -
sqrt(complex<double>(-Delta, 0) / complex<double>(27, 0))), 1.0 / 3);
complex<double> z = u + v;
res.push_back(z.real());
cout << "z=" << z << endl;
}*/
complex<double> temp;
temp = S + T - (b / (3 * a));
res.push_back(temp.real());
temp = -(S + T)/complex<double>(2,0) - (b/(3*a))+complex<double>(0,sqrt(3)/2)*(S-T);
res.push_back(temp.real());
temp = -(S + T) / complex<double>(2, 0) - (b / (3 * a)) - complex<double>(0, sqrt(3) / 2)*(S - T);
res.push_back(temp.real());
}
// cout <<"res[0]"<< res[0] << endl;
//cout <<"Delta" << Delta << endl;
if (isnan(res[0]) || (res.size() > 0 && isnan(res[1])) || (res.size() > 1 && isnan(res[2])))
{
cout << "erreur nan" << endl;
exit(1);
}
return res;
}
-
sylvain231
- Membre Relatif
- Messages: 301
- Enregistré le: 07 Avr 2020, 13:20
-
par sylvain231 » 24 Juin 2023, 15:48
Léon si tu peux faire un code Maple pour tester les formules de Wikipédia avec les exemples de mon lien ce serait super !
NB : j'ai besoin du delta pour récupérer les bonnes solutions réelles car en C++ il peut y avoir des résidus dans les parties imaginaires et ça pose problème
si ça marche pour toi on pourra tracer étape par étape pour voir où ça coince
-
Ben314
- Le Ben
- Messages: 21575
- Enregistré le: 11 Nov 2009, 22:53
-
par Ben314 » 24 Juin 2023, 16:17
Vu ton code, il faudrait peut-être songer à commencer par se demander comment est implémentée une fonction du style pow( X , Y ) avec X qui est de type complexe et Y non entier vu que, mathématiquement parlant, ça a pas trop de sens...
Qui n'entend qu'un son n'entend qu'une sonnerie. Signé : Sonfucius
-
sylvain231
- Membre Relatif
- Messages: 301
- Enregistré le: 07 Avr 2020, 13:20
-
par sylvain231 » 24 Juin 2023, 17:05
normalement ça marche, peux-tu tracer le calcul des trois équations de ma page avec les formules de Wikipédia pour me dire si ça marche pour toi STP ?
-
sylvain231
- Membre Relatif
- Messages: 301
- Enregistré le: 07 Avr 2020, 13:20
-
par sylvain231 » 24 Juin 2023, 17:12
car moi ça ne marche même pas dans le cas delta <0 (une solution réelle) et pourtant tous les calculs sont sur des réels, je pense vraiment que leurs formules sont fausses
par exemple pour l'équation x^3+x^2+x+1=0
-
sylvain231
- Membre Relatif
- Messages: 301
- Enregistré le: 07 Avr 2020, 13:20
-
par sylvain231 » 24 Juin 2023, 17:44
j'ai réussi en pompant sur le site :
https://cplusplus.com/forum/beginner/234717/voici mon code :
- Code: Tout sélectionner
//https://cplusplus.com/forum/beginner/234717/
vector<double> resoutEquationTroisiemeDegre(double a, double b, double c,double d) {
if (a == 0)
{
cerr << "erreur a=0" << endl;
exit(1);
}
vector<double>res;
// Reduced equation: X^3 - 3pX - 2q = 0, where X = x-b/(3a)
double p = (b * b - 3.0 * a * c) / (9.0 * a * a);
double q = (9.0 * a * b * c - 27.0 * a * a * d - 2.0 * b * b * b) / (54.0 * a * a * a);
double offset = b / (3.0 * a);
// Discriminant
double discriminant = p * p * p - q * q;
if (discriminant > 0) // set X = 2 sqrt(p) cos(theta) and compare 4 cos^3(theta)-3 cos(theta) = cos(3 theta)
{
double theta = acos(q / (p * sqrt(p)));
double r = 2.0 * sqrt(p);
for (int n = 0; n < 3; n++)
res.push_back(r * cos((theta + 2.0 * n * CV_PI) / 3.0) - offset);
}
else
{
double gamma1 = cbrt(q + sqrt(-discriminant));
double gamma2 = cbrt(q - sqrt(-discriminant));
res.push_back( gamma1 + gamma2 - offset);
double re = -0.5 * (gamma1 + gamma2) - offset;
double im = (gamma1 - gamma2) * sqrt(3.0) / 2.0;
if (discriminant == 0.0) // Equal roots (hmmm, floating point ...)
{
res.push_back(re);
}
}
return res;
}
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 25 invités