Apprendre Maple Tableau des variations d'une fonction

 
  Page d'accueilPage d'accueil   RechercherRechercher   Forum de discussionForum de discussion   ContactContact   SommaireSommaire 
  Cours MapleCours Maple   Travaux dirigésTravaux dirigés   Thèmes d'activitésThèmes d'activités   Thèmes d'activitésMaplets
Ecran MapleEcran Maple  TéléchargementTéléchargement  BibliographieBibliographie  LiensLiens  

 

Page d'accueil   Thèmes d'activités   << Thème précédent    Thème suivant >>



Tableau des variations pour une courbe paramétrée
Tableau des variations d'une fonction définie par intervalles
 

Tableau des variations d'une fonction x->f(x)

> restart:

Procédure principale tab_var(f , x::name , a, b ) qui trace le tableau de variations de  f  à partir des paramètres formels :
(ne fonctionne pas pour certaines fonctions où la fonction solve peut donner des résultats incomplets ou erronés)

        f :      fonction de la variable réelle x.                
       x
:       nom de la variable.
       a, b:   bornes de l'intervalle d'étude.


Procédures locales internes à la procédure principale
:

Construction de la liste des valeurs de x à insérer dans le tableau des variations:
Procédure liste_X( f, x::name, a, b)
Paramètres formels :
       f :      fonction de la variable réelle x.
       x:       nom de la variable.

       a, b:   bornes de l'intervalle d'étude.
Résultat:

       N:     liste des valeurs de x (ordonnée selon les valeurs croissantes) à insérer dans le tableau des variations.
                N est formée à partir des valeurs a,b , des points singuliers de f et de f ', et des valeurs annulant  f '(x).         

Signe de la dérivée:
Procédure signe_derivee( f, L::list, X::list ) construit une liste permettant la gestion des signes de la dérivée de f
et des flèches de variations sur les différents intervalles définis par le second argument et troisième arguments.

Procédure liste_def(f , L::list) :
liste_def
( f,  liste_X(f, x, a, b) )  donne la liste indiquant les points où  f et  f ' sont définies ou non ( avec x entre a et b ) :

Résultat sous la forme d'une liste [ [x[1], b[1], c[1]] , ... , [x[n] , b[n] , c[n] ] ] ,
avec b[i] = true ( ou false )  si  f est définie (ou non définie) au point x[i]                
et  c[i] = true ( ou false )  si  f ' est définie (ou non définie) au point x[i]                   .

Affichage d'un texte:
Procédure texte(absc,ord,txt,police,taille,drapeau,indice)
Affichage d'un texte txt à la position (absc , ord) suivant la  police et la  taille des caractères:
Selon la valeur de drapeau: ( exemple x ) , et de l' indice: ( exemple i ), on affichera  
x[i]    par exemple.

Tracé des flèches:
Procédure fleche(P1,P2)
Trace une flèche entre les points P1[x1,y1] et P2[x2,y2].

> with(plots):

Warning, the name changecoords has been redefined

> tab_var:=proc(f,x::name,a,b)
local liste_X,signe_derivee,liste_def,texte,fleche,traits_verticaux,
N,X,Y,S,Lf,largeur,hauteur,bordures,doubles_traits,fleches,limites,colonne1,ligne1,signes,h,i,l,w;

#########################################################
####                                          procédure liste_X                                                            ####
#########################################################
liste_X:=proc(f,x::name,a,b)
local i,j,DF,F,L,M,N,S;
L:={a,b};
F:=[singular(f(x))]:
for i to nops(F) do
 L:=L union {rhs(op(F[i]))}
end do;
DF:=[singular(D(f)(x))]:
for i to nops(DF) do
 L:=L union {rhs(op(DF[i]))}
end do;
S:=[solve(D(f)(x),x)]:
if S=[x] then S:=[a,b] end if;
for i to nops(S) do
 L:=L union {S[i]}
end do;
L:=sort(convert(L,list));
M:=NULL;
for i to nops(L) do
 if evalb(evalf(L[i])>=evalf(a) and evalf(L[i])<=evalf(b)) then M:=M,L[i] end if
end do;
M:=sort(map(evalf,convert({M},list))):
N:=NULL;
for i to nops(M) do
 for j to nops(L) do
    if evalb(evalf(L[j])=M[i]) then N:=N,L[j] end if;
 end do;
end do;
[N]
end proc:

#########################################################
####                                               procédure signe_derivee                                          ####
#########################################################
signe_derivee:=proc(f,L::list,X::list)
local i,j,M,s;
M:=NULL;
for i to nops(X)-1 do
  if X[i]=-infinity then
      s:=evalf(simplify(D(f)(X[i+1]-1)))
  elif X[i+1]=infinity then
      s:=evalf(simplify(D(f)(X[i]+1)))
  else s:=evalf(simplify(D(f)((X[i]+X[i+1])/2)))
  end if;
  if s=0 then M:=M,0 else M:=M,sign(s) end if;
end do;
M:=[M]:
for i from nops(M) to 2 by -1 do
 if sign(M[i-1])=sign(M[i]) then
   if L[i][2]=true then M[i-1]:=M[i-1]+M[i] end if
 end if;
end do;
for i to nops(M) do
 if is(M[i],integer) and abs(M[i])>1 then
   for j from i+1 to i+abs(M[i])-1 do
      if M[i]>0 then M[j]:=evalf((j-i)/(abs(M[i])),2)
      else M[j]:=-(1+evalf((j-i)/M[i],2)) end if;  
   end do
 end if;
end do;
M
end proc:

#########################################################
####                                                   procédure list_def                                                   ####
#########################################################
liste_def:=proc(f,L::list)
local i,M,N,b,c;
M:=NULL:
for i in L do
 b:=true;c:=true;N:=NULL:
 try
    simplify(f(i));
 catch:
    b:=false;
 end try;
 N:=N,i,b;
 try
    simplify(D(f)(i));
 catch:
    c:=false;
 end try;
 N:=N,c;
 M:=M,[N]
end do;
[M];
end proc:

#########################################################
####                                                 procédure texte                                                        ####
#########################################################
texte:=proc(absc,ord,txt,police,taille,drapeau,indice)
if txt=-infinity then
  textplot([absc,ord,"-"],font=[police,taille]),textplot([absc+1.2,ord,"¥"],font=[SYMBOL,taille])
elif txt=infinity then
  textplot([absc,ord,"+¥"],font=[SYMBOL,taille])
elif drapeau=0 then
  textplot([absc,ord,txt],font=[police,taille])
else
  if is(txt,rational) then  
    textplot([absc,ord,txt],font=[police,taille])
  else  
    textplot([absc,ord,cat(drapeau,indice)],font=[police,taille])
  end if;
end if;
end proc:

#########################################################
####                                                  procédure fleche                                                      ####
#########################################################
fleche:=proc(P1,P2)
local f;

f:=proc(x1,y1,x2,y2,a)
local d,x3,y3,x4,y4,x5,y5;
d:=evalf(sqrt((x2-x1)^2+(y2-y1)^2)):
x3:=evalf(x1+(d-a)/d*(x2-x1)):y3:=evalf(y1+(d-a)/d*(y2-y1)):
x4:=evalf(x2+0.5*(sqrt(3)*(x3-x2)-y3+y2)):
y4:=evalf(y2+0.5*(x3-x2+sqrt(3)*(y3-y2))):
x5:=evalf(x2+0.5*(sqrt(3)*(x3-x2)+y3-y2)):
y5:=evalf(y2+0.5*(-x3+x2+sqrt(3)*(y3-y2))):
plot([[x1,y1],[x2,y2],[x4,y4],[x2,y2],[x5,y5]],color=black)
end proc:

f(P1[1],P1[2],P1[1]+P2[1],P1[2]+P2[2],1.5)
end proc:

