Comment faire un tracé de courbe point par point ?

Utilisation de Xcas

Modérateur : xcasadmin

Répondre
F. Delente
Messages : 7
Inscription : mar. juil. 21, 2009 4:13 pm

Comment faire un tracé de courbe point par point ?

Message par F. Delente » mar. juil. 21, 2009 6:51 pm

Bonsoir.

J'ai défini une fonction f donc j'aimerais faire un tracé point par point, selon un pas que je définirais moi-même.

J'ai essayé ceci dans une fenêtre 2D : (a et b sont les bornes de l'intervalle où je veux représenter la fonction)

f(x):=x²

pour k de -1 jusque 1 pas 0.1 faire
point((k,f(k));
fpour

et je n'obtiens qu'un seul point, le dernier, de coordonnées (1,1)... Comment obtenir tous les autres ?

À tout hasard, je suis sur linux, la version de Xcas est la dernière (?)

Merci pour toute indication.

parisse
Messages : 5740
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Comment faire un tracé de courbe point par point ?

Message par parisse » mar. juil. 21, 2009 7:14 pm

F. Delente a écrit :Bonsoir.

J'ai défini une fonction f donc j'aimerais faire un tracé point par point, selon un pas que je définirais moi-même.

J'ai essayé ceci dans une fenêtre 2D : (a et b sont les bornes de l'intervalle où je veux représenter la fonction)
On peut le faire directement dans une ligne de commande.
f(x):=x²

pour k de -1 jusque 1 pas 0.1 faire
point((k,f(k));
fpour
ca devrait s'afficher dans la fenetre DispG que vous pouvez faire apparaitre par le menu Cfg (ou la commande DispG). Ca n'apparaitra pas en réponse, parce que seul le dernier résultat calculé par la boucle est renvoyé par "pour". Pour afficher tous les points, il faut créer une séquence de points, le plus simple est de faire res:=NULL; avant la boucle et
res:=res,point((k,f(k));
dans la boucle.
C'est d'ailleurs un bon exemple de boucle pour le nouveau programme de 2nde, c'était à ça que vous pensiez (pour ne pas utiliser l'instruction plot avec un parametre step) ou c'est pour ne pas avoir les points reliés entre eux?

F. Delente
Messages : 7
Inscription : mar. juil. 21, 2009 4:13 pm

Re: Comment faire un tracé de courbe point par point ?

Message par F. Delente » mar. juil. 21, 2009 7:27 pm

parisse a écrit : On peut le faire directement dans une ligne de commande.
Je ne comprends pas, que voulez vous dire ?
ca devrait s'afficher dans la fenetre DispG que vous pouvez faire apparaitre par le menu Cfg (ou la commande DispG). Ca n'apparaitra pas en réponse, parce que seul le dernier résultat calculé par la boucle est renvoyé par "pour". Pour afficher tous les points, il faut créer une séquence de points, le plus simple est de faire res:=NULL; avant la boucle et
res:=res,point((k,f(k));
dans la boucle.
Ok, je vais chercher comment afifcher res dans une fenêtre graphique après ça...
C'est d'ailleurs un bon exemple de boucle pour le nouveau programme de 2nde, c'était à ça que vous pensiez (pour ne pas utiliser l'instruction plot avec un parametre step) ou c'est pour ne pas avoir les points reliés entre eux?
Oui, c'est pour les 2ndes, je voudrais tracer le graphe de la fonction « nombre de diviseurs d'un nombre » qui est suggérée dans les documents d'accompagnement.

Merci.

F. Delente
Messages : 7
Inscription : mar. juil. 21, 2009 4:13 pm

Re: Comment faire un tracé de courbe point par point ?

Message par F. Delente » mar. juil. 21, 2009 7:37 pm

J'ai défini la fonction nombreDeDiviseursDe(x) ainsi :

Code : Tout sélectionner

nombreDeDiviseursDe(x):={
  local t, k;
  x:=floor(x);
  t:=0;
  for(k:=1;k<=x;k:=k+1) {
    if(irem(x,k)==0) t:=t+1;
  }
  return t;
}
puis j'ai affiché une fenêtre 2D, dans laquelle j'ai tapé

Code : Tout sélectionner

plot(nombreDeDiviseursDe(x),x=1..25)
et j'obtiens une segmentation fault...

Je voulais joindre le fichier de la session mais j'ai eu une erreur à l'upload, je retenterai plus tard.

parisse
Messages : 5740
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Comment faire un tracé de courbe point par point ?

Message par parisse » mer. juil. 22, 2009 7:22 am

Quelques éléments de réponse:
1/ Vous pouvez taper une commande dont le résultat est graphique dans une ligne de commande normale (en-dehors d'une figure), le résultat sera affiché dans un graphe en-dessous de la figure. Ca me parait mieux adapté pour le tracé point par point, parce qu'il y a plus de place dans une ligne de commande normale, et qu'il n'y a rien d'interactif.
2/ Vous ne pouvez pas faire un plot d'une fonction définie sur les entiers uniquement. Le segfault vient très probablement d'une tentative d'évaluation en un argument réel, je vais regarder de plus près. A la limite, on pourrait utiliser plot en précisant le step pour être sur de n'évaluer qu'en des entiers, mais il faudrait alors convertir le réel en entier avec exact. Par contre, vous pouvez utiliser plotlist ou scatterplot pour représenter une liste de valeurs (les images des entiers) ou une liste de points ou mieux vous pouvez reprendre votre fonction de tracé en remplaçant l'appel à f par l'appel à nombreDeDiviseursDe.
3/ vous pouvez aussi utiliser size(idivis(x)) si le but n'est pas de faire un algo de calcul du nombre de diviseurs

a+

parisse
Messages : 5740
Inscription : mar. déc. 20, 2005 4:02 pm
Contact :

Re: Comment faire un tracé de courbe point par point ?

Message par parisse » mer. juil. 22, 2009 8:18 am

Re-bonjour,

désolé, j'ai répondu trop vite ci-dessus. Votre fonction est bien définie sur les réels grace à floor. Il y a un bug dans floor qui provoque un segfault, je pense l'avoir corrigé. Le problème apparait parce que x:=floor(x); place floor(x) dans x lorsque x est une variable non affectée, ce qu'elle est lors de l'évaluation des arguments de la commande plot. Après un mécanisme interne d'évaluation flottante de x provoquait une récursion infinie à cause du remplacement x par floor(x) puis par floor(floor(x)) etc.
Après correction du bug de floor, ca ne marchait toujours pas en raison de la facon dont le test k<=x est fait dans la boucle. Si x est non affecté, le test renvoie k<=x qui est non nul, et du coup ça tourne indéfiniment lors de l'évaluation de l'argument de plot. Je vais essayer de modifier la façon de tester dans une boucle for pour sortir de la boucle si un des éléments est symbolique.
En attendant une version corrigée, je vous invite à ajouter un test de type de x pour pouvoir fonctionner malgré tout. Juste avant x:=floor(x); ajoutez
if (type(x)!=DOM_FLOAT && type(x)!=DOM_INT) return 'nombreDeDiviseursDe'(x);
Et merci pour le signalement de bugs!

F. Delente
Messages : 7
Inscription : mar. juil. 21, 2009 4:13 pm

Re: Comment faire un tracé de courbe point par point ?

Message par F. Delente » mer. juil. 22, 2009 9:31 am

parisse a écrit :Et merci pour le signalement de bugs!
Ok, merci de votre travail !

J'ai réussi à afffcher ma courbe point par point, parfait !

Code : Tout sélectionner

tracePointParPoint(f,a,b,inc):={
  local r,k;
  r:=[];
  for(k:=a;k<=b;k:=k+inc) {
    r:=r,point((k,f(k)));
  }
}
puis

Code : Tout sélectionner

tracePointParPoint(nombreDeDiviseursDe,1,25,0.1)
me donne la représentation graphique de nombreDeDiviseursDe sur [1;25] par pas de 0,1 !

F. Delente
Messages : 7
Inscription : mar. juil. 21, 2009 4:13 pm

Re: Comment faire un tracé de courbe point par point ?

Message par F. Delente » mer. juil. 22, 2009 9:33 am

F. Delente a écrit :
parisse a écrit :Et merci pour le signalement de bugs!
Ok, merci de votre travail !

J'ai réussi à afffcher ma courbe point par point, parfait !

Code : Tout sélectionner

tracePointParPoint(f,a,b,inc):={
  local r,k;
  r:=[];
  for(k:=a;k<=b;k:=k+inc) {
    r:=r,point((k,f(k)));
  }
}
puis

Code : Tout sélectionner

tracePointParPoint(nombreDeDiviseursDe,1,25,0.1)
me donne la représentation graphique de nombreDeDiviseursDe sur [1;25] par pas de 0,1 !
P.S. Vos autres remarques (scatterplot, etc.) m'ouvrent des perspectives, je ne connais pas encore suffisamment toutes les fonctionnalités de Xcas !

Guillaume
Messages : 112
Inscription : sam. janv. 20, 2007 8:48 pm
Contact :

Re: Comment faire un tracé de courbe point par point ?

Message par Guillaume » jeu. juil. 23, 2009 8:30 am

Bonjour,
si on parle de diviseur d'un nombre, on parle d'entiers : ça évite le problème du "floor"...mais Bernard serait passé à côté d'un bug.

Sinon, une variante pour parler d'économie de temps d'un algorithme et réfléchir aux compteurs :

Code : Tout sélectionner

NbDiv(n):={
local t,k,fin;
 t:=2;
 fin:=n;
 for(k:=2;k<fin;k++){
   if(irem(n,k)==0)then{t:=t+2;fin:=n/k}
 }
return(t)
}:;
Par exemple, la réponse est instantanée pour 100010010 (mille cent dix :) ) alors qu'avec la méthode de départ il a fallu plus de 7 minutes sur mon ordi !

Pour le tracé point par point.

Code : Tout sélectionner

Plot_NbDiv(a,b):={
local P,k;
P:=NULL;
 for(k:=a;k<=b;k++){
  P:=P,[k,NbDiv(k)]
 }
scatterplot([P])
}:;

jjbat
Messages : 29
Inscription : jeu. juin 28, 2007 8:11 am
Localisation : Toulouse
Contact :

Re: Comment faire un tracé de courbe point par point ?

Message par jjbat » ven. juil. 24, 2009 9:18 pm

C'est effectivement plus rapide, mais il faut modifier l'affectation de t pour bien gérer les carrés parfaits.

Code : Tout sélectionner

NbDiv(n):={
local t,k,fin;
t:=2;
fin:=n;
for(k:=2;k<fin;k++){
   if(irem(n,k)==0)then{
     fin:=n/k;
     if(k==fin) then{t:=t+1} else{t:=t+2};}
 }
return(t)
}:;

Guillaume
Messages : 112
Inscription : sam. janv. 20, 2007 8:48 pm
Contact :

Re: Comment faire un tracé de courbe point par point ?

Message par Guillaume » ven. juil. 24, 2009 10:41 pm

Bien vu !!

Répondre