Page 1 sur 3

Non tracé des discontinuités

Posté : mer. 9 juin 2010, 17:48
par jmbdeblois
Bonjour, j'ai repris l'exemple de Heaviside pour tracer une fonction f dont je joins le code, mais il y a le tracé de la discontinuité en x=2. Je n'ai pas du tout comprendre au booléen censé l'en empêcher !
Où est mon erreur alors ?

Code : Tout sélectionner

import graph;
size(300);

real xmin=-3,xmax=3;
real ymin=-1,ymax=2;

// Test pour savoir s'il faut relier les points ou pas lors de l'utilisation de graph.
bool3 condition(real x)
{
  static int derniersigne=0;
  int signe = sgn(x);
  bool b = derniersigne == 0 || signe == derniersigne;
  derniersigne = signe;
  return b ? true : default;
}

// Définition de la fonction de Heaviside
real H(real t) {return t < 0 ? 0 : 1;}
// Définition de la fonction
real f(real t){ return t*H(t)-(t-1)*H(t-1)-H(t-2);}

// Tracé de la courbe
guide[] CH=graph(f,xmin,xmax,condition,n=400);
draw(CH,1.5bp+blue);

real margeaxe=.4;
xaxis(Label("$x$",align=Align),xmin-margeaxe,xmax+margeaxe,Ticks(NoZero),Arrow);
yaxis(ymin-margeaxe,ymax+margeaxe,Ticks(NoZero),Arrow);

shipout(bbox(2mm,Fill(white)));

Re: Non tracé des discontinuités

Posté : mer. 9 juin 2010, 18:36
par maurice
Bonjour,

en remplaçant

Code : Tout sélectionner

int signe = sgn(x);
par

Code : Tout sélectionner

int signe = sgn(x-2);
ça marche.

Code : Tout sélectionner

// Test pour savoir s'il faut relier les points ou pas lors de l'utilisation de graph.
bool3 condition(real x)
{
  static int derniersigne=0;
  int signe = sgn(x-2);
  bool b = derniersigne == 0 || signe == derniersigne;
  derniersigne = signe;
  return b ? true : default;
}


Par contre pour les explications, faudra attendre le maître.
J'ai fait ca à l'intuition.

Maurice

Re: Non tracé des discontinuités

Posté : mer. 9 juin 2010, 19:39
par jmbdeblois
Bien sûr, que je suis ballot. Merci Maurice.
EN fait le test sert à ne pas tracer les discontinuités là ou il y a des discontinuités !
Faudrait bosser sur ce booléen pour qu'il les repère systématiquement. Car s'il y en a deux, comme dans le cas d'un signal carré...

Re: Non tracé des discontinuités

Posté : mer. 9 juin 2010, 22:48
par GM
jmbdeblois a écrit :Faudrait bosser sur ce booléen pour qu'il les repère systématiquement.


Houla... pas facile cela.
J'en veux pour preuve que, si c'était un problème facile... les calculatrices sauraient les gérer or, bien souvent, elles tracent des traits verticaux abusifs reliant des branches qu'elles ne devraient pas relier.

Personne ne connait un des concepteurs de geogebra ou d'un autre grapheur pour savoir comment ils font ?

Re: Non tracé des discontinuités

Posté : jeu. 10 juin 2010, 10:10
par jmbdeblois
GM a écrit :Houla... pas facile cela.
J'en veux pour preuve que, si c'était un problème facile... les calculatrices sauraient les gérer or, bien souvent, elles tracent des traits verticaux abusifs reliant des branches qu'elles ne devraient pas relier.

L'idée que j'avais déjà programmée il y a quelques temps, est de tester la différence entre deux ordonnées consécutives dans le tracé par segment de f. Si la valeur absolue de la différence est supérieur à un certain epsilon prévu à l'avance, on ne trace pas la fonction. On saute d'un point à l'autre, sans tracer le segment entre ces deux points.
L'écueil est sur les fonctions présentant des variations très fortes (comme exp). Mais ça marchait pas trop mal.

Re: Non tracé des discontinuités

Posté : jeu. 10 juin 2010, 12:50
par maurice
Bonjour,

Et pourquoi pas un tracé point par point ?

Figure asymptote dee5e794365a4db455287766ad595c4b
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1. import graph;
  2.  
  3. //Taille de l'image
  4. size(400,0);
  5.  
  6. //Tracé de la courbe point par point
  7. void pointparpoint(real f(real x), real a, real b, int n, pen stylo=black) {
  8. real[] A=new real[n+1];
  9. real[] B=new real[n+1];
  10. real w=linewidth();
  11. for (int k=0; k<=n; ++k) {
  12. A[k]=a+k*((b-a)/n);
  13. B[k]=f(a+k*((b-a)/n));
  14. dot((A[k],B[k]),stylo+2w);
  15. }
  16. }
  17.  
  18. //Définition de la fonction
  19. real f(real x) {return floor(x);}
  20. real g(real x) {return exp(x);}
  21.  
  22. xaxis(Ticks(NoZero),Arrow);
  23. yaxis(Ticks(NoZero),Arrow);
  24. pointparpoint(f,-3,3,600,red);
  25. pointparpoint(g,-3,log(3),1000,green);