#########################################################
####                                                       procédure principale                                          ####
#########################################################
X:=liste_X(f,x,a,b): # print(`liste_X `=X):
Lf:=liste_def(f,X):  # print(`liste_def `=Lf):
S:=signe_derivee(f,Lf,X): # print(`signe_derivee `=S):

largeur:=10:hauteur:=5:
w:=nops(X)*largeur:

# affichage des bordures du tableau
bordures:=[
plot([[0,0],[w,0],[w,4*hauteur],[0,4*hauteur],[0,0],[0.9*largeur,0],[0.9*largeur,4*hauteur]],color=black),
plot([[0,3*hauteur],[w,3*hauteur]],color=black),plot([[0,2*hauteur],[w,2*hauteur]],color=black)]:

# affichage des traits verticaux de séparation
traits_verticaux:=NULL:
for i to nops(S) do
 if is(S[i],integer) then
traits_verticaux:=traits_verticaux,plot([[(i+abs(S[i]))*largeur,0],[(i+abs(S[i]))*largeur,3*hauteur]],color=black)
 end if;
end do;
traits_verticaux:=[traits_verticaux]:

# affichage des doubles traits verticaux aux points où f (resp. f') n'est pas définie
doubles_traits:=NULL:
for i to nops(Lf) do
 if i=1 then l:=largeur*0.925 else l:=largeur end if;
 if Lf[i][2]=false then
    doubles_traits:=doubles_traits,plot([[i*l+0.6,0],[i*l+0.6,2*hauteur]],color=black)
 end if;
 if Lf[i][3]=false then         doubles_traits:=doubles_traits,plot([[i*l+0.6,2*hauteur],[i*l+0.6,3*hauteur]],color=black)
 else
    if simplify(D(f)(Lf[i][1]))=0 and abs(Lf[i][1])<>infinity then     doubles_traits:=doubles_traits,texte(l*i,2*hauteur+hauteur/2,0,HELVETICA,10,0,0),
   plot([[l*i,2*hauteur],[l*i,3*hauteur]],color=black)    
    end if
 end if
end do;
doubles_traits:=[doubles_traits]:

# affichage des textes dans la première colonne : "x" , "f(x)" , "f'(x)"  
colonne1:=[texte(0.45*largeur,3*hauteur+hauteur/2,x,HELVETICA,10,0,0),
        texte(0.45*largeur,2*hauteur+hauteur/2,cat(f,"`(",x,")"),HELVETICA,10,0,0),
        texte(0.45*largeur,hauteur,cat(f,`(`,x,`)`),HELVETICA,10,0,0)]:

# affichage des valeurs de x dans la première ligne du tableau
ligne1:=NULL:
for i to nops(X) do
 if X[i]=-infinity then ligne1:=ligne1,texte(largeur/20+largeur,3*hauteur+hauteur/2,X[i],HELVETICA,10,0,0)
 elif X[i]=infinity then ligne1:=ligne1,texte(w-largeur/4,3*hauteur+hauteur/2,X[i],SYMBOL,10,0,0)
 else
    ligne1:=ligne1,texte(largeur*i,3*hauteur+hauteur/2,X[i],HELVETICA,10,x,i)
 end if
end do:
ligne1:=[ligne1]:

# affichage des signes de la dérivée dans la seconde ligne et
# affichage des flèches associées dans la troisième ligne
signes:=NULL:fleches:=NULL:
for i to nops(S) do
  if S[i]<0 then
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"-",HELVETICA,10,0,0):  
    if is(S[i],integer) then fleches:=fleches,fleche([largeur*i+largeur/4,2*hauteur-hauteur/4],
        [largeur*(abs(S[i])-1)+largeur/2,-2*hauteur+hauteur/2] )
    end if;
 elif S[i]=0 then
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"0",HELVETICA,10,0,0):    
fleches:=fleches,fleche([largeur*i+largeur/4,hauteur],[largeur*(abs(S[i])-1)+largeur/2,0] )  
 else
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"+",HELVETICA,10,0,0):
    if is(S[i],integer) then
fleches:=fleches,fleche([largeur*i+largeur/4,hauteur/4],[largeur*(abs(S[i])-1)+largeur/2,2*hauteur-hauteur/2] )
    end if;
 end if;
end do;
signes:=[signes]:
fleches:=[fleches]:

# détermination des valeurs de f(x) ou des limites (à gauche ou à droite)
Y:=NULL:
for i to nops(Lf) do
 if i=1 then
   Y:=Y,[simplify(limit(f(x),x=Lf[i][1],right))]
 elif i=nops(Lf) then
   Y:=Y,[simplify(limit(f(x),x=Lf[i][1],left))]
 else
   if Lf[i][2]=true then Y:=Y,[simplify(limit(f(x),x=Lf[i][1]))]
   else Y:=Y,[simplify(limit(f(x),x=Lf[i][1],left)),simplify(limit(f(x),x=Lf[i][1],right))]
   end if
 end if;
end do;
Y:=[Y]:  

# affichage des valeurs de f(x) ou des limites aux extrémités des flèches
limites:=NULL:
for i to nops(Y) do
if i=1 then
    if S[i]<0 then
     limites:=limites,texte(largeur+largeur/8,2*hauteur-hauteur/8,Y[i][1],HELVETICA,10,f,i)
    else    
     limites:=limites,texte(largeur+largeur/8,hauteur/4,Y[i][1],HELVETICA,10,f,i);
    end if;
elif i=nops(Y) then
    if S[i-1]<0 then
      limites:=limites,texte(i*largeur-1.8,hauteur/4,Y[i][1],HELVETICA,10,f,i)
    else                  
      limites:=limites,texte(i*largeur-1.8,2*hauteur-hauteur/8,Y[i][1],HELVETICA,10,f,i)
    end if;
else
if nops(Y[i])=2 then
     if S[i-1]<0 then
         limites:=limites,texte(i*largeur-1.8,hauteur/4,Y[i][1],HELVETICA,10,f,i)
     else
         limites:=limites,texte(i*largeur-1.8,2*hauteur-hauteur/8,Y[i][1],HELVETICA,10,f,i)
     end if;
     if S[i]<0 then
         limites:=limites,texte(i*largeur+1.8,2*hauteur-hauteur/8,Y[i][2],HELVETICA,10,f,i)
     else
         limites:=limites,texte(i*largeur+1.8,hauteur/4,Y[i][2],HELVETICA,10,f,i)
     end if;

else # nops(Y[i])=1
  if S[i]<0 then
     if is(S[i],integer) then h:=2*hauteur-hauteur/8 else h:=-2*hauteur*S[i] end if;
  end if;  
  if S[i]>0 then
     if is(S[i],integer) then h:=hauteur/4 else h:=2*hauteur*S[i] end if;
  end if;
  limites:=limites,texte(i*largeur,h,Y[i][1],HELVETICA,10,f,i)  
end if;
end if;
end do:
limites:=[limites]:

# affichage des valeurs de x et des images f(x)
print(seq(x||i=Lf[i][1],i=1..nops(Lf)));
print(seq(f||i=op(Y[i]),i=1..nops(Y)));

# tracé du tableau des variations de f
display(bordures,traits_verticaux,doubles_traits,colonne1,ligne1,signes,fleches,limites,axes=none);

end proc:

> # Exemples
f:=t->1/(t^2-5*t+4)*sqrt(t+1);tab_var(f,t,-1,infinity);

f := proc (t) options operator, arrow; sqrt(t+1)/(t^2-5*t+4) end proc

t1 = -1, t2 = 1, t3 = 7/3, t4 = 4, t5 = infinity

f1 = 0, f2 = (infinity, -infinity), f3 = -3/20*30^(1/2), f4 = (-infinity, infinity), f5 = 0

[Plot]

> g:=x->(x^2+1)/(2*x^2+x-4);tab_var(g,x,-infinity,infinity);

