Trouver les extremums d'une fonctions polynome

Résolu
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention   -  
yg_be Messages postés 23541 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 :) ) :

 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);
A voir également:

13 réponses

yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 
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);
}
3
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
Je n'avais pas vu ce message , je test de suite !
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
Je viens de tester, les résultats sont bon , j'aimerai bien comprendre les lignes que tu as ajouter ( de la 94 à la 100 ) ? merci beaucoup pour ton aide !
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
difficile à expliquer sans faire un dessin.
fais un graphe de la fonction y=x+10 et puis ajoute ton rectangle dans le graphe.
sans le calcul de delta, ton algorithme calcule la surface de la partie de l'intégrale qui est dans le rectangle.
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
le calcul de delta ajoute la surface qui est entre ton rectangle et l'axe des x, pour obtenir toute la surface de l'intégrale.
0
Utilisateur anonyme
 
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 ?
2
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
YCN- Messages postés 116 Date d'inscription   Statut Membre Dernière intervention   12
 
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.
1
[Dal] Messages postés 6205 Date d'inscription   Statut Contributeur Dernière intervention   1 105
 
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 flottant
double
ou
long 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ête
float.h
(http://www.cplusplus.com/reference/cfloat/)
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
merci pour vos réponses en mettant P=0 au bon endroit, ça fonctionne. Maintenant je vais pouvoir continuer le code pour calculer les intégrales, il se peut que j'ai encore des soucis .. merci
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 
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.
1
YCN- Messages postés 116 Date d'inscription   Statut Membre Dernière intervention   12
 
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 .
0
[Dal] Messages postés 6205 Date d'inscription   Statut Contributeur Dernière intervention   1 105
 
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 ?
0
YCN- Messages postés 116 Date d'inscription   Statut Membre Dernière intervention   12
 
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 ^^
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > [Dal] Messages postés 6205 Date d'inscription   Statut Contributeur Dernière intervention  
 
je n'ai rien considéré. j'ai supposé que si la précision du résultat était importante, le projet n'aurait pas été confié à un double débutant (en maths et en programmation), et utiliserait des outils appropriés tels que matlab.
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
Bonsoir, merci pour vos réponses. La méthode utilisé est imposée en fait ...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 
bonsoir, peux-tu décrire plus précisément "sa marche pas"?
0
YCN- Messages postés 116 Date d'inscription   Statut Membre Dernière intervention   12
 
Au passage grosse bizarerie ici :

printf("entrer le degre du poly attention le degre est inferieur ou egal a 20 : ");
scanf("%d", &D);
0
Utilisateur anonyme
 
Ça sert à acquérir le degré du polynome comme l'indique la question, où vois-tu quelque chose de bizarre ?
0
YCN- Messages postés 116 Date d'inscription   Statut Membre Dernière intervention   12
 
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
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
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);
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 
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;
 }
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
Bonjour, merci pour ta réponse !
je viens de remplacer par ce que tu aurais fais ca me donne les mêmes résultats
l'énoncé dit " chaque point tiré peut contribuer positivement a l'intégrale ( il vaut 1 ), négativement ( il vaut -1 ) ou se trouve hors de l'aire de la courbe ( il vaut 0 )
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584 > adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
alors ainsi:
if  ((ya<y) && (ya>0))
 {
     compteur=compteur+1;
 }
else if ((ya>y) && (ya<0))
 {
     compteur=compteur-1;
 }
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
déjà essayé en mettant +1 et -1 , ça me donne toujours le même résultat : bizarre ...
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
tu obtiens toujours les mêmes valeurs pour numerateur, compteur, ar, vallapp, numerateur et N?
as-tu testé avec des polynômes simples comme y=x et y=x^2?
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
oui par exemple avec y=x² vallap = 1.999999 en mettant -1 et +1 avec N=9999999
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
que donnent tous tes printf dans le cas de y=x²?
cela devrait nous mettre sur la piste de ce qui cloche.
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 584
 
suggestion:
déclare xmax et xmin comme float
remplace
xa=((rand())/RAND_MAX)*2-1;

par
xa=((rand()*(xmax-xmin))/RAND_MAX)+xmin;
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
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
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
j'ai comme une impression que le problème n'est que sur cette fonction, en testant avec plusieurs autres fonctions je trouve a peux près le bon résultats, mais pour f(x)=3x²+2x+2 je trouve 2.666 comme tout a l'heure
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
non je me suis trompé j'ai trouvé d'autres fonction ou sa ne fonctionne pas , des fois ça marche , des fois pas je comprend pas
0
yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention   1 584
 
et tu as bien ceci:
if  ((ya<y) && (ya>0))
 {
     compteur=compteur+1;
 }
else if ((ya>y) && (ya<0))
 {
     compteur=compteur-1;
 }

et avec y=x, y=x-1, y=x+1 ?
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention   > yg_be Messages postés 23541 Date d'inscription   Statut Contributeur Dernière intervention  
 
Oui j'ai bien ça, ce que j'obtiens :
y=x ----> environ 0 donc c'est correct
y=x-1 -----> environ -2 donc c'est correct
y=x+1 ---> environ 2 donc c'est correct
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
je comprend pas la plus part sont correcte mais par exemple pour y=3x²+2x+2 toujours 2.666 ( ce n'est pas la seule fonction ou sa coince )
0
rlo73 Messages postés 2956 Date d'inscription   Statut Membre Dernière intervention   635
 
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
0
adilbela Messages postés 20 Date d'inscription   Statut Membre Dernière intervention  
 
merci pour la réponse mais en effet, le problème pour le calcul du min est max est résolue maintenant je cherche à calculer des intégrales sur [-1;1]
0