Effectivement pour l'exponentielle, n doit devenir "gran".

Maurice

Re: Non tracé des discontinuités

Posté : jeu. 10 juin 2010, 17:08
par jmbdeblois
C'est pas mal du tout ça !
Effectivement, du coup les discontinuités sont presque évacuées.
J'essaye de ce pas !

Re: Non tracé des discontinuités

Posté : jeu. 10 juin 2010, 18:27
par jmbdeblois
Voici ce que cela donne :

Figure asymptote 5aa11b95dc5c4cb5bda4eb072a81ce75
*** Pour masquer/découvrir le code Asymptote qui a permis de créer la figure, il faut cliquer dessus. ;-) ***

CODE ASYMPTOTE de la figure ci-dessus : Tout sélectionner
  1. import graph;
  2. import patterns;
  3. usepackage("mathrsfs");
  4.  
  5. unitsize(2cm,2cm);
  6. real xmin=-1,xmax=4;
  7. real ymin=-1.5,ymax=1.5;
  8.  
  9. // Définition de la fonction de Heaviside
  10. real H(real t) {return t < 0 ? 0 : 1;}
  11. // Définition de la fonction
  12. real f(real t){ return H(t)-(t-1)*H(t-1)+(t-2)*H(t-2);}
  13. real g(real t){ return -H(t-1)+H(t-2);}
  14.  
  15.  
  16. xlimits(xmin,xmax,Crop);
  17. ylimits(ymin,ymax,Crop);
  18.  
  19. // The grid :
  20. xaxis(BottomTop, xmin, xmax, Ticks("%", Step=1, step=0.5, extend=true, ptick=lightgrey));
  21. yaxis(LeftRight, ymin, ymax, Ticks("%", Step=1, step=0.5, extend=true, ptick=lightgrey));
  22. // The axis.
  23. xequals(Label("$y$",align=W),0,ymin=ymin-0.25, ymax=ymax+0.25,
  24. Ticks(NoZero,pTick=nullpen, ptick=grey),
  25. p=linewidth(1pt), Arrow(2mm));
  26. yequals(Label("$x$",align=S),0,xmin=xmin-0.25, xmax=xmax+0.25,
  27. Ticks(NoZero,pTick=nullpen, ptick=grey),
  28. p=linewidth(1pt), Arrow(2mm));
  29.  
  30. labelx(Label("$O$",NoFill), 0, SW);
  31. draw(Label("$\vec{\imath}$",align=S,UnFill),
  32. (0,0)--(1,0),scale(2)*currentpen,Arrow);
  33. draw(Label("$\vec{\jmath}$",align=W,UnFill),
  34. (0,0)--(0,1),scale(2)*currentpen,Arrow);
  35. dot((0,0));
  36.  
  37. label("$\mathscr{C}_f$",(1.5,f(1.5)),2N,red);
  38. label("$\mathscr{C}_f'$",(1.5,g(1.5)),2S,green);
  39.  
  40. //Tracé de la courbe point par point
  41. void pointparpoint(real f(real x), real a, real b, int n, pen stylo=black) {
  42. real[] A=new real[n+1];
  43. real[] B=new real[n+1];
  44. real w=linewidth();
  45. for (int k=0; k<=n; ++k) {
  46. A[k]=a+k*((b-a)/n);
  47. B[k]=f(a+k*((b-a)/n));
  48. dot((A[k],B[k]),stylo+2w);
  49. }
  50. }
  51.  
  52. pointparpoint(f,-1,3,600,red);
  53. pointparpoint(g,0,3,600,green);

Re: Non tracé des discontinuités

Posté : jeu. 10 juin 2010, 19:56
par OG
Bonsoir

Pour faire quelque chose d'efficace et rapide qui détecte tous les points de discontinuité
cela ne doit pas être coton et il y aura toujours des faux positifs ou des vrais négatifs.

Une solution intermédiaire serait déjà de pouvoir donner une liste (finie) des points de discontinuité.

O.G.

Re: Non tracé des discontinuités

Posté : jeu. 10 juin 2010, 21:12
par projetmbc
GM a écrit :Personne ne connait un des concepteurs de geogebra ou d'un autre grapheur pour savoir comment ils font ?

La seule technique que je connaisse est de travailler avec un seuil d'acceptation des segments verticaux reliant deux points consécutifs du tracé de la courbe d'équation cartésienne.

L'idée d'indiquer à la main les points de discontinuité est une très bonne idée aussi.