g := proc (x) options operator, arrow; (x^2+1)/(2*x^2+x-4) end proc

x1 = -infinity, x2 = -1/4-1/4*33^(1/2), x3 = 6-37^(1/2), x4 = -1/4+1/4*33^(1/2), x5 = 6+37^(1/2), x6 = infinity

g1 = 1/2, g2 = (infinity, -infinity), g3 = 2*(-37+6*37^(1/2))/(-148+25*37^(1/2)), g4 = (-infinity, infinity), g5 = 2*(37+6*37^(1/2))/(148+25*37^(1/2)), g6 = 1/2

[Plot]

> h:=x->-x^4+2*x^3+3*x^2-4*x-5;tab_var(h,x,-infinity,infinity);

h := proc (x) options operator, arrow; -x^4+2*x^3+3*x^2-4*x-5 end proc

x1 = -infinity, x2 = -1, x3 = 1/2, x4 = 2, x5 = infinity

h1 = -infinity, h2 = -1, h3 = (-97)/16, h4 = -1, h5 = -infinity

[Plot]

> i:=x->exp(-x^2)/(x*(x^2+x-1));tab_var(i,x,-infinity,infinity);

i := proc (x) options operator, arrow; exp(-x^2)/(x*(x^2+x-1)) end proc

x1 = -infinity, x2 = -1/2*5^(1/2)-1/2, x3 = -1/2-1/2*3^(1/2), x4 = 0, x5 = 1/2*3^(1/2)-1/2, x6 = 1/2*5^(1/2)-1/2, x7 = infinity

i1 = 0, i2 = (-infinity, infinity), i3 = 4*exp(-1-1/2*3^(1/2))/(1+3^(1/2)), i4 = (infinity, -infinity), i5 = -4*exp(-1+1/2*3^(1/2))/(3^(1/2)-1), i6 = (-infinity, infinity), i7 = 0

[Plot]

> j:=x->2*x/(x^2-1)+1/2*ln(abs((1+2*x)/(1-2*x)));tab_var(j,x,-infinity,infinity);

j := proc (x) options operator, arrow; 2*x/(x^2-1)+1/2*ln(abs((1+2*x)/(1-2*x))) end proc

x1 = -infinity, x2 = -1, x3 = (-1)/2, x4 = 0, x5 = 1/2, x6 = 1, x7 = infinity

j1 = 0, j2 = (-infinity, infinity), j3 = (-infinity, -infinity), j4 = 0, j5 = (infinity, infinity), j6 = (-infinity, infinity), j7 = 0

[Plot]

Tableau des variations d'une fonction x->f(x)
Tableau des variations d'une fonction définie par intervalles



Tableau des variations pour une courbe paramétrée:  x->f(x) , x->g(x)

> restart:

Procédure principale tab_var_param(f ,g, x::name , a, b ) qui trace le tableau des variations de  f  et de g à partir des paramètres formels :
(ne fonctionne pas pour certaines fonctions où la fonction solve peut donner des résultats incomplets ou erronés)

        f ,g:   fonctions de la variable réelle x.                
       x
:       nom de la variable.
       a, b:   bornes de l'intervalle d'étude.


Procédures locales internes à la procédure principale
:

Construction de la liste des valeurs de x à insérer dans le tableau de variations:
Procédure liste_X( f, x::name, a, b)
Paramètres formels :
       f :      fonction de la variable réelle x.
       x:       nom de la variable.

       a, b:   bornes de l'intervalle d'étude.
Résultat:

       N:     liste des valeurs de x (ordonnée selon les valeurs croissantes) à insérer dans le tableau de variations.
                N est formée à partir des valeurs a,b , des points singuliers de f et de f ', et des valeurs annulant  f '(x).         

Signe de la dérivée:
Procédure signe_derivee( f, g, L::list, X::list ) construit une liste permettant la gestion des signes de la dérivée de f
et de g et les flèches de variations sur les différents intervalles définis par les troisième et quatrième arguments.

Procédure liste_def(f ,g,  L::list) : construit une liste indiquant les points où  f et  f ', ainsi que g et g ' sont
définies ou non.

Affichage d'un texte:
Procédure texte(absc,ord,txt,police,taille,drapeau,indice)
Affichage d'un texte txt à la position (absc , ord) suivant la  police et la  taille des caractères:
Selon la valeur de drapeau: ( exemple x ) , et de l' indice: ( exemple i ), on affichera  
x[i]    par exemple.

Tracé des flèches:
Procédure fleche(P1,P2)
Trace une flèche entre les points P1[x1,y1] et P2[x2,y2].

> with(plots):

Warning, the name changecoords has been redefined

> tab_var_param:=proc(f,g,x::name,a,b)
local liste_X,signe_derivee,liste_def,texte,fleche,M,N,X,Y,traits_verticaux,
Xf,Xg,Yf,Yg,S,Lfg,largeur,hauteur,bordures,doubles_traits,fleches,limites,colonne1,ligne1,
signes,h,i,j,l,w;

#########################################################
####                                           procédure liste_X                                                            ####
#########################################################
liste_X:=proc(f,x::name,a,b)
local i,j,DF,F,L,M,N,S;
L:={a,b};
F:=[singular(f(x))]:
for i to nops(F) do
 L:=L union {rhs(op(F[i]))}
end do;
DF:=[singular(D(f)(x))]:
for i to nops(DF) do
 L:=L union {rhs(op(DF[i]))}
end do;
S:=[solve(D(f)(x),x)]:
if S=[x] then S:=[a,b] end if;
for i to nops(S) do
 L:=L union {S[i]}
end do;
L:=sort(convert(L,list));
M:=NULL;
for i to nops(L) do
 if evalb(evalf(L[i])>=evalf(a) and evalf(L[i])<=evalf(b)) then M:=M,L[i] end if
end do;
M:=sort(map(evalf,convert({M},list))):
N:=NULL;
for i to nops(M) do
 for j to nops(L) do
    if evalb(evalf(L[j])=M[i]) then N:=N,L[j] end if;
 end do;
end do;
[N]
end proc:

#########################################################
####                                            procédure signe_derivee                                              ####
#########################################################
signe_derivee:=proc(f,g,L::list,X::list)
local i,j,M,N,s,t;
M:=NULL;
for i to nops(X)-1 do
  N:=NULL:
  if X[i]=-infinity then
      s:=evalf(simplify(D(f)(X[i+1]-1))):t:=evalf(simplify(D(g)(X[i+1]-1)))
  elif X[i+1]=infinity then
      s:=evalf(simplify(D(f)(X[i]+1))):t:=evalf(simplify(D(g)(X[i]+1)))
  else
      s:=evalf(simplify(D(f)((X[i]+X[i+1])/2))):t:=evalf(simplify(D(g)((X[i]+X[i+1])/2)))
  end if;
  if s=0 then N:=N,0 else N:=N,sign(s) end if;
  if t=0 then N:=N,0 else N:=N,sign(t) end if;
  M:=M,[N]
end do;
M:=[M]:
for i from nops(M) to 2 by -1 do
 if sign(M[i-1][1])=sign(M[i][1]) then
   if L[i][2]=true then M[i-1][1]:=M[i-1][1]+M[i][1] end if
 end if;
 if sign(M[i-1][2])=sign(M[i][2]) then
   if L[i][4]=true then M[i-1][2]:=M[i-1][2]+M[i][2] end if
 end if;
end do;
for i to nops(M) do
 if is(M[i][1],integer) and abs(M[i][1])>1 then
   for j from i+1 to i+abs(M[i][1])-1 do
      if M[i][1]>0 then M[j][1]:=evalf((j-i)/(abs(M[i][1])),2)
      else M[j][1]:=-(1+evalf((j-i)/M[i][1],2)) end if;  
   end do
 end if;
 if is(M[i][2],integer) and abs(M[i][2])>1 then
   for j from i+1 to i+abs(M[i][2])-1 do
      if M[i][2]>0 then M[j][2]:=evalf((j-i)/(abs(M[i][2])),2)
      else M[j][2]:=-(1+evalf((j-i)/M[i][2],2)) end if;  
   end do
 end if;
