Signaler

Trouver les extremums d'une fonctions polynome [Résolu]

Posez votre question adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - Dernière réponse le 8 juin 2017 à 09:39 par yg_be
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);
Afficher la suite 
Utile
+3
plus moins
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);
}
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 7 juin 2017 à 22:46
Je n'avais pas vu ce message , je test de suite !
Répondre
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 7 juin 2017 à 22:52
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 !
Répondre
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 7 juin 2017 à 23:25
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.
Répondre
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 8 juin 2017 à 09:39
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.
Répondre
Donnez votre avis
Utile
+2
plus moins
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 ?
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 2 juin 2017 à 21:04
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
Répondre
Donnez votre avis
Utile
+1
plus moins
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.
[Dal] 4339Messages postés mercredi 15 septembre 2004Date d'inscription ContributeurStatut 20 juin 2017 Dernière intervention - 2 juin 2017 à 12:49
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/)
Répondre
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 2 juin 2017 à 21:11
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
Répondre
Donnez votre avis
Utile
+1
plus moins
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.
[Dal] 4339Messages postés mercredi 15 septembre 2004Date d'inscription ContributeurStatut 20 juin 2017 Dernière intervention - 2 juin 2017 à 15:03
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 ?
Répondre
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 2 juin 2017 à 17:01
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.
Répondre
YCN- 135Messages postés mercredi 24 juin 2015Date d'inscription 23 juin 2017 Dernière intervention - 2 juin 2017 à 15:14
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 ^^
Répondre
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 2 juin 2017 à 21:06
Bonsoir, merci pour vos réponses. La méthode utilisé est imposée en fait ...
Répondre
Flachy Joe 2089Messages postés jeudi 16 septembre 2004Date d'inscription 24 juin 2017 Dernière intervention - 6 juin 2017 à 21:59
Pour ceux que ça intéresse et qui n'ont pas de méthode imposée, une recherche efficace est celle des zéros de la dérivée grâce à la méthode de Newton : https://fr.wikipedia.org/wiki/M%C3%A9thode_de_Newton
Répondre
Donnez votre avis
Utile
+0
plus moins
bonsoir, peux-tu décrire plus précisément "sa marche pas"?
Donnez votre avis
Utile
+0
plus moins
Au passage grosse bizarerie ici :

printf("entrer le degre du poly attention le degre est inferieur ou egal a 20 : ");
scanf("%d", &D);
le père. 5952Messages postés mardi 15 mai 2012Date d'inscription 19 juin 2017 Dernière intervention - 2 juin 2017 à 15:18
Ça sert à acquérir le degré du polynome comme l'indique la question, où vois-tu quelque chose de bizarre ?
Répondre
YCN- 135Messages postés mercredi 24 juin 2015Date d'inscription 23 juin 2017 Dernière intervention - 2 juin 2017 à 15:23
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.

http://cdn.bulbagarden.net/upload/a/a0/Confusion_status_II.png
Répondre
Donnez votre avis
Utile
+0
plus moins
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);
Donnez votre avis
Utile
+0
plus moins
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;
 }
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 6 juin 2017 à 18:15
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 )
Répondre
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 6 juin 2017 à 18:21
alors ainsi:
if  ((ya<y) && (ya>0))
 {
     compteur=compteur+1;
 }
else if ((ya>y) && (ya<0))
 {
     compteur=compteur-1;
 }
Répondre
Donnez votre avis
Utile
+0
plus moins
déjà essayé en mettant +1 et -1 , ça me donne toujours le même résultat : bizarre ...
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 6 juin 2017 à 19:16
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?
Répondre
Donnez votre avis
Utile
+0
plus moins
oui par exemple avec y=x² vallap = 1.999999 en mettant -1 et +1 avec N=9999999
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 6 juin 2017 à 19:53
que donnent tous tes printf dans le cas de y=x²?
cela devrait nous mettre sur la piste de ce qui cloche.
Répondre
Donnez votre avis
Utile
+0
plus moins
suggestion:
déclare xmax et xmin comme float
remplace
xa=((rand())/RAND_MAX)*2-1;

par
xa=((rand()*(xmax-xmin))/RAND_MAX)+xmin;
Donnez votre avis
Utile
+0
plus moins
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
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention adilbela - 7 juin 2017 à 10:47
teste avec y=x+10 et y=x-10, ce sera plus clair.
Répondre
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 6 juin 2017 à 21:15
merci beaucoup pour toutes tes réponses en tout cas :)
Répondre
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 7 juin 2017 à 22:41
Bonsoir, désolé de la réponse tardive : j'ai finis les cours à 20h le temps de me faire à manger etc...
j'ai testé avec y=x+10 ca me donne 2 , y=x-10 ca me donne -2
Répondre
yg_be 2560Messages postés lundi 9 juin 2008Date d'inscription 24 juin 2017 Dernière intervention - 7 juin 2017 à 22:49
je suppose que tu n'as pas encore testé ma suggestion en #37. cela devrait corriger ces erreurs.
Répondre
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 7 juin 2017 à 23:20
Non je n'avais pas vu en effet ca les corriges j'aimerai bien comprendre les lignes que tu as ajouter ( de la 94 à la 100 ) ? merci beaucoup pour ton aide !
Répondre
Donnez votre avis
Utile
+0
plus moins
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
adilbela 20Messages postés jeudi 1 juin 2017Date d'inscription 7 juin 2017 Dernière intervention - 6 juin 2017 à 20:50
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]
Répondre
Donnez votre avis

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes.

Le fait d'être membre vous permet d'avoir des options supplémentaires.

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !