Trouver les extremums d'une fonctions polynome
Résolu
adilbela
Messages postés
19
Date d'inscription
Statut
Membre
Dernière intervention
-
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention -
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention -
bonjour, je dois faire un projet mais pour le réaliser je dois déjà définir une fonction polynome de degré inférieur ou égal a 20 et en determiner les extremum ( max et min ) sur l'intervalle [-1;1]
j'ai essayer, mais sa marche pas et ca m'énèrve d'être bloqué ici sachant que ce n'est que le début du projet ...
merci de m'aider !
voici mon code ( je suis débutant :) ) :
j'ai essayer, mais sa marche pas et ca m'énèrve d'être bloqué ici sachant que ce n'est que le début du projet ...
merci de m'aider !
voici mon code ( je suis débutant :) ) :
printf("Hello world!\n");
int D;
float Tab[50000];
int ind;
float P;
int xmax;
int xmin;
float ymax;
float ymin;
float i;
int ii;
float yxi;
float x;
printf("entrer le degre du poly attention le degre est inferieur ou egal a 20 : ");
scanf("%d", &D);
for (ind=0; ind<=D; ind=ind+1)
{
printf(" entrer le coeff de degre %d : ", D-ind);
scanf("%f", &Tab[ind]);
}
P=0;
xmax=1;
xmin=-1;
ymax=-10000;
ymin=10000;
for (i=-1; i<=1; i=i+0.001)
{
x=i;
for (ind=0; ind<=D; ind=ind+1)
{
P=P*x+Tab[ind];
}
yxi=P;
if (yxi<=ymin)
{
ymin=yxi;
}
if (yxi>=ymax)
{
ymax=yxi;
}
}
printf("le ymax est %f le min %f ", ymax, ymin);
scanf("%f", ymax);
printf(" le min est %f ", ymin);
scanf("%f", ymin);
13 réponses
Résumé de la discussion
On cherche à définir une fonction polynôme de degré inférieur ou égal à 20 et à déterminer ses extrema (max et min) sur l'intervalle [-1, 1]. Des correctifs clés consistent à réinitialiser P à 0 à chaque nouvel échantillonnage et à calculer le polynôme par Horner afin d'éviter un décalage dû à une P non réinitialisée. Il faut aussi initialiser ymin et ymax avec la valeur du polynôme au premier point et limiter Tab à 21 éléments pour respecter le degré maximal, afin d'assurer des bornes correctes. En complément, la dérivation et la recherche des zéros de P'(x) via des méthodes comme Newton permettent de localiser précisément les extrema plutôt qu'une approche par pas fixe.
-
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention Ambassadeur 1 588
suggestion:#include <stdio.h> #include <stdlib.h> #include <time.h> int main() { printf(" integration par tirage aleatoire \n"); int D; float Tab[50]; int ind; float P; float xmax; float xmin; float ymax; float ymin; float i; int ii; float yxi; float x; float ax; float ay; float ar; int N; time_t u; int compteur; float xa; float ya; float y; float vallapp; float numerateur; time(&u); srand(u); printf("entrer le degre du poly attention le degre est inferieur ou egal a 20 : "); scanf("%d", &D); for (ind = 0; ind <= D; ind = ind + 1) { printf(" entrer le coeff de degre %d : ", D - ind); scanf("%f", &Tab[ind]); } xmax = 1; xmin = -1; ymax = -10000; ymin = 10000; for (i = -1; i <= 1; i = i + 0.0000001) { x = i; P = 0; for (ind = 0; ind <= D; ind = ind + 1) { P = P*x + Tab[ind]; } yxi = P; if (yxi <= ymin) { ymin = yxi; } if (yxi >= ymax) { ymax = yxi; } } printf("le ymax est %f le min %f ", ymax, ymin); ax = xmax - xmin; ay = ymax - ymin; ar = ax*ay; printf(" l'air du rectangle est %f ", ar); printf(" entrer le nombre de tirage souhaite"); scanf("%d", &N); compteur = 0; for (ii = 1; ii <= N; ii = ii + 1) { xa = ((rand()*(xmax - xmin)) / RAND_MAX) + xmin; ya = ((rand()*(ymax - ymin)) / RAND_MAX) + ymin; x = xa; P = 0; for (ind = 0; ind <= D; ind = ind + 1) { P = P*x + Tab[ind]; } y = P; if ((ya < y) && (ya > 0)) { compteur = compteur + 1; } else if ((ya > y) && (ya < 0)) { compteur = compteur - 1; } } printf(" le compteur est %d ", compteur); numerateur = compteur*ar; float delta; delta = 0; if (ymin > 0) delta = ymin; else if (ymax < 0) delta = ymax; vallapp = numerateur / N+(xmax-xmin)*delta; printf(" la valeur approche est %f ", vallapp); scanf("%f", ymin); } -
Bonjour
Ton programme marche presque parfaitement, à quelques petits détails près.
Le plus gros point est que tu oublies d'initialiser P à 0. Tu le fais une fois à l'extérieur du for i, mais il faut le faire à l'intérieur car tu ré-évalues P à chaque fois.
Déplace simplement la ligne P=0; et ça marche.
Je pense que tu aurais mis cette ligne naturellement au bon endroit si tu avais décomposé ton problème en fonctions comme te le conseille très justement yg_be.
(Par contre, ta façon d'évaluer le polynôme est nettement meilleure que la sienne en terme d'efficacité).
Sinon, je pense que tu devrais initialiser ymin et ymax avec la valeur du polynôme au premier point, car en fixant des valeurs arbitraires comme tu le fais, rien ne garantit que le polynôme ne reste pas toujours inférieur à ton max ou supérieur à ton min.
Et inutile de dimensionner ton Tab à 50000 si tu n'autorises pas un degré supérieur à 20. Degré qu'il faudrait vérifier, d'ailleurs.
Enfin, à quoi servent les scanf à la fin ?-
Merci beaucoup pour toutes vos réponses, en effet le problème venait du P=0... merci bien.
Le scanf à la fin c'est pour que les résultats restent affiché a l'écran car sinon une fois sur deux les résultats apparaissent et la fenêtre se ferme en moins d'une seconde alors qu'avec le scanf, elles restent
-
-
Salut,
Bon je crois déjà que une approche avec structure serait plus approprié. Voilà ce que j'ai fait pour te montrer. On est pas à l'abri d'erreurs et effets de bords puisque je n'ai pas poussé le debug très loin. Mais voilà comment je vois ça :
#include <stdlib.h> #include <stdio.h> typedef struct { float * coeff; int degree; } polynome; #define DEGREE 3 float x_pow ( float x , int degree) { int i; float pow = 1.0; for (i = 0 ; i < degree;i++){ pow *= x; } return pow; } float polynome_x ( polynome poly , float x){ float y = 0; int i; for ( i = 0 ; i < poly.degree ; i++ ) { y += x_pow(x , i); } return y; } #define LIMITE 1000.0 #define PAS 0.001 int main(void) { polynome my_polynome; int i; my_polynome.degree = DEGREE; my_polynome.coeff = (float * ) malloc (DEGREE * sizeof(float)) ; // On le remplis de manière simple pour l'exemple for (i=0;i<DEGREE;i++){ my_polynome.coeff[i] = (float ) i; } float x_p = - LIMITE; float x_max; float max = polynome_x(my_polynome,x_p); float current; while ( x_p < LIMITE ){ current = polynome_x(my_polynome,x_p); if ( current > max){ max = current; x_max = x_p; } x_p += PAS; } printf("maximum en x = %f avec P(x) = %f \n", x_max , max ); return 0; }
Maintenant à toi de t'inspirer et d'aller plus loin. Et de debuger les problèmes (attention à la puissance de 0 par exemple qui va toujours ajouter 1 et que je n'ai pas enlever par exemple, il doit très certainement en avoir d'autres). ça te fais une base je pense pour mieux structurer ton problème et y répondre de façon plus simple et plus logique.-
je n'ai pas testé ton code, mais cela a l'air sympa :-) ... sauf que tu fais le boulot à la place de adilbela ...
j'ajouterai pour adilbela, que pour une meilleure précision, on peut choisir un type flottantdouble
oulong double
, et qu'au lieu de choisir une valeur arbitraire pour le pas, on peut utiliser la valeur d'Epsilon, telle que définie dans l'entêtefloat.h
(http://www.cplusplus.com/reference/cfloat/) -
-
-
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention Ambassadeur 1 588
s'il est important pour le projet d'avoir un résultat précis, la méthode utilisée est inadaptée (quel que soit le pas).
je suppose que la précision n'est pas importante.-
Oui ça n'a pas l'air non plus. Ensuite on peu imaginer une méthode un peu dichotomique afin de trouver la solution la plus précise possible une fois que l'on a trouvé le minimum a un pas près, exemple une fois trouvé avec un pas de 0.001 on va regarder entre +/- 0.0005 et réduire encore le pas de recherche de 10 par exemple et ainsi de suite jusqu'au epsilon de float.h mais c'est vrai que ça ne semble pas être le but premier .
-
avec la méthode proposée par YCN-, j'ai suggéré des moyens d'obtenir des résultats plus précis dans les limites des types standard du C et pour le compilateur utilisé.
cela dit, cela me paraît bizarre que vous considéreriez tous deux, d'emblée, que pour un intervalle [-1;1] la précision ne serait pas importante ... j'imagine aussi que cela dépendra de la fonction polynomiale utilisée, cela dit, je ne suis pas matheux :-)
yg_be, peux-tu en dire plus sur les autres méthodes auxquelles tu penses ? -
Bah sinon on peut par exemple dériver et chercher les minimums là ou ils pourraient apparaître cad après que la dérivé ait été négative puis positive. Mais bon là encore ça pose des problème quant à savoir comment ne pas parcourir toute la dérivé. Après ouais ya certainement des trucs à chercher du côté des maths, on pourrait aussi imaginé de ne pas parcourir certaine plage de réels qui seraient équivalents, m'enfin c'est compliqué pour pas grand chose.
Donc moi je crois que ma proposition de semi dichotomie est pas mal finalement. Peut être pas le plus opti mais c'est déjà pas mal et certainement suffisant pour ce qu'il souhaite faire ^^ -
-
-
-
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question -
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention Ambassadeur 1 588
bonsoir, peux-tu décrire plus précisément "sa marche pas"? -
Au passage grosse bizarerie ici :
printf("entrer le degre du poly attention le degre est inferieur ou egal a 20 : "); scanf("%d", &D);-
-
Ah oui exact j'avais cru que D était un int * et qu'il fallait rentré une liste de coefficients! Du coup j'avais que j'avais trouvé ça bizarre!
C'est la liste de toutes les variables qui m'a rendu confus ahah, je me serais limite bléssé dans ma confusion d'ailleurs.
https://cdn.bulbagarden.net/upload/a/a0/Confusion_status_II.png
-
-
Bonjour ! j'ai avancé je viens de finir le projet qui étais donc de calculer une intégrale avec la méthode monte carlo, problème : les résultats sont pas justes, par exemple au lieu d'obtenir 6 ( calcul théorique ) j'obtient 2,9 ... alors je me demande si comme yg_be l'a dit " la méthode utilisé est inadapté " mais de la a obtenir des erreurs aussi importante ? ou c'est peut être un problème de code :
printf(" integration par tirage aleatoire \n"); int D; float Tab[500000]; int ind; float P; int xmax; int xmin; float ymax; float ymin; float i; int ii; float yxi; float x; float ax; float ay; float ar; int N; long int u; int compteur; float xa; float ya; float y; float vallapp; float numerateur; time(&u); srand(u); printf("entrer le degre du poly attention le degre est inferieur ou egal a 20 : "); scanf("%d", &D); for (ind=0; ind<=D; ind=ind+1) { printf(" entrer le coeff de degre %d : ", D-ind); scanf("%f", &Tab[ind]); } P=0; xmax=1; xmin=-1; ymax=-10000; ymin=10000; for (i=-1; i<=1; i=i+0.0000001) { x=i; for (ind=0; ind<=D; ind=ind+1) { P=P*x+Tab[ind]; } yxi=P; P=0; if (yxi<=ymin) { ymin=yxi; } if (yxi>=ymax) { ymax=yxi; } } printf("le ymax est %f le min %f ", ymax, ymin); ax=xmax-xmin; ay=ymax-ymin; ar=ax*ay; printf(" l'air du rectangle est %f ", ar); printf(" entrer le nombre de tirage souhaite"); scanf("%d", &N); compteur=0; for (ii=1; ii<=N; ii=ii+1) { xa=((rand())/RAND_MAX)*2-1; ya=((rand()*(ymax-ymin))/RAND_MAX)+ymin; x=xa; for (ind=0; ind<=D; ind=ind+1) { P=P*x+Tab[ind]; } y=P; P=0; if ((ya<y) && (y>0)) { compteur=compteur+1; } else if ((ya>y) && (y<0)) { compteur=compteur-1; } } printf(" le compteur est %d ", compteur); numerateur=compteur*ar; vallapp=numerateur/N; printf(" la valeur approche est %f ", vallapp); scanf("%f", ymin); -
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention Ambassadeur 1 588
es-tu certain de ceci?if ((ya<y) && (y>0)) { compteur=compteur+1; } else if ((ya>y) && (y<0)) { compteur=compteur-1; }
moi j'aurais fait:if ((ya<y) && (ya>0)) { compteur=compteur+1; } else if ((ya>y) && (ya<0)) { compteur=compteur+1; } -
déjà essayé en mettant +1 et -1 , ça me donne toujours le même résultat : bizarre ...
-
oui par exemple avec y=x² vallap = 1.999999 en mettant -1 et +1 avec N=9999999
-
yg_be Messages postés 23437 Date d'inscription Statut Contributeur Dernière intervention Ambassadeur 1 588
suggestion:
déclare xmax et xmin comme float
remplacexa=((rand())/RAND_MAX)*2-1;
parxa=((rand()*(xmax-xmin))/RAND_MAX)+xmin;
-
alors je viens de remplacer :
pour y=x² j'obtiens 0.667 ce qui semble correcte sur [-1;1] mais pour ( par exemple ) y=3x²+2x+2 j'obtiens : ar=10.67 ( aire du rectangle ), nombre de tirage ( à l'utilisateur de choisir ) : 9999999, compteur = 25001957, vallapp=2.66 ( comme avant de remplacer par ce que tu ma suggérer, bizarre ? ), numérateur = 266687552 -
Au risque de faire un peu de math et pas de programmation, pour chercher les min et max d'un polynômes une solution exacte serait de chercher les dérivées nulles et les extrémités du domaine de calcul.
Les min et max sont dans le lot....ça évite de faire des itérations.
désolé si je suis hors sujet, j'ai parcouru le code en diagonale