end do;
M
end proc:

#########################################################
####                                                    procédure list_def                                                  ####
#########################################################
liste_def:=proc(f,g,L::list)
local i,M,N,b;
M:=NULL:
for i in L do
 b:=true;N:=NULL:
 try
    simplify(f(i));
 catch:
    b:=false;
 end try;
 N:=N,i,b;
 b:=true;
 try
    simplify(D(f)(i));
 catch:
    b:=false;
 end try;
 N:=N,b;
 b:=true;
 try
    simplify(g(i));
 catch:
    b:=false;
 end try;
 N:=N,b;
 b:=true;
 try
    simplify(D(g)(i));
 catch:
    b:=false;
 end try;
 N:=N,b;
 M:=M,[N]
end do;
[M];
end proc:

#########################################################
####                                                   procédure texte                                                      ####
#########################################################
texte:=proc(absc,ord,txt,police,taille,drapeau,indice)
if txt=-infinity then
  textplot([absc,ord,"-"],font=[police,taille]),textplot([absc+1.2,ord,"¥"],font=[SYMBOL,taille])
elif txt=infinity then
  textplot([absc,ord,"+¥"],font=[SYMBOL,taille])
elif drapeau=0 then
  textplot([absc,ord,txt],font=[police,taille])
else
  if is(txt,rational) then  
    textplot([absc,ord,txt],font=[police,taille])
  else  
    textplot([absc,ord,cat(drapeau,indice)],font=[police,taille])
  end if;
end if;
end proc:

#########################################################
####                                                         procédure fleche                                               ####
#########################################################
fleche:=proc(P1,P2)
local f;

f:=proc(x1,y1,x2,y2,a)
local d,x3,y3,x4,y4,x5,y5;
d:=evalf(sqrt((x2-x1)^2+(y2-y1)^2)):
x3:=evalf(x1+(d-a)/d*(x2-x1)):y3:=evalf(y1+(d-a)/d*(y2-y1)):
x4:=evalf(x2+0.5*(sqrt(3)*(x3-x2)-y3+y2)):
y4:=evalf(y2+0.5*(x3-x2+sqrt(3)*(y3-y2))):
x5:=evalf(x2+0.5*(sqrt(3)*(x3-x2)+y3-y2)):
y5:=evalf(y2+0.5*(-x3+x2+sqrt(3)*(y3-y2))):
plot([[x1,y1],[x2,y2],[x4,y4],[x2,y2],[x5,y5]],color=black)
end proc:

f(P1[1],P1[2],P1[1]+P2[1],P1[2]+P2[2],1.5)
end proc:

#########################################################
####                                                   procédure principale                                               ####
#########################################################
Xf:=liste_X(f,x,a,b):Xg:=liste_X(g,x,a,b):
# print(`liste_Xf `=Xf):print(`liste_Xg `=Xg):

# calcul de la liste X de toutes les valeurs de x trouvées pour f et g
X:= convert( {op(Xf)} union {op(Xg)},list):
M:=sort(map(evalf,X)):
N:=NULL;
for i to nops(M) do
 for j to nops(X) do
    if evalb(evalf(X[j])=M[i]) then N:=N,X[j] end if;
 end do;
end do;
X:=[N]: # print(`liste_X `=X):

Lfg:=liste_def(f,g,X): # print(`liste_def `=Lfg):
S:=signe_derivee(f,g,Lfg,X): # print(`signe_derivee `=S):

largeur:=10:hauteur:=5:
w:=nops(X)*largeur:

# affichage des bordures du tableau
bordures:=[
plot([[0,0],[w,0],[w,7*hauteur],[0,7*hauteur],[0,0],[0.9*largeur,0],[0.9*largeur,7*hauteur]],color=black),
plot([[0,6*hauteur],[w,6*hauteur]],color=black),plot([[0,5*hauteur],[w,5*hauteur]],color=black),
plot([[0,3*hauteur],[w,3*hauteur]],color=black),plot([[0,2*hauteur],[w,2*hauteur]],color=black),
seq(plot([[i*largeur,5*hauteur],[i*largeur,6*hauteur]],color=black),i=2..nops(X)-1),
seq(plot([[i*largeur,2*hauteur],[i*largeur,3*hauteur]],color=black),i=2..nops(X)-1) ]:

# affichage des traits verticaux de séparation
traits_verticaux:=NULL:
for i to nops(S) do
 if is(S[i][1],integer) then
traits_verticaux:=traits_verticaux,plot([[(i+abs(S[i][1]))*largeur,3*hauteur],[(i+abs(S[i][1]))*largeur,6*hauteur]],color=black)
 end if;
 if is(S[i][2],integer) then
traits_verticaux:=traits_verticaux,plot([[(i+abs(S[i][2]))*largeur,0],[(i+abs(S[i][2]))*largeur,3*hauteur]],color=black)
 end if;
end do;
traits_verticaux:=[traits_verticaux]:

# affichage des doubles traits verticaux aux points où f,g (resp. f',g') ne sont pas définies
doubles_traits:=NULL:
for i to nops(Lfg) do
 if i=1 then l:=largeur*0.925 else l:=largeur end if;
 if Lfg[i][2]=false then
   doubles_traits:=doubles_traits,plot([[i*l+0.6,3*hauteur],[i*l+0.6,5*hauteur]],color=black)
 end if;
 if Lfg[i][3]=false then           
   doubles_traits:=doubles_traits,plot([[i*l+0.6,5*hauteur],[i*l+0.6,6*hauteur]],color=black)
 else
    if simplify(D(f)(Lfg[i][1]))=0 and abs(Lfg[i][1])<>infinity then
       doubles_traits:=doubles_traits,texte(l*i,5*hauteur+hauteur/2,0,HELVETICA,10,0,0)
    end if
 end if;
 if Lfg[i][4]=false then
   doubles_traits:=doubles_traits,plot([[i*l+0.6,0],[i*l+0.6,2*hauteur]],color=black)
 end if;
 if Lfg[i][5]=false then           
   doubles_traits:=doubles_traits,plot([[i*l+0.6,2*hauteur],[i*l+0.6,3*hauteur]],color=black)
 else
    if simplify(D(g)(Lfg[i][1]))=0 and abs(Lfg[i][1])<>infinity then
       doubles_traits:=doubles_traits,texte(l*i,2*hauteur+hauteur/2,0,HELVETICA,10,0,0)
    end if
 end if;
end do;
doubles_traits:=[doubles_traits]:

# affichage des textes dans la première colonne : "x" , "f'(x)" , "f(x)" , "g'(x)", "g(x)"  
colonne1:=[texte(0.45*largeur,6*hauteur+hauteur/2,x,HELVETICA,10,0,0),
        texte(0.45*largeur,5*hauteur+hauteur/2,cat(f,"`(",x,")"),HELVETICA,10,0,0),
        texte(0.45*largeur,4*hauteur,cat(f,`(`,x,`)`),HELVETICA,10,0,0),
        texte(0.45*largeur,2*hauteur+hauteur/2,cat(g,"`(",x,")"),HELVETICA,10,0,0),
        texte(0.45*largeur,hauteur,cat(g,`(`,x,`)`),HELVETICA,10,0,0)]:

# affichage des valeurs de x dans la première ligne du tableau
ligne1:=NULL:
for i to nops(X) do
 if X[i]=-infinity then ligne1:=ligne1,texte(largeur/20+largeur,6*hauteur+hauteur/2,X[i],HELVETICA,10,0,0)
 elif X[i]=infinity then ligne1:=ligne1,texte(w-largeur/4,6*hauteur+hauteur/2,X[i],SYMBOL,10,0,0)
 else
    ligne1:=ligne1,texte(largeur*i,6*hauteur+hauteur/2,X[i],HELVETICA,10,x,i)
 end if
end do:
ligne1:=[ligne1]:

# affichage des signes de la dérivée dans la seconde ligne et 4ème ligne
# affichage des flèches associées dans la troisième ligne et 5ème ligne
signes:=NULL:fleches:=NULL:
for i to nops(S) do

 if S[i][1]<0 then
    signes:=signes,texte(largeur/2+largeur*i,5*hauteur+hauteur/2,"-",HELVETICA,10,0,0):  
    if is(S[i][1],integer) then fleches:=fleches,fleche([largeur*i+largeur/4,5*hauteur-hauteur/4],
[largeur*(abs(S[i][1])-1)+largeur/2,-2*hauteur+hauteur/2] )
    end if;
 elif S[i][1]=0 then
    signes:=signes,texte(largeur/2+largeur*i,5*hauteur+hauteur/2,"0",HELVETICA,10,0,0):    
fleches:=fleches,fleche([largeur*i+largeur/4,4*hauteur],[largeur*(abs(S[i][1])-1)+largeur/2,0] )    else
    signes:=signes,texte(largeur/2+largeur*i,5*hauteur+hauteur/2,"+",HELVETICA,10,0,0):
    if is(S[i][1],integer) then
fleches:=fleches,fleche([largeur*i+largeur/4,3*hauteur+hauteur/4],[largeur*(abs(S[i][1])-1)+largeur/2,
2*hauteur-hauteur/2] )
    end if;
 end if;

  if S[i][2]<0 then
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"-",HELVETICA,10,0,0):  
    if is(S[i][2],integer) then fleches:=fleches,fleche([largeur*i+largeur/4,2*hauteur-hauteur/4],
    [largeur*(abs(S[i][2])-1)+largeur/2,-2*hauteur+hauteur/2] )
    end if;
 elif S[i][2]=0 then
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"0",HELVETICA,10,0,0):    
fleches:=fleches,fleche([largeur*i+largeur/4,hauteur],[largeur*(abs(S[i][2])-1)+largeur/2,0] )  
 else
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"+",HELVETICA,10,0,0):
    if is(S[i][2],integer) then
fleches:=fleches,fleche([largeur*i+largeur/4,hauteur/4],[largeur*(abs(S[i][2])-1)+largeur/2,2*hauteur-hauteur/2] )
    end if;
 end if;
end do;
signes:=[signes]:
fleches:=[fleches]:

# détermination des valeurs de f(x) ou de g(x) ou des limites (à gauche ou à droite)
Y:=NULL:
for i to nops(Lfg) do
 M:=NULL:N:=NULL:
 if i=1 then
   M:=M,simplify(limit(f(x),x=Lfg[i][1],right)):N:=N,simplify(limit(g(x),x=Lfg[i][1],right))
 elif i=nops(Lfg) then
   M:=M,simplify(limit(f(x),x=Lfg[i][1],left)):N:=N,simplify(limit(g(x),x=Lfg[i][1],left))
 else
   if Lfg[i][2]=true then M:=M,simplify(limit(f(x),x=Lfg[i][1]))
   else M:=M,simplify(limit(f(x),x=Lfg[i][1],left)),simplify(limit(f(x),x=Lfg[i][1],right))
   end if;
   if Lfg[i][4]=true then N:=N,simplify(limit(g(x),x=Lfg[i][1]))
   else N:=N,simplify(limit(g(x),x=Lfg[i][1],left)),simplify(limit(g(x),x=Lfg[i][1],right))
   end if;
 end if;
 Y:=Y,[[M],[N]]
end do;
Y:=[Y]:


# affichage des valeurs de f(x) ou des limites de f aux extrémités des flèches
limites:=NULL:
for i to nops(Y) do
if i=1 then
    if S[i][1]<0 then
      limites:=limites,texte(largeur+largeur/8,5*hauteur-hauteur/8,Y[i][1][1],HELVETICA,10,f,i)
    else    
      limites:=limites,texte(largeur+largeur/8,3*hauteur+hauteur/4,Y[i][1][1],HELVETICA,10,f,i);
    end if;
elif i=nops(Y) then
    if S[i-1][1]<0 then
      limites:=limites,texte(i*largeur-1.8,3*hauteur+hauteur/4,Y[i][1][1],HELVETICA,10,f,i)
    else                  
      limites:=limites,texte(i*largeur-1.8,5*hauteur-hauteur/8,Y[i][1][1],HELVETICA,10,f,i)
    end if;
else
if nops(Y[i][1])=2 then
     if S[i-1][1]<0 then
         limites:=limites,texte(i*largeur-1.8,3*hauteur+hauteur/4,Y[i][1][1],HELVETICA,10,f,i)
     else
         limites:=limites,texte(i*largeur-1.8,5*hauteur-hauteur/8,Y[i][1][1],HELVETICA,10,f,i)
     end if;
     if S[i][1]<0 then
         limites:=limites,texte(i*largeur+1.8,5*hauteur-hauteur/8,Y[i][1][2],HELVETICA,10,f,i)
     else
         limites:=limites,texte(i*largeur+1.8,3*hauteur+hauteur/4,Y[i][1][2],HELVETICA,10,f,i)
     end if;

else # nops(Y[i][1])=1
  if S[i][1]<0 then
     if is(S[i][1],integer) then h:=5*hauteur-hauteur/8 else h:=3*hauteur-2*hauteur*S[i][1] end if;
  end if;  
  if S[i][1]>0 then
     if is(S[i][1],integer) then h:=3*hauteur+hauteur/4 else h:=3*hauteur+2*hauteur*S[i][1] end if;
  end if;
  limites:=limites,texte(i*largeur,h,Y[i][1][1],HELVETICA,10,f,i)  
end if;
end if;
end do:

# affichage des valeurs de g(x) ou des limites de g aux extrémités des flèches
for i to nops(Y) do
if i=1 then
    if S[i][2]<0 then
     limites:=limites,texte(largeur+largeur/8,2*hauteur-hauteur/8,Y[i][2][1],HELVETICA,10,g,i)
    else    
     limites:=limites,texte(largeur+largeur/8,hauteur/4,Y[i][2][1],HELVETICA,10,g,i);
    end if;
elif i=nops(Y) then
    if S[i-1][2]<0 then
      limites:=limites,texte(i*largeur-1.8,hauteur/4,Y[i][2][1],HELVETICA,10,g,i)
    else                  
      limites:=limites,texte(i*largeur-1.8,2*hauteur-hauteur/8,Y[i][2][1],HELVETICA,10,g,i)
    end if;
else
if nops(Y[i][2])=2 then
     if S[i-1][2]<0 then
         limites:=limites,texte(i*largeur-1.8,hauteur/4,Y[i][2][1],HELVETICA,10,g,i)
     else
         limites:=limites,texte(i*largeur-1.8,2*hauteur-hauteur/8,Y[i][2][1],HELVETICA,10,g,i)
     end if;
     if S[i][2]<0 then
         limites:=limites,texte(i*largeur+1.8,2*hauteur-hauteur/8,Y[i][2][2],HELVETICA,10,g,i)
     else
         limites:=limites,texte(i*largeur+1.8,hauteur/4,Y[i][2][2],HELVETICA,10,g,i)
     end if;

else # nops(Y[i][2])=1
  if S[i][2]<0 then
     if is(S[i][2],integer) then h:=2*hauteur-hauteur/8 else h:=-2*hauteur*S[i][2] end if;
  end if;  
  if S[i][2]>0 then
     if is(S[i][2],integer) then h:=hauteur/4 else h:=2*hauteur*S[i][2] end if;
  end if;
  limites:=limites,texte(i*largeur,h,Y[i][2][1],HELVETICA,10,g,i)
end if;
end if;
end do:
limites:=[limites]:

# affichage des valeurs de x et des images f(x)
print(seq(x||i=Lfg[i][1],i=1..nops(Lfg)));
print(seq(f||i=op(Y[i][1]),i=1..nops(Y)));
print(seq(g||i=op(Y[i][2]),i=1..nops(Y)));

# tracé du tableau des variations de f
display(bordures,traits_verticaux,doubles_traits,colonne1,ligne1,signes,fleches,limites,axes=none);

end proc:

> x:=t->t^3/(t^2-9);y:=t->t*(t-2)/(t-3);

x := proc (t) options operator, arrow; t^3/(t^2-9) end proc

y := proc (t) options operator, arrow; t*(t-2)/(t-3) end proc

> tab_var_param(x,y,t,-infinity,infinity);

t1 = -infinity, t2 = -3*3^(1/2), t3 = -3, t4 = 0, t5 = 3-3^(1/2), t6 = 3, t7 = 3+3^(1/2), t8 = 3*3^(1/2), t9 = infinity

x1 = -infinity, x2 = -9/2*3^(1/2), x3 = (-infinity, infinity), x4 = 0, x5 = 2*(-9+5*3^(1/2))/(-1+2*3^(1/2)), x6 = (-infinity, infinity), x7 = 2*(9+5*3^(1/2))/(1+2*3^(1/2)), x8 = 9/2*3^(1/2), x9 = infi...

y1 = -infinity, y2 = -(9+2*3^(1/2))/(1+3^(1/2)), y3 = (-5)/2, y4 = 0, y5 = 4-2*3^(1/2), y6 = (-infinity, infinity), y7 = 4+2*3^(1/2), y8 = -(-9+2*3^(1/2))/(3^(1/2)-1), y9 = infinity

[Plot]

> f:=t->1/t+ln(2+t);g:=t->t+1/t;

f := proc (t) options operator, arrow; 1/t+ln(2+t) end proc

g := proc (t) options operator, arrow; t+1/t end proc

> tab_var_param(f,g,t,-2,+infinity);

t1 = -2, t2 = -1, t3 = 0, t4 = 1, t5 = 2, t6 = infinity

f1 = -infinity, f2 = -1, f3 = (-infinity, infinity), f4 = 1+ln(3), f5 = 1/2+2*ln(2), f6 = infinity

g1 = (-5)/2, g2 = -2, g3 = (-infinity, infinity), g4 = 2, g5 = 5/2, g6 = infinity

[Plot]

Tableau des variations d'une fonction x->f(x)
Tableau des variations pour une courbe paramétrée

Tableau des variations d'une fonction définie par intervalles

> restart:

Procédure principale tab_var_intervalles(f , x::name , a, b ) qui trace le tableau de variations de  f  définie par intervalles
à partir des paramètres formels :

(ne fonctionne pas pour certaines fonctions où la fonction solve peut donner des résultats incomplets ou erronés)

        f :      fonction de la variable réelle x.                
       x
:       nom de la variable.
       a, b:   bornes de l'intervalle d'étude.

La fonction f  définie par intervalles sera entrée sous la forme suivante (voir les exemples) :
f:=x ->
[
[x[1], x[2], b[1], c[1], f[1](x)] ,...,[x[n], x[n+1], b[n], c[n], f[n](x)] ];
f(x) = f[k](x) si  x appartient à l'intervalle ]x[k], x[k+1] [ ,
b[k]
= true ( ou false )  si l'extrémité gauche x[k] de l'intervalle est comprise (ou non comprise).
c[k] = true ( ou false ) si l'extrémité droite x[k+1] de l'intervalle est comprise (ou non comprise).
(Mettre ces booléens à la valeur true pour les cas
-infinity et +infinity ).

Procédures locales internes à la procédure principale
:

Procédure est_definie(a,f,x::name):
Cette procédure retourne true (ou false) selon que a est (ou n'est pas) une extrémité comprise de l'un des
intervalles définissant f (x).

Procédure fonction(a,f,x::name) :
Cette procédure retourne la liste de la (ou des 2) fonctions  f[k] servant à calculer la valeur prise par f au point a ou la
limite (à gauche, à droite) en ce point.
(donc 2 fonctions dans le cas où a est une extrémité d'un des intervalles définissant f (x) ).

Construction de la liste des valeurs de
x à insérer dans le tableau des variations:
Procédure liste_X( f, x::name, a, b)
Paramètres formels :
       f :      fonction de la variable réelle x.
       x:       nom de la variable.

       a, b:   bornes de l'intervalle d'étude.
Résultat:

       N:     liste des valeurs de x (ordonnée selon les valeurs croissantes) à insérer dans le tableau des variations.
                N est formée à partir des valeurs a,b , des points singuliers de f et de f ', et des valeurs annulant  f '(x).         

Signe de la dérivée:
Procédure signe_derivee( f, L::list ) construit une liste permettant la gestion des signes de la dérivée de f
et des flèches de variations sur les différents intervalles définis par le second argument.

Procédure liste_def(f,x::name,L::list) :
liste_def
( f,  liste_X(f, x, a, b) )  donne la liste indiquant les points où  f et  f ' sont définies ou non ( avec x entre a et b ) ,
ainsi :

Résultat sous la forme d'une liste [ [x[1] , b[1] , c[1] , d[1] ] , ... , [x[n] , b[n] , c[n] , d[n]  ] ] ,
avec b[i] = true ( ou false )  si  f est définie (ou non définie) au point x[i]                
et  c[i] = true ( ou false )  si  f ' est définie (ou non définie) au point x[i]
et  d[i] = true ( ou false )  si  x[i] est une extrémité (comprise ou non) de l'un des intervalles définissant f (x).                   .

Affichage d'un texte:
Procédure texte(absc,ord,txt,police,taille,drapeau,indice)
Affichage d'un texte txt à la position (absc , ord) suivant la  police et la  taille des caractères:
Selon la valeur de drapeau: ( exemple x ) , et de l' indice: ( exemple i ), on affichera  
x[i]    par exemple.

Tracé des flèches:
Procédure fleche(P1,P2)
Trace une flèche entre les points P1[x1,y1] et P2[x2,y2].

> with(plots):

Warning, the name changecoords has been redefined

> tab_var_intervalles:=proc(f,x::name,a,b)
local est_definie,fonction,liste_X,signe_derivee,liste_def,texte,fleche,
df,fn,fng,fnd,h,i,j,l,w,Lf,M,N,X,Y,S,traits_verticaux,largeur,hauteur,bordures,
doubles_traits,fleches,limites,colonne1,ligne1,signes;

#########################################################
####                                            procédure est_definie                                                   ####
#########################################################
est_definie:=proc(a,f,x::name)
local i,b;
for i to nops(f(x)) do
 b:=false;
 if (f(x)[i][1]=a and f(x)[i][3]=true) or (f(x)[i][2]=a and f(x)[i][4]=true)
     then b:=true:break end if;
end do;
b
end proc:

#########################################################
####                                               procédure fonction                                                      ####
#########################################################
fonction:=proc(a,f,x::name)
local i,L;
L:=NULL:
for i to nops(f(x)) do
    if f(x)[i][1]=a then L:=L,f(x)[i][5] end if;
    if f(x)[i][2]=a then L:=f(x)[i][5],L end if;
end do;
if L=NULL then
 for i to nops(f(x)) do
   if evalb(evalf(a)>=evalf(f(x)[i][1]) and evalf(a)<=evalf(f(x)[i][2]))
     then L:=L,f(x)[i][5] end if
 end do;   
end if;
[L]
end proc:  

#########################################################
####                                                      procédure liste_X                                                 ####
#########################################################
liste_X:=proc(f,x::name,a,b)
local i,j,DF,F,L,M,N,S;
L:={a,b};
F:=[singular(f(x))]:
for i to nops(F) do
 L:=L union {rhs(op(F[i]))}
end do;
DF:=[singular(D(f)(x))]:
for i to nops(DF) do
 L:=L union {rhs(op(DF[i]))}
end do;
S:=[solve(D(f)(x),x)]:
if S=[x] then S:=[a,b] end if;
for i to nops(S) do
 L:=L union {S[i]}
end do;
L:=sort(convert(L,list));
M:=NULL;
for i to nops(L) do
 if evalb(evalf(L[i])>=evalf(a) and evalf(L[i])<=evalf(b)) then M:=M,L[i] end if
end do;
M:=sort(map(evalf,convert({M},list))):
N:=NULL;
for i to nops(M) do
 for j to nops(L) do
    if evalb(evalf(L[j])=M[i]) then N:=N,L[j] end if;
 end do;
end do;
[N]
end proc:

#########################################################
####                                               procédure signe_derivee                                          ####
#########################################################
signe_derivee:=proc(f,x::name,L::list,X::list)
local i,j,M,s,g;
M:=NULL;
for i to nops(X)-1 do
  g:=fonction(X[i],f,x);
  if nops(g)=1 then g:=unapply(g[1],x) else g:=unapply(g[2],x) end if;
  if X[i]=-infinity then
      s:=evalf(simplify(D(g)(X[i+1]-1)))
  elif X[i+1]=infinity then
      s:=evalf(simplify(D(g)(X[i]+1)))
  else s:=evalf(simplify(D(g)((X[i]+X[i+1])/2)))
  end if;
  if s=0 then M:=M,0 else M:=M,sign(s) end if;
end do;
M:=[M]:
for i from nops(M) to 2 by -1 do
 if sign(M[i-1])=sign(M[i]) then
   if L[i][2]=true and L[i][4]=false then M[i-1]:=M[i-1]+M[i] end if
 end if;
end do;
for i to nops(M) do
 if is(M[i],integer) and abs(M[i])>1 then
   for j from i+1 to i+abs(M[i])-1 do
      if M[i]>0 then M[j]:=evalf((j-i)/(abs(M[i])),2)
      else M[j]:=-(1+evalf((j-i)/M[i],2)) end if;  
   end do
 end if;
end do;
M
end proc:

#########################################################
####                                                      procédure list_def                                               ####
#########################################################
liste_def:=proc(f,x::name,L::list)
local i,j,F,g,M,N,b,b1,b2,c,l1,l2;

M:=NULL:
for i in L do
 F:=fonction(i,f,x);
 N:=NULL:
 if nops(F)=1 then
   g:=unapply(op(F),x);
   b:=true;c:=true;
   try
     simplify(g(i));
   catch:
     b:=false;
   end try;
   N:=N,i,b;
   try
     simplify(D(g)(i));
   catch:
     c:=false;
   end try;
   N:=N,c;
 else  # nops(F)=2
   F[1]:=unapply(F[1],x):F[2]:=unapply(F[2],x):
   c:=est_definie(i,f,x);
   N:=N,i,c;
   if c then  
     b1:=true:b2:=true;
     try
       l1:=limit(diff(F[1](x),x),x=i,left);
       simplify(l1);
     catch:
       b1:=false;
     end try;
     try
       l2:=limit(diff(F[2](x),x),x=i,right);
       simplify(l2);
     catch:
       b2:=false;
     end try;
     if b1=false or b2=false then N:=N,false else
      N:=N,evalb(l1=l2 and abs(l1)<>infinity and abs(l2)<>infinity and l1<>undefined and l2<>undefined)
     end if;
   else
     N:=N,c
   end if;
 end if;
 b:=false;
 for j to nops(f(x)) do
   if f(x)[j][1]=i or f(x)[j][2]=i then b:=true: break end if
 end do;
 N:=N,b:
 M:=M,[N]
end do;
[M];
end proc:

#########################################################
####                                                   procédure texte                                                       ####
#########################################################
texte:=proc(absc,ord,txt,police,taille,drapeau,indice)
if txt=-infinity then
  textplot([absc,ord,"-"],font=[police,taille]),
  textplot([absc+1.2,ord,"¥"],font=[SYMBOL,taille])
elif txt=infinity then
  textplot([absc,ord,"+¥"],font=[SYMBOL,taille])
elif drapeau=0 then
  textplot([absc,ord,txt],font=[police,taille])
else
  if is(txt,rational) then  
    textplot([absc,ord,txt],font=[police,taille])
  else  
    textplot([absc,ord,cat(drapeau,indice)],font=[police,taille])
  end if;
end if;
end proc:

#########################################################
####                                                         procédure fleche                                               ####
#########################################################
fleche:=proc(P1,P2)
local f;

f:=proc(x1,y1,x2,y2,a)
local d,x3,y3,x4,y4,x5,y5;
d:=evalf(sqrt((x2-x1)^2+(y2-y1)^2)):
x3:=evalf(x1+(d-a)/d*(x2-x1)):y3:=evalf(y1+(d-a)/d*(y2-y1)):
x4:=evalf(x2+0.5*(sqrt(3)*(x3-x2)-y3+y2)):
y4:=evalf(y2+0.5*(x3-x2+sqrt(3)*(y3-y2))):
x5:=evalf(x2+0.5*(sqrt(3)*(x3-x2)+y3-y2)):
y5:=evalf(y2+0.5*(-x3+x2+sqrt(3)*(y3-y2))):
plot([[x1,y1],[x2,y2],[x4,y4],[x2,y2],[x5,y5]],color=black)
end proc:

f(P1[1],P1[2],P1[1]+P2[1],P1[2]+P2[2],1.5)
end proc:

#########################################################
####                                                    procédure principale                                              ####
#########################################################
X:={a,b};
for i to nops(f(x)) do
  X:=X union { op( liste_X(unapply(f(x)[i][5],x),x,f(x)[i][1],f(x)[i][2]) )}
end do;
X:=sort(convert(X,list));
M:=NULL;
for i to nops(X) do
 if evalb(evalf(X[i])>=evalf(a) and evalf(X[i])<=evalf(b)) then M:=M,X[i] end if
end do;
M:=sort(map(evalf,convert({M},list))):
N:=NULL;
for i to nops(M) do
 for j to nops(X) do
    if evalb(evalf(X[j])=M[i]) then N:=N,X[j] end if;
 end do;
end do;
X:=[N]: # print(`liste_X `=X);

Lf:=liste_def(f,x,X):  # print(`liste_def `=Lf):
S:=signe_derivee(f,x,Lf,X): # print(`signe_derivee `=S):

largeur:=10:hauteur:=5:
w:=nops(X)*largeur:

# affichage des bordures du tableau
bordures:=[
plot([[0,0],[w,0],[w,4*hauteur],[0,4*hauteur],[0,0],[0.9*largeur,0],[0.9*largeur,4*hauteur]],color=black),
plot([[0,3*hauteur],[w,3*hauteur]],color=black),plot([[0,2*hauteur],[w,2*hauteur]],color=black)]:

# affichage des traits verticaux de séparation
traits_verticaux:=NULL:
for i to nops(S) do
 if is(S[i],integer) then
traits_verticaux:=traits_verticaux,plot([[(i+abs(S[i]))*largeur,0],[(i+abs(S[i]))*largeur,3*hauteur]],color=black)
 end if;
end do;
traits_verticaux:=[traits_verticaux]:

# affichage des doubles traits verticaux aux points où f (resp. f') n'est pas définie
doubles_traits:=NULL:
for i to nops(Lf) do
 if i=1 then l:=largeur*0.925 else l:=largeur end if;
 if Lf[i][2]=false then
    doubles_traits:=doubles_traits,plot([[i*l+0.6,0],[i*l+0.6,2*hauteur]],color=black)
 end if;
 if Lf[i][3]=false then         doubles_traits:=doubles_traits,plot([[i*l+0.6,2*hauteur],[i*l+0.6,3*hauteur]],color=black)
 else
    df:=unapply(diff(op(fonction(Lf[i][1],f,x)),x),x):
    if simplify(df(Lf[i][1]))=0 and abs(Lf[i][1])<>infinity then     doubles_traits:=doubles_traits,texte(l*i,2*hauteur+hauteur/2,0,HELVETICA,10,0,0),
                                  plot([[l*i,2*hauteur],[l*i,3*hauteur]],color=black)    
    end if
 end if
end do;
doubles_traits:=[doubles_traits]:

# affichage des textes dans la première colonne : "x" , "f(x)" , "f'(x)"
colonne1:=[texte(0.45*largeur,3*hauteur+hauteur/2,x,HELVETICA,10,0,0),
        texte(0.45*largeur,2*hauteur+hauteur/2,cat(f,"`(",x,")"),HELVETICA,10,0,0),
        texte(0.45*largeur,hauteur,cat(f,`(`,x,`)`),HELVETICA,10,0,0)]:

# affichage des valeurs de x dans la première ligne du tableau
ligne1:=NULL:
for i to nops(X) do
 if X[i]=-infinity then ligne1:=ligne1,texte(largeur/20+largeur,3*hauteur+hauteur/2,X[i],HELVETICA,10,0,0)
 elif X[i]=infinity then ligne1:=ligne1,texte(w-largeur/4,3*hauteur+hauteur/2,X[i],SYMBOL,10,0,0)
 else
    ligne1:=ligne1,texte(largeur*i,3*hauteur+hauteur/2,X[i],HELVETICA,10,x,i)
 end if
end do:
ligne1:=[ligne1]:

# affichage des signes de la dérivée dans la seconde ligne et affichage des flèches associées dans la
# troisième ligne
signes:=NULL:fleches:=NULL:
for i to nops(S) do
  if S[i]<0 then
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"-",HELVETICA,10,0,0):  
    if is(S[i],integer) then fleches:=fleches,fleche([largeur*i+largeur/4,2*hauteur-hauteur/4],
     [largeur*(abs(S[i])-1)+largeur/2,-2*hauteur+hauteur/2] )
    end if;
 elif S[i]=0 then
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"0",HELVETICA,10,0,0):    
fleches:=fleches,fleche([largeur*i+largeur/4,hauteur],[largeur*(abs(S[i])-1)+largeur/2,0] )  
 else
    signes:=signes,texte(largeur/2+largeur*i,2*hauteur+hauteur/2,"+",HELVETICA,10,0,0):
    if is(S[i],integer) then
fleches:=fleches,fleche([largeur*i+largeur/4,hauteur/4],[largeur*(abs(S[i])-1)+largeur/2,2*hauteur-hauteur/2] )
    end if;
 end if;
end do;
signes:=[signes]:
fleches:=[fleches]:

# détermination des valeurs de f(x) ou des limites (à gauche ou à droite)
Y:=NULL:
for i to nops(Lf) do
 fn:=fonction(Lf[i][1],f,x):
 if nops(fn)=1 then
   fn:=unapply(op(fn),x):
   Y:=Y,[simplify(limit(fn(x),x=Lf[i][1]))]
 else
   N:=NULL:
   fng:=unapply(fn[1],x):N:=N,simplify(limit(fng(x),x=Lf[i][1],left)):
   fnd:=unapply(fn[2],x):N:=N,simplify(limit(fnd(x),x=Lf[i][1],right)):
   Y:=Y,[N]
 end if;
end do;
Y:=[Y]:  

# affichage des valeurs de f(x) ou des limites aux extrémités des flèches
limites:=NULL:
for i to nops(Y) do
if i=1 then
    if S[i]<0 then
     limites:=limites,texte(largeur+largeur/8,2*hauteur-hauteur/8,Y[i][1],HELVETICA,10,f,i)
    else    
     limites:=limites,texte(largeur+largeur/8,hauteur/4,Y[i][1],HELVETICA,10,f,i);
    end if;
elif i=nops(Y) then
    if S[i-1]<0 then
      limites:=limites,texte(i*largeur-1.8,hauteur/4,Y[i][1],HELVETICA,10,f,i)
    else                  
      limites:=limites,texte(i*largeur-1.8,2*hauteur-hauteur/8,Y[i][1],HELVETICA,10,f,i)
    end if;
else
if nops(Y[i])=2 then
     if S[i-1]<0 then
         limites:=limites,texte(i*largeur-1.8,hauteur/4,Y[i][1],HELVETICA,10,f,i)
     else
         limites:=limites,texte(i*largeur-1.8,2*hauteur-hauteur/8,Y[i][1],HELVETICA,10,f,i)
     end if;
     if S[i]<0 then
         limites:=limites,texte(i*largeur+1.8,2*hauteur-hauteur/8,Y[i][2],HELVETICA,10,f,i)
     else
         limites:=limites,texte(i*largeur+1.8,hauteur/4,Y[i][2],HELVETICA,10,f,i)
     end if;

else # nops(Y[i])=1
  if S[i]<0 then
     if is(S[i],integer) then h:=2*hauteur-hauteur/8 else h:=-2*hauteur*S[i] end if;
  end if;  
  if S[i]>0 then
     if is(S[i],integer) then h:=hauteur/4 else h:=2*hauteur*S[i] end if;
  end if;
  limites:=limites,texte(i*largeur,h,Y[i][1],HELVETICA,10,f,i)  
end if;
end if;
end do:
limites:=[limites]:

# affichage des valeurs de x et des images f(x)
print(seq(x||i=Lf[i][1],i=1..nops(Lf)));
print(seq(f||i=op(Y[i]),i=1..nops(Y)));

# tracé du tableau des variations de f
display(bordures,traits_verticaux,doubles_traits,colonne1,ligne1,signes,fleches,limites,axes=none);
end proc:

> f:=x->[[-infinity,-3,true,false,x^2+10*x+30],[-3,4,true,true,10*exp(-x^2)],[4,+infinity,false,true,-x+6]];
tab_var_intervalles(f,x,-infinity,infinity);

f := proc (x) options operator, arrow; [[-infinity, -3, true, false, x^2+10*x+30], [-3, 4, true, true, 10*exp(-x^2)], [4, infinity, false, true, -x+6]] end proc

x1 = -infinity, x2 = -5, x3 = -3, x4 = 0, x5 = 4, x6 = infinity

f1 = infinity, f2 = 5, f3 = (9, 10*exp(-9)), f4 = 10, f5 = (10*exp(-16), 2), f6 = -infinity

[Plot]

> g:=x->[[-infinity,1,true,true,-(4+x)^3],[1,3,false,false,10+1/x],[3,7,true,false,(6-x)*exp(x)+exp(7)],
[7,+infinity,true,true,-exp(x)+exp(7)]];  tab_var_intervalles(g,x,-infinity,infinity);

g := proc (x) options operator, arrow; [[-infinity, 1, true, true, -(4+x)^3], [1, 3, false, false, 10+1/x], [3, 7, true, false, (-x+6)*exp(x)+exp(7)], [7, infinity, true, true, -exp(x)+exp(7)]] end pr...

x1 = -infinity, x2 = -4, x3 = 1, x4 = 3, x5 = 5, x6 = 7, x7 = infinity

g1 = infinity, g2 = 0, g3 = (-125, 11), g4 = (31/3, 3*exp(3)+exp(7)), g5 = exp(5)+exp(7), g6 = (0, 0), g7 = -infinity

[Plot]

 

Tableau des variations d'une fonction x->f(x)
Tableau des variations pour une courbe paramétrée
Tableau des variations d'une fonction définie par intervalles
 


©  - Alain Le Stang - Navigation optimisée pour une résolution 1024 x 768.