 
 
 
L’objectif ici est de traduire les algorithmes en l’écriture de programmes.
On écrit ici des programmes permettant d’avoir les termes d’une suite ou
d’une série et de trouver des valeurs approchées de leur limites.
Mais, pour édutier les suites et les séries, on peut aussi utiliser le 
tableur ce qui est souvent plus facile que d’écrire un programme.
Soit un une suite de réels définie soit par un=f(n), soit par une relation de récurrence un=f(un−m,..,un−1) et la donnée de ses premiers termes. On veut ici, calculer les valeurs de un. Pour les fonctions qui suivent, il suffira de rajouter la fonction evalf dans le return pour avoir une valeur approchée de un : par exemple return evalf(uk).
Pour avoir le n-ième terme un il suffit :
de définir la fonction f et de taper f(n).
On peut aussi mettre f comme paramètre et taper :
u(f,n):=f(n)
Ainsi u(sq,3) vaut 9 et u(sqrt,3) vaut sqrt(3).
On remarquera qu’il est souvent préférable de simplifier 
l’écriture de u(f,n) avec la commande normal : mettre plutôt
normal dans la définition de f.
Par exemple on définit :
f(x):=normal(x/sqrt(3)+sqrt(3))).
On tape :
u(f,3)
On obtient :
2*sqrt(3)
On peut aussi considérer qu’il n’y a qu’un paramètre l qui est la 
séquence f,n et définir u par :
u(l):=l[0](l[1])
Pour avoir la suite des termes uk, pour k allant de k0 à n, on écrit :
utermes(f,k0,n):={
local k,lres;
lres:=NULL;
for (k:=k0;k<=n;k++){
     lres:=lres,f(k);
}
return lres;
}
On a choisit de mettre tous les termes cherchés dans une séquence.
On a : lres:=NULL; initialise la séquence à vide.
Par exemple, avec la fonction :
f(x):=normal(x/sqrt(3)+sqrt(3))).
On tape :
utermes(f,0,5)
On obtient :
sqrt(3),4*sqrt(3)/3,5*sqrt(3)/3,2*sqrt(3),7*sqrt(3)/3,8*sqrt(3)/3
On va représenter une suite un par des segments verticaux : le terme 
up sera représenté par le segment joignant le point (p,0) au point 
(p,f(p)).
Pour faire cette représentation, on définit la fonction f et on valide le
programme suivant qui permet de représenter uj1=f(j1)..uj2=f(j2).
plotsuite(f,j1,j2):={
local j,P,L;
L:=NULL;
for (j:=j1;j<=j2;j++) {
P:=point(j+i*u(j),couleur=point_width_4+noir);
L:=L,segment(j,P,couleur=ligne_tiret+rouge),P;
}
return L;
};
Exemple
u(n):=1+(-1)^n/n
puis,
plotsuite(u,0,10)
puis,
plotsuite(u,20,30)
Pour avoir les termes u0=a,...up, on définit la fonction f puis on tape :
plotsuiterec1(f,a,p):={
local j,P,L;
L:=NULL;
a:=evalf(a);
for (j:=0;j<=p;j++) {
P:=point(j+i*a,couleur=point_width_4+noir);
L:=L,segment(j,P,couleur=ligne_tiret+rouge),P;
a:=f(a);
}
return L;
};
Exemple
f(x):=x^2-2
puis,
plotsuiterec1(f,0,10)
ou,
plotsuiterec1(sq-2,0,10)
Pour avoir les termes u0=la[0],u1=la[1],...up, on définit la fonction f puis on tape :
plotsuiterec(f,la,p):={
local j,P,L,s,a;
L:=NULL;
s:=size(la);
la:=evalf(la);
for (j:=0;j<s;j++) {
P:=point(j+i*la[j],couleur=point_width_4+noir);
L:=L,segment(j,P,couleur=ligne_tiret+rouge),P;
}
for (j:=s;j<=p;j++) {
a:=f(op(la));
P:=point(j+i*a,couleur=point_width_4+noir);
L:=L,segment(j,P,couleur=ligne_tiret+rouge),P;
la:=append(tail(la),a);
}
return L;
};
Exemple
f(x,y):=x+y
puis,
plotsuiterec(f,[0,1],6) 
Cette session se trouve dans plottoile.xws.
On rappelle que la commande plotseq(f(x),a,p) permet de visualiser les 
p premiers termes de la suite récurrente u0=a, un=f(un−1) si 
n>0 en visualisant "l’escargot".
On se propose de réécrire cette commande de façon a bien mettre en evidence
la construction des différents termes de la suite.
À la différence de plotseq la fonction plottoile a comme 
premier argument la fonction f et non l’expression f(x).
On représente le premier terme u0 par une croix noire sur l’axe des x 
d’abscisse le deuxième argument. Pour avoir u1, on trace le segment 
vertical allant de la croix au graphe de f(x), puis le segment horizontal
allant, du point du graphe de f(x) au graphe de la première bissectrice 
(pour reporter la valeur de f(u0) sur l’axe des x), 
puis, un segment vertical en pointillés allant, du graphe de la première 
bissectrice à l’axe des x pour tracer une croix rouge.
Pour avoir les termes suivants, on trace 
ensuite un segment vertical allant du point du graphe de la première 
bissectrice, au graphe de f(x), puis le segment horizontal allant, du point 
du graphe de f(x) au graphe de la première bissectrice, puis, un segment 
vertical jusqu’à l’axe des x pour tracer une croix rouge etc...
On s’arrête lorsque l’on a dessiné p croix rouges, p etant le 
troisième argument.
On tape :
plottoile(f,u,n):={
local j,v,L,P;
u:=evalf(u);
P:=point(u,couleur=point_width_4+noir);
if (n<=0 ) {return P;}
v:=f(u);
L:=segment(u,u+i*v,couleur=rouge),P;
L:=L,segment(u+i*v,v+i*v,couleur=rouge);
u:=v;
v:=f(u);
P:=point(u,couleur=point_width_4+rouge);
L:=L,segment(u,u+i*u,couleur=ligne_tiret+rouge),P;
for (j:=2;j<=n;j++) {
L:=L,segment(u+i*u,u+i*v,couleur=rouge);
L:=L,segment(u+i*v,v+i*v,couleur=rouge);
u:=v;
v:=f(u);
P:=point(u,couleur=point_width_4+rouge);
L:=L,segment(u,u+i*u,couleur=ligne_tiret+rouge),P;}
return plotfunc(f(x),x,couleur=vert),plotfunc(x,x,couleur=bleu),L;
};
Par exemple pour voir les premiers termes de :
u0=2, si n ≥ 1, un=cos(un−1), on tape :
plottoile(cos,2,5)
On peut aussi noter les indices des termes de la suite pour la croix
représentant uj en rajoutant legende(u,j,quadrant4). 
plottoilegende(f,u,n):={
local j,v,L,P;
u:=evalf(u);
P:=point(u,couleur=point_width_4+noir),legende(u,0,quadrant4);
if (n<=0 ) {return P;}
v:=f(u);
L:=segment(u,u+i*v,couleur=rouge),P;
L:=L,segment(u+i*v,v+i*v,couleur=rouge);
u:=v;
v:=f(u);
P:=point(u,couleur=point_width_4+rouge),legende(u,1,quadrant4);
L:=L,segment(u,u+i*u,couleur=ligne_tiret+rouge),P;
for (j:=2;j<=n;j++) {
L:=L,segment(u+i*u,u+i*v,couleur=rouge);
L:=L,segment(u+i*v,v+i*v,couleur=rouge);
u:=v;
v:=f(u);
P:=point(u,couleur=point_width_4+rouge),legende(u,j,quadrant4);
L:=L,segment(u,u+i*u,couleur=ligne_tiret+rouge),P;}
return plotfunc(f(x),x,couleur=vert),plotfunc(x,x,couleur=bleu),L;
};
Par exemple pour voir les premiers termes avec leur indice de :
u0=2, si n ≥ 1, un=cos(un−1), on tape :
plottoilegende(cos,2,5)
On peut aussi faire une animation qui montrera la progression de la 
construction. Pour cela on modifie la fonction plottoile en toile
pour avoir dans LT, la progression du tracé. On remarquera que l’on met
entre crochet les objets graphiques qui seront affichés simultanément lors 
de l’animation.
On tape :
toile(f,u,n):={
local j,v,L,P,LT;
u:=evalf(u);
P:=point(u,couleur=point_width_4+noir);
v:=f(u);
LT:=P;
L:=segment(u,u+i*v,couleur=rouge);
L:=L,segment(u+i*v,v+i*v,couleur=rouge);
u:=v;
v:=f(u);
P:=point(u,couleur=point_width_4+rouge);
L:=L,segment(u,u+i*u,couleur=ligne_tiret+rouge),P;
LT:=LT,[LT,L];
for (j:=2;j<=n;j++) {
L:=L,segment(u+i*u,u+i*v,couleur=rouge);
L:=L,segment(u+i*v,v+i*v,couleur=rouge);
u:=v;
v:=f(u);
P:=point(u,couleur=point_width_4+rouge);
L:=L,segment(u,u+i*u,couleur=ligne_tiret+rouge),P;
LT:=LT,[LT,L];
}
return LT;
};
Puis on anime la liste LT renvoyée par toile.
animtoile(f,u,n):={
local LT;
LT:=toile(f,u,n);
return plotfunc(f(x),x,couleur=vert),
       plotfunc(x,x,couleur=bleu),
       animation(LT);
};
Par exemple pour voir en animation les premiers termes de :
u0=2, si n ≥ 1, un=cos(un−1), on tape :
animtoile(cos,2,5)
On peut régler la vitesse d’animation avec Menu ->Animation (situé 
dans le pavé de boutons à droite de la fenêtre graphique).
On peut arrêter l’animation avec le bouton ▸| (à 
gauche de Menu) : il suffit alors, de cliquer dans la 
fenêtre graphique, pour que l’animation se déroule au pas à pas.
Commençons par un exemple : la suite de Fibonnacci définie par :
u0=a
u1=b
un=un−1+un−2 pour n ≥ 2
On écrit pour avoir un:
fibon(a,b,n):={
local k,uk;
for (k:=2;k<=n;k++) {
    uk:=a+b;
    a:=b;
    b:=uk;
}
return uk;
}
On écrit pour avoir u0,u1...un:
fibona(a,b,n):={
local k,uk,res;
res:=a,b;
for (k:=2;k<=n;k++) {
    uk:=a+b;
    a:=b;
    b:=uk
    res:=res,uk;
}
return res;
}
On écrit pour avoir uc,uc+1...un pour c ≥ 0 :
fibonac(a,b,c,n):={
local k,uk,res;
for (k:=2;k<c;k++) {
    uk:=a+b;
    a:=b;
    b:=uk
};
if c>1 res:=NULL else 
    if c==0 {res:=a,b;c:=2;} else 
        if c==1 {res:=b;c:=2};
for (k:=c;k<=n;k++) {
    uk:=a+b;
    a:=b;
    b:=uk
    res:=res,uk;
}
return res;
}
Remarque On peut bien sûr écrire un programme récursif qui donne la valeur de un. Mais cela n’est pas efficace car on calcule plusieurs fois le même terme. Car par exemple pour calculer u5 on doit calculer u3 et u4 et pour calculer u4, il faudra à nouveau calculer u3 et u2, donc u3 sera calculé 2 fois et u2 sera calculé 3 fois. Pour s’en rendre compte on peut imprimer les valeurs des variables pour chacun des appels récursifs.
On a :
u0=u0
u1=u1
un=un−1+un−2 pour n ≥ 2
Donc
fibonr(u0,u1,n):={
if (n==0) {print(u0,u1,n);return u0;}
if (n==1) {print(u0,u1,n)return u1;}
print(u0,u1,n)
return fibonr(u0,u1,n-2)+fibonr(u0,u1,n-1);
}:;
On peut aussi compter le nombre de fois que la fonction a èté appelée c’est à dire le nombre de print du programme fibonr précédent:
fibona(u0,u1,n):={
if (n==0) {return [u0,1];}
if (n==1) {return [u1,1];}
print(u0,u1,n)
return fibona(u0,u1,n-2)+fibona(u0,u1,n-1)+[0,1];
}
On tape : fibona(1,1,6)
On obtient : [13,25]
On a :
1 appel avec n=6,
1 appel avec n=5,
2 appels avec n=4,
3 appels avec n=3,
5 appels avec n=2,
8 appels avec n=1,
5 appels avec n=0,
On remarque que le nombre d’appels est une suite de Fibonacci et on voit que 
pour calculer un on doit calculer u2 fibon(1,1,n-2 fois !
On suppose maintenant que la suite est définie par une relation de 
récurrence definie par une fonction f de m variables :
pour définir la suite on se donne les m premiers termes :
u0,u1,..,um−1 et la relation :
un=f(un−m,un−m+1,..,un−1) pour n≥ m.
On veut calculer un, et on suppose que les valeurs de 
u0,u1,..,um−1 sont dans la liste l0.
 On écrit :
urec(f,n,l0):={
local s,k,uk;
s:=size(l0);
l0:=op(l0);
for (k:=s;k<=n;k++) {
    uk:=f(l0);
    l0:=tail(l0),uk;
}
return uk;
}
On utilise op au début, pour transformer la liste l0 en une 
séquence et tail(l0) pour enlever le premier élément et ainsi 
l0:=tail(l0),uk est une séquence qui a toujours s éléments.
On peut aussi considérer que le paramètre l contient toutes les 
variables à savoir l=f,n,u0,..,um−1 . On écrit mais c’est 
inutilement compliqué (!) :
urecs(l):={
local f,n,s,k,uk;
f:=l[0];
n:=l[1];
l:=tail(tail(l));
s:=size(l);
//f est une fonction de s variables
for (k:=s;k<=n;k++) {
    uk:=f(l);
    l:=tail(l),uk;
}
return uk;
}
Pour avoir tous les termes uk de la suite pour k allant de 0 à n,
On considère que le paramètre l contient toutes les 
variables à savoir l=f,n,u0,..,um−1.
On écrit :
urec_termes(l):={
local f,n,s,k,uk,lres;
f:=l[0];
n:=l[2];
l:=tail(tail(tail(l)));
s:=size(l);
//f est une fonction de s variables
lres:=l;
for (k:=s;k<=n;k++) {
    uk:=f(l);
    lres:=lres,uk;
    l:=tail(l),uk;
}
return lres;
}
Par exemple on définit :
f(x,y):=normal(x+y)
On tape :
urec_termes(f,5,1,1)
On obtient la suite de Fibonacci :
1,1,2,3,5,8
On tape :
urec_termes(f,5,1,(sqrt(5)+1)/2)
On obtient :
1,(sqrt(5)+1)/2,(sqrt(5)+3)/2,sqrt(5)+2,
(3*sqrt(5)+7)/2,(5*sqrt(5)+11)/2
On tape, pour vérifier que l’on a obtenu la suite géométrique de raison 
(sqrt(5)+1)/2 :
seq(normal(((sqrt(5)+1)/2)^k),k=0..5)
On obtient :
1,(sqrt(5)+1)/2,(sqrt(5)+3)/2,sqrt(5)+2,
(3*sqrt(5)+7)/2,(5*sqrt(5)+11)/2
Pour avoir tous les termes uk de la suite pour k allant de k0 à n,
On considère que le paramètre l contient toutes les 
variables à savoir l=f,k0,n,u0,..,um−1.
On écrit :
urec_termekn(l):={
local f,n,s,k,uk,k0,lres;
f:=l[0];
k0:=l[1];
n:=l[2];
l:=tail(tail(tail(l)));
s:=size(l);
//f est une fonction de s variables
for (k:=s;k<k0;k++) {
    uk:=f(l);
    l:=tail(l),uk;
};
if k0>1 res:=NULL else 
  if k0==0 {res:=a,b;k0:=2;} else 
    if k0==1 {res:=b;k0:=2};
for (k:=k0;k<=n;k++) {
    uk:=f(l);
    lres:=lres,uk;
    l:=tail(l),uk;
}
return lres;
}
Par exemple on définit :
f(x,y):=normal(x+y)
On tape :
urec_termekn(f,5,10,1,1)
On obtient la suite de Fibonacci :
8,13,21,34,55,89
On tape :
urec_termes(f,5,9,1,(sqrt(5)+1)/2)
On obtient :
5*sqrt(5)+11)/2,4*sqrt(5)+9,(13*sqrt(5)+29)/2,
 (21*sqrt(5)+47)/2,17*sqrt(5)+38
Soit un une suite de réels telle que la série ∑k=0∞uk converge vers S. On veut ici, calculer une valeur appochée de cette somme. Si la série converge rapidement, il suffit de calculer ∑k=0n uk pour n assez grand, sinon il faut procéder à une accélération de convergence, en construisant une série de même somme et convergeant plus rapidement.
On écrit :
sum_serie(f,n0,n):={
local s,k;
//un=f(n) ou f est une fonction de 1 variable
s:=0;
for (k:=n0;k<=n;k++) {
    s:=s+evalf(f(k));
}
return s;
}
Il est plus précis de faire le calcul de la somme en commençant par les plus petits termes, on écrit :
serie_sum(f,n0,n):={
local s,k;
//un=f(n) ou f est une fonction de 1 variable
s:=0;
for (k:=n;k>=n0;k--) {
    s:=s+evalf(f(k));
}
return s;
}
On peut avoir aussi besoin de la suite des sommes partielles : par exemple 
pour les séries alternées deux sommes partielles successives encadrent 
la somme de la série.
On écrit en utilisant un paramètre supplémentaire alt pour 
repérer les séries alternées de la forme un=altn*f(n) : 
sums_serie(f,n0,n,alt):={
local ls,s,k;
//un=(alt)^n*f(n) ou f est une fonction de 1 variable
s:=0;
ls:=[];
if (alt<0){
  if (irem(n0,2)==0) {alt:=-alt;}
  for (k:=n0;k<=n;k++) {
    s:=s+evalf(alt*f(k));
    alt:=-alt;
    ls:=concat(ls,s);
  }
}
else {
  for (k:=n0;k<=n;k++) {
    s:=s+evalf(alt*f(k));
    ls:=concat(ls,s);
  } 
}
return ls;
}
On va calculer la somme :
∑k=0n1/k! en commencant par les plus petits termes :
vale0(n):={
local S,k;
S:=0;
for (k:=n;k>=0;k--){
S:=S+1/k!;
}
return S;
}
:;
On tape :
SS:=vale0(22)
iquo(numer(SS)*10^22,denom(SS))
On obtient :
27182818284590452353602
On va calculer la somme :
S=∑k=0n1/k! en calculant k! au fur et à mesure dans f
vale1(n):={
local S,f,k;
f:=1;
S:=1;
for (k:=1;k<=n;k++){
f:=f*k;
S:=S+1/f;
}
return S;
}
:;
On tape :
S:=vale1(22)
iquo(numer(S)*10^22,denom(S))
On obtient :
27182818284590452353602
On va calculer la somme :
S=∑k=0n1/k! en calculant son numérateur p et son 
dénominateur f à chaque étape : on a p/(k−1)!+1/k!=(p*k+1)/k!
et k!=f*k. Le résultat obtenu en cherchant le quotient de 10n*p
par f donnera les n chiffres significatils de e i.e e=vale(n)*10−n
lorsque n≥ 22 car 1./23!<4e−23
vale(n):={
local p,f,k;
f:=1;
p:=1;
for (k:=1;k<=n;k++){
f:=f*k;
p:=p*k+1;
}
return iquo(p*10^n,f);
}
:;
On tape :
vale(22)
On obtient :
27182818284590452353602
 
On suppose que un=f(n) et que f(n) admet un développement limité 
à tous les ordres par rapport à 1/n.
On suppose que uk∼ a/kp et on pose :
 vk=uk−a/(k+1)(k+2)...(k+p)
On a alors,  vk=O(1/kp+1) et on connait :
∑k=0∞a/(k+1)(k+2)...(k+p)
En effet :
a/(k+1)(k+2)...(k+p)=a/p−1(1/(k+1)(k+2)...(k+p−1)−a/(k+2)(k+3)...(k+p)) 
donc
∑k=0∞a/(k+1)(k+2)...(k+p)=a/p−1(1/1· 2·...· (p−1))=a/(p−1)(p−1)! et,
∑k=k0∞a/(k+1)(k+2)...(k+p)=a/(p−1)(k0+1)(k0+2)..(k0+p−1)
On a :
∑k=0∞uk=a/(p−1)(p−1)!+∑k=0∞vk
On peut ensuite continuer à appliquer la même méthode à vk.
Exercice
Utiliser cette méthode pour calculer numériquement :
∑k=0∞1/(k+1)2.
On va faire "à la main" trois accélérations successives.
On pose :
 uk =1/(k+1)2
On tape :
u(k):=1/(k+1)^2
On tape :
v(k):=1/((k+1)^2*(k+2))
On tape :
w(k):=2/((k+1)^2*(k+2)*(k+3))
On tape :
t(k):=6/((k+1)^2*(k+2)(k+3)(k+4))
On compare π2/6 et les valeurs obtenues pour n=200, car on sait 
que :
 S=∑k=0∞1/(k+1)2=π2/6≃ 1.64493406685
On tape :
serie_sum(u,0,200)
ou
evalf(sum(1/(k+1)^2,k=0..200))
On obtient S à 5*10−3 prés (1 décimale exacte) :
1.63997129788
On tape :
1+serie_sum(v,0,200)
ou
evalf(1+sum(1/((k+1)^2*(k+2)),k=0..200))
On obtient S à 1.25*10−5 prés (4 décimales exactes) :
1.64492179293
On tape :
1+1/4+serie_sum(w,0,200)
ou
evalf(1+1/4+sum(2/((k+1)^2*(k+2)*(k+3)),k=0..200))
On obtient S à 8.3*10−8 prés (5 décimales exactes) :
1.64493398626
On tape :
1+1/4+1/9+serie_sum(t,0,200)
ou
evalf(1+1/4+1/9+sum(6/((k+1)^2*(k+2)*(k+3)*(k+4)),k=0..200))
On obtient S à 9.2*10−10 prés (8 décimales exactes) :
1.64493406596
Les erreurs
Si on compare la somme ∑k=n+1∞1/(k+1)2 à une intégrale on a :
| 
 | 
 | < | ∫ | 
 | 
 | dx= | 
 | 
Ou encore, on peut aussi remarquer que :
| 
 | 
 | < | 
 | 
 | = | 
 | 
puisque  1/k(k+1)=1/k−1/k+1.
Au bout de la p-ième accéleration on calcule la somme de :
 uk(p)=p!/(k+1)2(k+2)...(k+p+1) et on a :
| 
 | 
 | < | 
 | 
 | 
Et puisque :
| 
 | = | 
 | − | 
 | 
On a :
| 
 | un(p)= | 
 | 
 | < | 
 | 
Donc
| 
 | un(p)< | 
 | 
On vérifie (π2/6≃ 1.64493406685) :
 1.63997129788<π2/6<1.63997129788+1/201=1.64494642226
 1.64492179293<π2/6<1.64492179293+1/(2*2012)=1.64493416886
 1.64493398626<π2/6<1.64493398626+2/(3*2013)=1.64493406836
 1.64493406596<π2/6<1.64493406596+6/(4*2014)=1.64493406688
Le programme
On peut écrire un programme qui va demander le nombre d’accélérations
pour calculer
 ∑k=0∞1/(k+1)2
serie_sumacc(n,acc):={
local p,l,j,k,ls,sf,sg,gk,fact;
ls:=[];
//calcul sans acceleration
sf:=0.0;
for (k:=n;k>=0;k--) {
   sf:=sf+1/(k+1)^2;
}
ls:=[sf];
sf:=0.0;
fact:=1;
for (p:=1;p<=acc;p++){
  //calcul de 1+1/4+..+1/p^2, le terme a rajouter
  sf:=sf+evalf(1/p^2);
  //calcul de p!
  fact:=fact*(p);
  //calcul de sg, somme(de 0 a n) de la serie acceleree p fois
  sg:=0.0;
  for (k:=0;k<=n;k++) {
    gk:=1/(k+1)^2;
    //calcul du k-ieme terme gk de la serie acceleree p fois (sans p!)
    for (j:=1;j<=p;j++) {
      gk:=evalf(gk/(k+j+1));
    }
    sg:=sg+gk;
  }
  ls:=concat(ls,sf+fact*sg);
}
return(ls);
}
On suppose que uk=(−1)kf(k) avec f(k) tend vers zéro quand k tend 
vers +∞ et f décroissante de ℝ+ dans ℝ+.
On pose :
g(x)=1/2(f(x)−f(x+1)) donc
 vk=(−1)kf(k)−f(k+1)/2=uk+uk+1/2=(−1)k g(k)
On a :
∑k=0n vk=1/2(∑k=0n uk+∑k=0n uk+1)
donc,
∑k=0n vk=1/2(∑k=0n uk+∑k=1n+1 uk)
donc,
∑k=0n vk=u0/2+un+1/2+∑k=0n uk
Puisque f(k) tend vers zéro quand k tend vers +∞,
g(k)=1/2(f(k)−f(k+1)) tend aussi vers zéro quand k tend vers 
+∞.
Si la fonction f est convexe (f″(x)>0), la série ∑k=0∞vk
vérifie aussi le théorème des séries alternées.
En effet, pour x>0 on a :
g(x)=1/2(f(x)−f(x+1)) ≥ 0 puisque f décroissante sur
ℝ+
g′(x)=1/2(f′(x)−f′(x+1)) < 0 puisque f″(x)>0, f′ est
négative et croissante sur ℝ+
donc g est décroissante de ℝ+ dans ℝ+ et 
g(k) tend vers zéro quand k tend vers +∞.
Conclusion : La série ∑k=0∞vk est une série
alternée de somme S+u0/2.
Si de plus, f′(x)/f(x) tend vers zéro quand x tend vers l’infini,
la série ∑k=0∞vk converge plus rapidement que 
∑k=0∞uk, puisque il existe c, x<c<x+1 d’après le th des accroissements finis tel que:
 0<g(x)=1/2(f(x)−f(x+1))=−1/2f′(c)
on a donc, puisque f′ est négative et croissante:
0<g(x)<−1/2f′(x)=o(f(x)).
Utiliser cette méthode pour calculer numériquement :
∑k=0∞(−1)k/k+1.
Toutes les dérivées de f(x)=1/(x+1) ont un signe constant sur 
[0;+∞[ et tendent vers zéro à l’infini, ces dérivées sont donc 
monotones et on peut donc faire plusieurs accélérations successives.
On va faire "à la main " trois accélérations successives.
On pose :
 uk =(−1)k/(k+1)
On tape :
u(k):=(-1)^k/(k+1)
On tape :
v(k):=(-1)^k/(2*(k+1)*(k+2))
On tape :
w(k):=(-1)^k/(2*(k+1)*(k+2)*(k+3))
On tape :
t(k):=(-1)^k*3/(4*(k+1)*(k+2)*(k+3)*(k+4))
On compare  ln(2) et les valeurs obtenues pour n=200, car on sait 
que :
 S=∑k=0∞(−1)k1/(k+1)=ln(2)≃ 
0.69314718056
On tape :
serie_sum(u,0,200)
On obtient S à 5*10−3 prés (2 décimales exactes) :
0.69562855486
On tape :
1/2+serie_sum(v,0,200)
On obtient S à 1.23*10−5 prés (4 décimales exactes) :
0.693153307335
On tape :
1/2+1/8+serie_sum(w,0,200)
On obtient S à 6.1*10−8 prés (8 décimales exactes) :
0.693147210666
On tape :
1/2+1/8+1/24+serie_sum(t,0,200)
On obtient S à 4.6*10−10 prés (10 décimales exactes) :
0.693147180781
Les erreurs
Le reste d’une série alternée est du signe de son premier terme et 
la valeur absolue du reste est inférieure à la valeur absolue de son
premier terme :
|∑k=n+1∞(−1)k1/(k+1)|<1/(n+2)
Au bout de la p-ième accéleration on calcule la somme de :
 uk(p)=(−1)kp!/2p(k+1)(k+2)...(k+p+1) et on a :
| | | 
 | 
 | |< | 
 | < | 
 | 
On vérifie (ln(2)≃ 0.69314718055995) :
 0.69562855486<ln(2)<0.69562855486+1/202=0.70057904991
 0.693153307335<ln(2)<0.693153307335+1/(2*2022)=0.693165561036
 0.693147210666<ln(2)<0.693147210666+2/(4*2023)=0.693147271328
 0.693147180781<ln(2)<0.693147180781+6/(8*2024)=0.693147181231.
On peut écrire un programme qui va demander le nombre p 
d’accélérations.
Si  uk(p) désigne le k-ième terme de la série accélérée
p fois, on a :
 ∑k=0∞(−1)k/(k+1)=∑k=0pu0(k−1)/2+∑k=0∞uk(p)
avec
  uk(p)=(−1)k p!/2p(k+1)...(k+p+1)
On choisit de multiplier seulement à la fin par p!/2p et 
de ne calculer que la somme des n premiers termes :
| 
 | 
 | 
 
On met cette 
somme dans la variable sg, pour cela on calcule 
 (−1)k/(k+1)...(k+p+1) que l’on met dans la variable
gk :
au début sg=0 et gk=1/(p+1)! (c’est la valeur pour k=0)
 puis, on ajoute gk à la somme sg, ensuite on calcule 
(−1)11!/(p+2)! que l’on met dans gk 
(c’est la valeur pour k=1) etc...
La variable sf sert au début à calculer 
 ∑k=0n (−1)k/(k+1) puis,
sf sert à calculer la somme à rajouter
∑k=0pu0(k−1)/2
(qui vaut 1/2+1/8+1/24 pour p=3 accélerations).
Dans le programme, on utilise la variable fact pour calculer 
(p+1)! et la variable fact2 pour calculer p!/2p.
On écrit :
seriealt_sumacc(n,acc):={
local l,j,k,ls,sf,sg,gk,fact,fact2,alt,t0,p;
//calcul sans acceleration
sf:=0.0;
alt:=1;
for (k:=n;k>=0;k--) {
sf:=sf+alt/(k+1);
alt:=-alt;
}
if (alt==1) {
ls:=[-sf];} 
else {
ls:=[sf];
}
t0:=0.5;
// sf maintenant est la somme a rajouter
sf:=0.0;
fact:=1;fact2:=1;
for (p:=1;p<=acc;p++){
  sf:=sf+fact2*t0;
  //calcul de p+1! et de p!/2^p
  fact:=fact*(p+1);
  fact2:=fact2*p/2;
//sg, somme(de k=0 a n) de la serie gk acceleree p fois
  sg:=0.0;
//terme d'indice 0 (ds gk) de la serie acceleree p fois 
//(sans p!/2^p=fact2)
  gk:=1/fact;
//on conserve gk/2 dans t0 car il faut rajouter t0 
//au prochain sf 
  t0:=gk/2;
  sg:=sg+gk;
  alt:=-1;
  for (k:=1;k<=n;k++) {
     gk:=1/(k+1);
//terme d'indice k (ds gk) de la serie acceleree p fois 
//(sans p!/2^p=fact2)
     for (j:=1;j<=p;j++) {
       gk:=evalf(gk/(k+j+1));
     }
     sg:=sg+alt*gk;
     alt:=-alt;
  } 
ls:=concat(ls,sf+fact2*sg);
}
return(ls);
}
On met ce programme dans un niveau éditeur de programmes (que l’on ouvre 
avec Alt+p), puis on le teste et le valide avec OK et on tape 
dans une ligne de commandes :
seriealt_sumacc(200,3)
On obtient :
[0.69562855486,0.693153307335,0.693147210666,0.693147180781]
On tape :
seriealt_sumacc(100,4)
On obtient :
[0.698073169409,0.693171208625,0.693147412699,
0.693147183892,0.693147180623]
On cherche une approximation de :
∑n=0∞(−1)n*u(n)=sum((-1)^n*u(n),n,0,infinity)
lorsque u(n) tend vers 0 en décroissant.
On pose :
Delta(u))(n)=u(n+1)-u(n) et
delta(u,p,n)=(Delta@@p(u))(n)
On a :
delta(u,2,n)=u(n+2)-2*u(n+1)+u(n)
delta(u,3,n)=u(n+3)-3*u(n+2)+3*u(n+1)-u(n)
delta(u,p,N)=u(n+p)-comb(p,1)*u(n+p-1)+comb(p,2)*u(n+p-2)+
         ....+(-1)^p*u(n)
c’est à dire :
delta(u,p,n)=sum((-1)^(p-j)*comb(p,j)*u(n+j),j,0,p)
La transformation d’Euler consiste à écrire :
sum((-1)^n*u(n),n,N,infinity)
sous la forme :
(-1)^N*sum((-1)^p*delta(u,p,N)/2^(p+1),p,0,infinity)
Pour prouver cette égalité il suffit de développer la dernière 
expression et de chercher le coefficient de u(N+k) dans la somme :
 ∑p=0∞,(−1)p*delta(u,p,N)/2p+1
Le coefficient de u(N+k) est :
s(k)=(-1)^k*sum(comb(k+p,p)/2^(k+p+1),p,0,infinity)
et cette somme vaut (-1)^k quelque soit k entier.
En effet par récurrence :
pour k=0, comb(k+p,p)=1 et
sum(1/2^(p+1),p,0,infinity)=1/2+1/4+...1/2^n+...=1
On a de plus :
- pour p=0, comb(k+p,p)=comb(k+1+p,p)=1
- pour p>0, comb(k+p,p)=comb(k+1+p,p)-comb(k+1+p-1,p-1)
donc
s(k)=(-1)^k*sum(comb(k+1+p,p)/2^(k+p+1),p,0,infinity)-
(-1)^k*sum(comb(k+1+p-1,p-1)/2^(k+1+p-1+1),p,1,infinity)=
-2*s(k+1)-
(-1)^k*sum(comb(k+1+p,p)/2^(k+1+p+1),p,0,infinity)=
-2*s(k+1)+s(k+1)=-s(k+1).
donc si s(k)=(-1)^k alors s(k+1)=(-1)^(k+1).
La transformation d’Euler permet une accélération de convergence car 
la série :
sum((-1)^p*delta(u,p,N)/2^(p+1),p,0,infinity)
converge plus rapidement.
On définit, tout d’abord, la fonction delta :
delta(u,p,n):={
  local val,k,s;
  val:=0;
  s:=1;
  for (k:=p;k>=0;k--) {
  val:=val+comb(p,k)*u(n+k)*s;
  s:=s*-1;
  }
  return val;
};
On écrit la transforpmation d’Euler :
trans_euler(u,N,M) qui approche
sum((-1)^n*u(n),n,0,infinity) et vaut :
sum((-1)^n*u(n),n,0,N-1)+
(-1)^N*sum((-1/2)^p*delta(u,p,N)/2,p,0,M).
trans_euler(u,N,M):={
  local S,T,k,s;
  S:=0;
  s:=1;
  for (k:=0;k<N;k++) {
  S:=S+u(k)*s; 
  s:=s*-1;
  }
  T:=0;
  s:=s*1/2;
for (k:=0;k<=M;k++) {
  T:=T+delta(u,k,N)*s; 
  s:=s*-1/2;
};
  return evalf(normal(S+T));
};
Par exemple pour u(n)=1/(n+1) avec 20 digits, on tape :
u(n):=1/(n+1);
DIGITS:=20;
trans_euler(u,10,20);
On obtient :
0.693147180559945056511
trans_euler(u,9,21);
On obtient :
0.693147180559945594072
 On remarque que l’on a 16 decimales exactes car on a :
evalf(ln(2))=0.693147180559945309415
La méthode présentée dans cette section est trés largement inspirée par le texte "Sommation de séries alternées" de l’épreuve de modélisation de l’agrégation de mathématiques (session 2006).
On veut évaluer la somme S de la série alternée :
S=∑n=0∞(−1)nan
avec (an)n≥ 0 est une suite de nombres positifs qui tend vers 0 en 
décroissant.
On suppose que l’on a pour n≥ 0 :
a−n=∫01xndµ
où µ est une mesure positive sur [0,1].
C’est en particulier le cas si an=A(n) avec A fonction indefiniment 
dérivable pour laquelle les kième dérivées A(k) sont telles que
(−1)k*A(k)(x) soit positif pour x≥ 0 pour tout k≥ 0.
Théorème :
Soit Pn une suite de polynômes de degré n vérifiant 
Pn(−1)≠ 0.
À Pn, on associe les coefficients cn,k pour 0 ≤ k<n définis 
par :
 Pn(−1)−Pn(x)/1+x=∑k=0n−1cn,kxk
et le coefficient dn défini par :
dn=Pn(−1)
Soient S=∑k=0∞(−1)kak 
et  Sn=1/dn∑k=0n−1cn,kak
Alors :
 |S−Sn|≥ supx ∈ [0,1] |Pn(x)|/|dn|S
On a, en effet, avec l’hypothèse faite sur les ak :
 S=∫01 1/1+xdµ et
 S−Sn=∫01Pn(x)/dn(1+x)dµ
Pour calculer S il reste à choisir la suite des polynômes Pn.
On peut choisir :
^n+(3-sqrt(8))^n)/2;//n=nombres de termes et a fonction definissant a(n)
//S_n(P_n) =seriealt(n,a) 
//S_n(P_n) approche sum((-1)^k*a(k),k,0,+infinity)
//avec P_n=poly de chebyshev
seriealt1(n,a):={
local k,d,c,p,S;
d:=((3+sqrt(8))^n+(3-sqrt(8))^n)/2;
p:=1;
c:=d-p;
S:=a(0)*c;
for (k:=1;k<n;k++) {
p:=p*(k+n-1)*(k-n-1)/(k-1/2)/k;
c:=-p-c;
S:=S+a(k)*c;
}
return evalf(S/d);
};
^n;//n=nombres de termes et a fonction definissant a(n)
//S_n(P_n) =seriealt(n,a) 
//S_n(P_n) approche sum((-1)^k*a(k),k,0,+infinity)
//avec P_n(x)=poly (1-x)^n
seriealt2(n,a):={
local k,d,c,p,S;
d:=2^n;
p:=1;
c:=d-p;
S:=a(0)*c;
for (k:=1;k<n;k++) {
p:=p*(k-n-1)/k;
c:=-p-c;
S:=S+a(k)*c;
}
return evalf(S/d);
};
^q*2^2q;//n=nombres de termes et a fonction definissant a(n)
//S_n(P_n) =seriealt(n,a) 
//S_n(P_n) approche sum((-1)^k*a(k),k,0,+infinity)
//avec P_n=poly de chebyshev
seriealt3(n,a):={
local k,d,c,p,q,S;
q:=ceil(n/3);
n:=3*q;
d:=(-1)^q*2^(2*q);
p:=0;
c:=d-p;
S:=a(0)*c;
for (k:=1;k<q;k++) {
c:=-p-c;
S:=S+a(k)*c;
}
p:=1;
c:=-c-p;
S:=S+a(q)*c;
for (k:=q+1;k<n;k++) {
p:=p*(k-n-1)/(k-q);
c:=-p-c;
S:=S+a(k)*c;
}
return evalf(S/d);
};
On choisit n=20.
On tape :
evalf(2/(3+sqrt(8))^20,2^-20,3^-21)=
9.77243031253e-16,9.53674316406e-07,9.55990663597e-11
On a donc pour n=20 une approximation en 10−15 pour Chebyshev, en 
10−6 pour (1−x)20 et en 10−10 pour x7(1−x)14 :
On choisit dans la suite Digits:=20
Pour calculer une approximation de π/4.
On a :
sum((-1)^n/(2*n+1),n,0,+infinity)=pi/4
On tape :
b(n):=1/(2*n+1)
seriealt1(20,b);evalf(pi/4)
On obtient :
0.785398163397448309926, 0.785398163397448309615
On tape :
seriealt2(20,b);seriealt3(20,b);
On obtient :
0.785397981918786731599, 0.785398163413201025973
Pour calculer une approximation de ln(2).
On a :
sum((-1)^n/(n+1),n,0,+infinity)=ln(2)
On tape :
a(n):=1/(n+1)
seriealt1(30,a);evalf(ln(2))
On obtient :
0.693147180559945311245, 0.693147180559945309415
On tape :
seriealt2(20,a);seriealt3(20,a);
On obtient :
0.693147137051028936275, 0.693147180577738915258
On a l’identité formelle :
∑n ≥ 1an=∑m ≥ 1(−1)m−1bm avec
bm=∑k ≥ 0 2k a2km.
En effet, si n0 est un entier il existe un entier p0 et un entier impair 
m0 uniques vérifiant n0=2p0*m0 .
Dans la somme ∑m ≥ 1(−1)m−1∑k ≥ 0 2k a2km on 
cherche le coefficient de an0, on a soit :
k=0 et m=n0=m0*2p0, soit
k=1 et m=m0*2p0−1, soit
................ soit
k=p0 et m=m0.
 On remarquera que toutes les valeurs, sauf la dernière, de m sont 
paires, donc les différentes valeurs de (1)m−1 sont 
(-1) sauf la dernière qui vaut +1.
∑m ≥ 1∑k ≥ 0 (−1)m−12k a2km=
∑n0 ≥ 1an0*(∑k=0p0−1(−1)*2k+2p0)=
∑n ≥ 1an puisque 2p0−∑k=0p0−12k=1
Prenons comme exemple la série de terme général an=1/ns avec 
s>1.
pour s=2
si a(n)=1/n^2
on a :
2^k*a(2^k*m)=1/(2^k*m^2)
b(m)=1/m^2*sum(1/2^k,k,0,+infinity)=2/m^2
pour s quelconque
si a(n)=1/n^s
On a 2^k*a(2^k*m)=1/(2^(k*(s-1))*m^s)
b(m)=1/m^s*sum((1/2^(s-1))^k,k,0,+infinity)
Donc :
b(m)=2^(s-1)/((2^(s-1)-1)*m^s)
pour s=2
b(m):=2/(m^2)
pour s=4
b(m):=8/(7*m^4)
On a :
sum((-1)^(m-1)*b(m),1,+infinity)=
sum((-1)^(m)*b(m+1),0,+infinity)
On choisit encore Digits:=20
pour s=2, ∑n=1∞1/n2=π2/6
On tape :
t2(m):=2/(m+1)^2
seriealt1(20,t2),evalf(pi^2/6)
On obtient :
1.64493406684822645248, 1.64493406684822643645
On tape :
seriealt2(20,t2);seriealt3(20,t2);
On obtient :
1.64493374613777534516, 1.64493406688805599300
pour s=4, ∑n=1∞1/n4=π4/90
On tape :
t4(m):=8/(7*(m+1)^4)
seriealt1(20,t4);evalf(pi^4/90)
On obtient :
1.08232323371113822384, 1.08232323371113819149
On tape :
seriealt2(20,t4);seriealt3(20,t4);
On obtient :
1.08232265198912440013, 1.08232323371697925335
Pour calculer une approximation de la constante d’Euler, (voir aussi 15.2.3 
et 13.5.2).
γ=-psi(1).
On a :
-psi(1)=sum((-1)^n*ln(n)/n,n,1,+infinity)/ln(2)+ln(2)/2
et
sum((-1)^n*ln(n)/n,n,1,+infinity)=
-sum((-1)^n*ln(n+1)/(n+1),n,0,+infinity)
c(n):=log(n+1)/(n+1)
-seriealt1(20,c)/ln(2)+ln(2)/2;-evalf(psi(1),0)
On obtient :
0.577215664901532859864, 0.57721566490153
On tape :
-seriealt2(20,c)/ln(2)+ln(2)/2,-seriealt3(20,c)/ln(2)+ln(2)/2
On obtient :
0.577215550220266823551, 0.577215664918305723256
On tape :
Digits:=24;
evalf(euler_gamma)
On obtient : 0.5772156649015328606065119
Définition
Le nième polynômes de Bernstein associé à f continuesur [0,1] est :
| Bn(f)(t)= | 
 | comb(n,p)f( | 
 | )(1−t)n−ptp | 
Théorème
Si f est continue la suite Bn(f) converge uniformément vers f dans 
I=[0,1].
bernstein(f,n,t) approche uniformement f continue sur [0,1].
On tape :
bernstein(f,n,t):={
retourne sum(comb(n,p)*f(p/n)*(1-t)^(n-p)*t^p,p=0..n);
  }:;
bernab(f,n,t,a,b) approche uniformement f continue sur [0,1].
On tape :
bernab(f,n,t,a,b):={
 retourne  sum(comb(n,p)*f(a*(1-p/n)+b*p/n)*(b-t)^(n-p)*(t-a)^p/(b-a)^n,p=0..n)
   }:;
On tape :
plotfunc([bernstein(sin,12,x),sin(x)],x)
On obtient :
Un graphe proche de sin(x) sur 0,1
On tape :
plotfunc([bernstein(sin,12,x,-pi/2,pi/2),sin(x)],x)
On obtient :
Un graphe proche de sin(x) sur -pi/2,pi/2
Un développement asymptotique est une généralisation d’un développement de Taylor, par exemple lorsque le point de développement est en l’infini. De nombreuses fonctions ayant une limite en l’infini admettent un développement asymptotique en l’infini, mais ces développements sont souvent des séries qui semblent commencer par converger mais sont divergentes. Ce type de développement s’avère néanmoins très utile lorsqu’on n’a pas besoin d’une trop grande précision sur la valeur de la fonction.
Nous allons illustrer ce type de développement sur un exemple, la fonction exponentielle intégrale, définie à une constante près par
| f(x)= | ∫ | 
 | 
 | dt | 
On peut montrer que l’intégrale existe bien, car l’intégrand est positif et inférieur à 
e−t (qui admet −e−t comme primitive, cette primitive ayant une limite en 
+∞).
Pour trouver le développement asymptotique de f en +∞, on effectue 
des intégrations par parties répétées, en intégrant l’exponentielle 
et en dérivant la fraction rationnelle :
| 
 | 
où
| S(x)=e−x | ⎛ ⎜ ⎜ ⎝ | 
 | − | 
 | + | 
 | + ... + | 
 | ⎞ ⎟ ⎟ ⎠ | , R(x)=− | ∫ | 
 | 
 | dt (1) | 
Le développement en séries est divergent puisque pour x>0 fixé et n tendant vers l’infini
| 
 | 
 | = +∞ | 
mais si x est grand, au début la série semble converger, de manière très rapide :
| 
 | >> | 
 | >> | 
 | 
On peut utiliser S(x) comme valeur approchée de f(x) pour x grand si on sait majorer R(x) par un nombre suffisamment petit. On a
| | R(x) | ≤ | ∫ | 
 | 
 | = | 
 | 
On retrouve une majoration du type de celle des séries alternées, l’erreur est inférieure à la valeur absolue du dernier terme sommé. Pour x fixé assez grand, il faut donc de trouver un rang n, s’il en existe un, tel que n!/xn<є où є est la précision relative que l’on s’est fixée. Par exemple, si x≥ 100, n=12 convient pour є=12!/10012=5e−16 (à peu près la précision relative d’un “double”).
Pour d’autres méthodes concernant le calcul approché de la constante d’Euler voir aussi
13.3.4 et 15.2.3.
On peut montrer que
| 
 | un, un= | 
 | 
 | − ln(n) (2) | 
existe (par exemple en cherchant un équivalent de un+1−un qui vaut −1/2n2) et on définit γ comme sa limite. Malheureusement, la convergence est très lente et cette définition n’est pas applicable pour obtenir la valeur de γ avec une très grande précision. Il y a un lien entre γ et la fonction exponentielle intégrale (définie par f(x)=∫x+∞ e−t/t dt) , plus précisément lorsque x→ 0, f(x) admet −ln(x) comme singularité, plus précisément f(x)+ln(x) admet un développement en séries (de rayon de convergence +∞), car :
| 
 | 
Que vaut la constante du membre de droite :
| C= | ∫ | 
 | (e−t−1) | 
 | dt + | ∫ | 
 | e−t | 
 | dt | 
Il se trouve que C=−γ (voir plus bas une démonstration condensée) et donc :
| γ= | ∫ | 
 | 
 | dt −f(x)−ln(x) (3) | 
Pour obtenir une valeur approchée de γ, il suffit donc de prendre un 
x assez grand pour pouvoir calculer f(x) par son développement 
asymptotique à la précision requise (f(x)S(x)+R(x) avec 
S(x)=e−x(1/x−1/x2 + 2/x3+...+(−1)n n!/xn+1) et R(x)=− ∫x+∞ (−1)n n!e−t/tn+1  dt  et |R(x)|≤ n!e−x/xn+1), puis de calculer l’intégrale du membre de 
droite par le développement en séries en x=0 (en utilisant une 
précision intermédiaire plus grande puisque ce développement en séries 
va sembler diverger au début avant de converger pour n suffisamment grand).
Exemple1 : on pose x=13.
On calcule f(13) par (1)
avec n=13 et une erreur absolue inférieure à e−13 13!/1314≤ 3.6e−12.
On a en effet pour x=x0 si vn=e−x0n!/x0n+1 :
vn/vn−1≤ 1 équivalent à n/x0≤ 1équivalent 
à n≤ x0.
 Donc si x=x0=13 on calcule f(13) avec :
f(13)≃ ∑n=013 e−13(−1)n n!/xn+1
Ou bien, on tape :
Digits:=2; puis
exp(-13)*n!/13.^(n+1))$(n=0..20) renvoie :
1.7e-07,1.3e-08,2.1e-09,4.7e-10,1.5e-10,5.6e-11,2.6e-11,
1.4e-11,8.6e-12,5.9e-12,4.6e-12,3.9e-12,3.6e-12, 3.6e-12,
3.8e-12,4.4e-12,5.5e-12,7.1e-12,9.9e-12,1.4e-11,2.2e-11
donc
exp(-13)*sum((-1)^n*n!/13.^(n+1),n=0..13)
puis on remplace dans (3), avec
| ∫ | 
 | 
 | dt = | 
 | (−1)n | 
 | 
dont on obtient une valeur approchée, en faisant la somme jusqu’au rang 49, 
le reste de cette somme R50 est positif et est inférieur à 
13.^51/51/51!) qui est de l’ordre de 8.2e-12. 
On a en effet si vn=13n+1/(n+1)(n+1)! :
|RN|=∑n=N+1∞vn<vn+1=13N+2/(N+2)(N+2)!
et |R49|<8.2e−12. 
evalf(sum((-1)^n*13^(n+1)/(n+1)/(n+1)!,n=0..49))
La somme argument de evalf étant exacte, il n’y a pas de problèmes 
de perte de précision.
On obtient finalement comme valeur approchée de γ
-exp(-13)*sum((-1)^n*n!/13.^(n+1),n=0..13)-ln(13.)+evalf(  sum((-1)^n*13^(n+1)/(n+1)/(n+1)!,n=0..49))
On choisit alors 12 chiffres significatif et on tape :
Digits:=12;
f13:=exp(-13.)*evalf(sum((-1)^n*n!/13^(n+1),n=0..13))
I13:=evalf(sum((-1)^*13^(n+1)/(n+1)/(n+1)!,n=0..49))
La constante d’Euler vaut donc à 1.2e-11 près :
-f13-ln(13.)+I13
On obtient :
0.577215664897
On tape :
evalf(euler_gamma)
On obtient :
0.5772156649018
soit 0.57721566489 avec une erreur inférieure à 1.2e-11.
Exemple2 : on pose x=40.
On tape :
r40:=(exp(-40.)*40!/40.^41) on obtient r40 inférieur à 7.2e-36
On choisit alors 36 chiffres significatif et on tape :
Digits:=36;
f40:=exp(-40.)*evalf(sum((-1)^n*n!/40^(n+1),n=0..40))
puisque :
40.^168/168./168! est inférieur à 3.3e-36, on tape :
I40:=evalf(sum((-1)^n*40^(n+1)/(n+1)/(n+1)!,n=0..166))
La constante d’Euler vaut donc à (7.2+3.3)e-36 près:
-f40-ln(40.)+I40
On obtient avec une erreur inférieure à 1.1e-35:
0.5772156649015328606065120900824024285
On tape :
evalf(euler_gamma)
On obtient :
0.5772156649015328606065120900824024308
Remarques
La somme argument de evalf
étant exacte, il n’y a pas de problèmes de perte de précision,
on peut aussi faire les calculs intermédiaires en arithmétique approchée,
lorsque x=13 on doit alors prendre 4 chiffres significatifs de plus
(pour tenir compte de la valeur du plus grand terme
sommé dans la série vn=13n+1/(n+1)(n+1)! 
qui est v10=13^11/11/11!\simeq 4.08e+03).
On a en effet :
vn/vn−1=13*n/(n+1)2>1 si n2+11n+1>0 i.e. n≤ 10 et
vn/vn−1=13*n/(n+1)2<1 si n≥ 11
On tape avec des calculs intermédiaires en arithmétique approchée :
Digits:=16; sum((-1)^n*13.^(n+1)/(n+1)/(n+1)!,n=0..49)
On obtient dans ce cas comme valeur approchée de γ :
0.57721566489675213
Bien entendu, cette méthode avec des calculs intermédiaires en 
arithmétique approchée est surtout intéressante si on veut calculer
un grand nombre de décimales de la constante d’Euler c’est à dire quand 
on prend x=x0 tres grand, sinon
on peut par exemple appliquer la méthode d’accélération de Richardson 
(cf 15.2.3) à
la suite convergente (2) qui définit γ.
On peut calculer π de la même manière avec le développement 
en séries et asymptotique
de la fonction sinus intégral (on remplace exponentielle par sinus dans
la définition de f, voir plus bas une démonstration condensée) et 
l’égalité
| ∫ | 
 | 
 | dt = | 
 | (4) | 
Calcul de C (et preuve de (4)) :
Pour cela on effectue une intégration par parties, cette fois en intégrant 1/t
et en dérivant l’exponentielle (moins 1 dans la première intégrale).
| 
 | 
Pour calculer cette intégrale, on utilise l’égalité (qui se démontre par récurrence en faisant une intégration par parties) :
| n!= | ∫ | 
 | tn e−t dt | 
On va à nouveau intégrer par parties, on intègre un facteur 1 et on dérive l’intégrand, on simplifie, puis on intègre t et on dérive l’autre terme, puis t2/2, etc.
| 
 | 
où
| In= | ∫ | 
 | 
 | e−t (ln(t)−ln(n)) dt | 
Pour déterminer In on fait le changement de variables t=nu
| 
 | 
Or en faisant le même changement de variables t=nu :
| n!= | ∫ | 
 | tn e−t dt = nn+1 | ∫ | 
 | en(ln(u)−u) du | 
Donc
| In= | 
 | 
Lorsque n tend vers l’infini, on peut montrer que In → 0, en effet les intégrales
sont équivalentes à leur valeur sur un petit intervalle autour de u=1, point où l’argument
de l’exponentielle est maximal, 
et comme l’intégrand du numérateur a une amplitude ln(u) qui s’annule en u=1, 
il devient négligeable devant le dénominateur. Finalement on a bien C=−γ.
On peut remarquer qu’en faisant le même calcul que C 
mais en remplacant e−t par e−α t pour ℜ(α)>0, donne
limIn=−ln(α) (car le point critique où la dérivée
de la phase s’annule est alors 1/α). Ceci peut aussi se vérifier
pour α réel en faisant le changement de variables α t=u
| ∫ | 
 | (e−α t−1) | 
 | dt + | ∫ | 
 | e−α t | 
 | dt = −γ −ln(α) | 
En faisant tendre α vers −i, −ln(α) tend vers ln(i)=iπ/2 et on obtient
| ∫ | 
 | (eit−1) | 
 | dt + | ∫ | 
 | ei t | 
 | dt = −γ + i | 
 | 
dont la partie imaginaire nous donne (4), et la partie réelle une autre identité sur γ faisant intervenir la fonction cosinus intégral.
Dans Xcas, il existe déjà une fonction qui calcule la valeur approchée r d’une solution de f(x)=0 par la méthode de Newton, qui est : newton.
Soit f deux fois dérivable ayant un zéro et un seul r dans l’intervalle
[a ;  b]. Supposons de plus que f′ et f″ ont un signe constant sur
[a ;  b]. La méthode de Newton consiste à approcher r par l’abscisse
x1 du point commun à Ox et à la tangente en un point M0
du graphe de f. Si M0 a pour coordonées (x0,f(x0)) 
(x0 ∈ [a ;  b]), la tangente en M0 a pour équation :
y=f(x0)+f′(x0)*(x−x0) et donc on a :
| x1=x0− | 
 | 
On peut alors réitérer le processus, et on obtient une suite xn qui 
converge vers r soit par valeurs supérieures, si f′*f″>0 sur 
[a ; b] (i.e. si f′(r)>0 et si f est convexe (f″>0 sur [a ;  b])
ou si f′(r)<0 et si f est concave (f″<0 sur [a ;  b])) soit par 
valeurs inférieures, si f′*f″<0 sur [a ;  b] (i.e. si f′(r)<0 et si 
f est convexe (f″>0 sur [a ; b]) ou si f′(r)>0 et si f est 
concave (f″<0 sur [a ;  b])).
On fait le dessin en tapant :
f(x):=x*x-2; x0:=5/2; G:=plotfunc(f(x)); T0:=tangent(G,x0); Ox:=droite(0,1); M1:=inter(T0,Ox)[0]; x1:=affixe(M1) segment(point(x1,0),point(x1,f(x1))); T1:=tangent(G,x1); M2:=inter(T1,droite(0,1))[0] x2:=affixe(M2): segment(point(x2,0),point(x2,f(x2)));
ou encore pour faire le dessin de la méthode de Newton pour la fonction f en partant du point de coordonnèes (a,f(a)) et obtenir p nouveaux points.
plotnewton(f,a,p):={
local L,P,m,j,b;
L:=plotfunc(f(x),x,affichage=vert);
L:=L,point(a,couleur=point_width_4+rouge);
for (j:=1;j<=p;j++) {
b:=f(a);
L:=L,segment(a,a+i*b,couleur=ligne_tiret+rouge);
m:=function_diff(f)(a);
L:=L,plotfunc(b+(x-a)*m,x);
if (m==0){return "pente nulle"}
a:=a-f(a)/m;
P:=point(a,couleur=point_width_4+rouge);
L:=L,P;
}
return affixe(P),L;
};
On tape :
plotnewton(sq-2,4,2)
pour obtenir les termes x0,x1,x2 de la suite de Newton qui converge 
vers √2 et où x0=4 :

On remarquera que :
plotnewton(sq-2,4,2)[0]
renvoie :
113/72 ≃ 1.56944444444
On tape :
plotnewton(ln-1,5,2)
pour obtenir les termes x0,x1,x2 de la suite de Newton qui converge 
vers e et où x0=5 :

On peut aussi faire une animation, pour cela, on tape : 
newtonsuite(f,a,p):={
local L,P,m,j,b,LT;
P:=point(a,couleur=point_width_4+rouge);
LT:=P;
f1:=function_diff(f);
for (j:=1;j<=p;j++) {
b:=f(a);
L:=L,segment(a,a+i*b,couleur=ligne_tiret+rouge);
m:=f1(a);
L:=L,plotfunc(b+(x-a)*m,x);
if (m==0){return "pente nulle"}
a:=a-f(a)/m;
P:=point(a,couleur=point_width_4+rouge);
LT:=LT,[LT,L,P];
}
print(affixe(P));
return LT;
};
animnewton(f,a,p):={
local LT;
LT:=newtonsuite(f,a,p);
return plotfunc(f(x),x,affichage=vert),animation(LT);
};
On tape :
animnewton(sq-2,4,3)
Puis, on écrit la fonction newton_rac qui renvoie la valeur 
approchée à eps près de la racine de 
f(x)=0 on commençant l’itération avec x0.
On remarquera que le paramètre f est une fonction et donc, que sa 
dérivée est la fonction g:=function_diff(f).
On cherche une valeur approchée donc il faut écrire :
x0:=evalf(x0-f(x0)/g(x0))
car si on ne met pas evalf, les calculs de l’itération se feront
excactement et seront vite compliqués.
newton_rac(f,x0,eps):={
local x1,h,g;
g:=function\_diff(f)
x0:=evalf(x0-f(x0)/g(x0));
x1:=x0-f(x0)/g(x0);
if (x1>x0) {h:=eps;} else {h:=-eps;}
while (f(x1)*f(x1+h)>0){
   x1:=x1-f(x1)/g(x1);
}
return x1;
}
La solution avec Xcas

Pour montrer que l’équation f(x)=0 a deux solutions a et b qui 
vérifient a<−1<b<0, on calcule, d’après le graphe 
f(−3),f(−2),f(−1),f(0).
On tape :
f(x)$(x=-3..0)
On obtient :
0.0506387948964,-0.0706705664732,-0.167879441171,0.2
donc puisque f est continue, d’après le théorème des valeurs intermédiaires on a : −3<a<−2 et −1<b<0
Newtonvaleur(x0):={
  local j,f,g,h;
  f(x):=x*exp(x)+0.2;
  g(x):=(x+1)*exp(x);
  h(x):=x-f(x)/g(x);
  pour j de 1 jusque 5 faire
    x0:=h(x0);
  fpour;
  retourne x0;
}:;
RemarqueNewtonvalpres(x0,eps):={
  local j,g,h,t,s;
  f(x):=x*exp(x)+0.2;
  g(x):=(x+1)*exp(x);
  h(x):=x-f(x)/g(x);
  j:=0;
  t:=x0-eps;
  //s:=ifte(f(x0)>0,1,-1);
  s:=sign(f(x0));
  tantque s*f(t)>0 faire
    x0:=h(x0);
    t:=x0-eps;
    j:=j+1;
  ftantque;
  print(j);
  retourne t,x0;
}:;
On tape pour avoir la valeur de xj qui donne un encadrement de a à 
1e−6 prés :Newtonvaleura(x0,a):={
  local j,f,g,h;
  f(x,a):=x*exp(x)+a;
  g(x):=(x+1)*exp(x);
  h(x):=x-f(x,a)/g(x);
  pour j de 1 jusque 5 faire
    x0:=h(x0);
  fpour;
  retourne x0;
}:;
lorsque a=−1/e, on a f(0,a)=a<0 et f(1,a)=e−1/e>0.
On tape :Newtonimplicit():={
  local j,f,g,h,a,xj,y0,y,L;
  g(y):=(y+1)*exp(y);
  f(y,a):=y*exp(y)+a;
  pour xj de -4 jusque 0 pas 0.1 faire
  a:=xj*exp(xj);
  h(y):=y-f(y,a)/g(y);
  y0:=-a;
  pour j de 1 jusque 5 faire
    y0:=h(y0);
  fpour;
  L:=L,point(xj+i*y0);
fpour;
L:=L,point(0.28-i);
pour xj de 0.01 jusque 0.28 pas 0.02 faire
  a:=xj*exp(xj);
  h(y):=y-f(y,a)/g(y);
  y0:=0;
  pour j de 1 jusque 5 faire
    y0:=h(y0);
  fpour;
  L:=L,point(xj+i*y0);
  y0:=-2;
  pour j de 1 jusque 5 faire
    y0:=h(y0);
  fpour;
  L:=L,point(xj+i*y0)
fpour;
retourne L;
}:;
On tape Newtonimplicit()
On peut aussi vouloir calculer y à eps -près. Mais attention lorsqu’on 
part de y0=−2 on obtient une valeur soit par défaut, soit par excés selon
le signe de f(−2,a) (si f(−2,a)>0 ce sera par excès car pour x=−2 on a 
un point d’inflexion).
On tape alors :
Newtonimpl(eps):={
  local j,f,g,h,a,xj,y0,y,t,s,L;
  g(y):=(y+1)*exp(y);
  f(y,a):=y*exp(y)+a;
  L:=NULL;
  pour xj de -5 jusque 0 pas 0.05 faire
  a:=evalf(xj*exp(xj));
  h(y):=y-f(y,a)/g(y);
  y0:=-a;
  t:=y0-eps;
  s:=sign(f(y0,a));
  tantque s*f(t,a)>0 faire
    y0:=h(y0);
    t:=y0-eps;
  ftantque;
  L:=L,point(xj+i*y0);
fpour;
L:=L,point(0.28-i);
pour xj de 0.01 jusque 0.28 pas 0.02 faire
  a:=evalf(xj*exp(xj));
  h(y):=y-f(y,a)/g(y);
  y0:=0.;
  t:=y0-eps;
  s:=sign(f(y0,a));
  tantque s*f(t,a)>0 faire
    y0:=h(y0);
    t:=y0-eps;
  ftantque;
  L:=L,point(xj+i*y0);
fpour;
  pour xj de 0.01 jusque 0.28 pas 0.02 faire
    a:=evalf(xj*exp(xj));
  h(y):=y-f(y,a)/g(y);
  y0:=-2.;
  s:=sign(f(y0,a));
  si s>0  alors eps:=-abs(eps); fsi; 
  t:=y0-eps;
  tantque s*f(t,a)>0 faire
    y0:=h(y0);
    t:=y0-eps;
  ftantque;
  L:=L,point(xj+i*y0)
fpour;
retourne L;
}:;
On tape Newtonimpl(0.01)
On peut vérifier en tapant :
plotimplicit(x*exp(x)+y*exp(y),[x,y])
La solution avec Xcas
On configure Xcas avec 20 digits.
ptfixecos(x0,n):={
local j,f;
f(x):=cos(x);
pour j de 1 jusque n faire
  x0:=f(evalf(x0));
fpour;
retourne x0;
}:;
On tape : ptfixecos(0,4)Newtoncos(x0,n):={
local j,g,F,dF;
F(x):=cos(x)-x;
dF:=function_diff(F);
//g(x):=(x*sin(x)+cos(x))/(sin(x)+1);
g(x):=normal(x-F(x)/dF(x));
pour j de 1 jusque n faire
  x0:=g(evalf(x0));
fpour;
retourne x0;
}:;
On tape : Newtoncos(0,4)Aitkencos(x0,n):={
local j,gs,f,y0;
f(x):=cos(x);
gs(x):=x-(f(x)-x)*(f(x)-x)/(f(f(x))-2f(x)+x);
pour j de 1 jusque n faire
  x0:=f(evalf(x0));
  y0:=gs(x0);
fpour;
print(x0);
retourne y0;
}:;
On tape : Aitkencos(0,4)Steffensencos(x0,n):={
local j,gs,f;
f(x):=cos(x);
gs(x):=x-(f(x)-x)*(f(x)-x)/(f(f(x))-2f(x)+x);
pour j de 1 jusque n faire
  x0:=gs(evalf(x0));
fpour;
retourne x0;
}:;
On tape : Steffensencos(0,4)
Les méthodes de Newton et de Steffensen sont plus performantes car ce sont 
des méthodes d’ordre 2 (la fonction que l’on iére a une dérivée nulle 
au point solution de f(x)=cos(x)=x).
Même avec Digits:=30 on a :
Steffensencos(0,6)=Steffensencos(0,10)=
 Newtoncos(0,6)=Newtoncos(0,10)=
0.7390851332151606416553120876735
On tape :
Newton0(4)
On obtient avec 22 digits:
0.51775736368245829829471
Newton0(n):={
local j,f,f1,g,x0;
f(x):=exp(-x)*cos(x)-x;
f1:=function_diff(f);
g(x):=normal(x-f(x)/f1(x));
x0:=0.0;
pour j de 1 jusque n faire
x0:=g(x0)
fpour;
retourne x0;
}:;
Newtoneps(n,eps):={
  local j,f,f1,g,x0;
  f(x):=exp(-x)*cos(x)-x;
  f1:=function_diff(f);
  g(x):=normal(x-f(x)/f1(x));
  x0:=0.0;
  j:=0;
  tantque f(x0+eps)>0 faire
    x0:=g(x0);
    j:=j+1;
  ftantque;
  print(j);
  retourne x0,x0+eps;
}
:;
On tape :Newtonimpl():={
  local j,f,f1,g,x0,t,a,L;
  a:=evalf(pi/2);
  f(x):=exp(-x)*cos(x)-x;
  f1:=function_diff(f);
  L:=NULL;
    pour t de -a jusque -1 pas 0.1 faire
      g(x):=normal(x-(f(x)+t)/f1(x));
      x0:=0.0;
      tantque f(x0-0.01)+t<0 faire
        x0:=g(x0);
      ftantque;
      L:=L,point(t,x0);
    fpour;
    pour t de -1 jusque a pas 0.1 faire
      g(x):=normal(x-(f(x)+t)/f1(x));
      x0:=0.0;
      tantque f(x0+0.01)+t>0 faire
        x0:=g(x0);
      ftantque;
      L:=L,point(t,x0);
    fpour;
    return L;
  }
:;
On tape : 
Lorsqu’on part d’une valeur x0 trop éloignée de la racine de f(x)
(si par exemple |f(x0)| est grand),
on a intérêt à utiliser un préfacteur pour se rapprocher plus vite de 
la solution de f(x)=0.
Posons  n(x)=−f(x)/f′(x), on a alors :
| 
 | 
 | =f′(x0) | 
donc
| 
 | 
 | =n(x0)*f′(x0)=−f(x0) | 
ce qui veut dire que :
f(x0+h*n(x0))=f(x0)(1−h)+h· є(h) avec є(h) tend vers 0
quand h tend vers 0.
Donc, il existe h0 vérifiant :
|f(x0+h0*n(x0))|<|f(x0)|
Remarque : Il faut minimiser |f(x0+h0*n(x0))|. 
or plus h0 est proche de 1 et plus |f(x0)*(1−h0)| sera petit. 
Par exemple, on prendra le plus grand h0, dans la liste 
[1,3/4,(3/4)2,...] qui vérifie |f(x0+h0*n(x0))|<|f(x0)|
Pour cette valeur de h0, x0+h0*n(x0) est probablement plus 
proche de la racine que x0 : on dit que h0 est le préfacteur de la 
méthode de Newton.
On va choisir par exemple au début h0=1, et on regarde si 
|f(x0+n(x0))|<|f(x0)|,
si ce n’est pas le cas on prend h0=(3/4) et on regarde si 
|f(x0+3/4*n(x0))|<|f(x0)|,
si ce n’est pas le cas on prend h0=(3/4)2 etc...
On change de préfacteurs à chaque étape jusqu’à ce que :
abs(f(x1))−abs(f(x0))<0 sans préfacteur,
on continue alors l’itération sans préfacteur, c’est à dire avec la 
méthode de Newton normale. 
On écrit donc :
newton_prefacts(f,x0,eps):={
local x1,h,h0,prefact,niter;
//prefact est egal par ex a 3/4
h0:=1.0;
niter:=0;
prefact:=0.75;
x1:=x0-h0*f(x0)/function_diff(f)(x0);
while (abs(f(x1))-abs(f(x0))>0) {
   h0:=h0*prefact;
   x1:=x0-h0*f(x0)/function_diff(f)(x0);
} 
h:=eps;
while (h0!=1 and niter<100){
   x0:=x1;
   x1:=x1-h0*f(x1)/function_diff(f)(x1);
   while (abs(f(x1))-abs(f(x0))>0) {
      h0:=h0*prefact;
      x1:=x0-h0*f(x0)/function_diff(f)(x0);
   } 
   while (abs(f(x1))-abs(f(x0)<0 and h0!=1)) {
      h0:=h0/prefact;
      x1:=x0-h0*f(x0)/function_diff(f)(x0);
   } 
niter:=niter+1;   
}
while (f(x1-h)*f(x1+h)>0  and niter<200){
   x0:=x1;
   x1:=x1-f(x1)/function_diff(f)(x1);
   niter:=niter+1;
}
if  (niter<200) {return x1;} else {return "pas trouve";} 
}
On définit la fonction f par f(x):=x2-2 et on met ce programme 
dans un niveau éditeur de programmes (que l’on ouvre avec Alt+p), puis 
on le teste et on le valide avec OK.
 On tape :
newton_prefacts(f,100,1e-10)
On obtient :
1.41421356237
On tape :
newton_prefacts(f,3,1e-5)
On obtient :
1.41421378005
Soit f une fonction définie sur [a;b]. On suppose que f est unimodale sur [a;b], c’est à dite que f a un seul extremum sur [a;b]. On suppose de plus que cet extremum est un minimum (sinon on remplacera f par −f.) On se propose de trouver un encadrement à eps près de la valeur pour laquelle f est minimum.
On partage [a;b] en trois morceaux en considérant c et d 
vérifiant : a<c<d<b.
On calcule f(c) et f(d) et on les compare.
Puisque f a un seul minimum sur [a;b] elle décroit, passe par son 
minimum, puis f croit. Selon les trois cas possibles on a :
Ainsi, l’intervalle de recherche a diminué et on peut recommencer le processus. Pour que l’algorithme soit performant, on veut que l’intervalle de recherche diminue rapidement et que le nombre de valeurs de f à calculer soit le plus petit possible. Pour cela comment doit-on choisir c et d ?
On choisit c et d proche de a+b/2 par exemple :
 c=a+b−eps/2 et d=a+b+eps/2 pour eps donné.
Dans ce cas, à chaque étape l’intervalle diminue presque de moitié mais 
on doit calculer, à chaque étape, deux valeurs de f. 
Comment faire pour que l’une des valeurs de f déjà calculée serve 
à l’étape suivante ?
La solution se trouve dans la suite de Fibonacci, suite définie par :
u0=1, u1=2, un=un−2+un−1 dont les premiers termes sont :
1,2,3,5,8,13,21,34,55,89...
Par exemple si on partage [a;b] en 89 parties égales si l=(b−a)/89,
on choisit c=a+34*l et d=a+55*l et ainsi on a :
c−a=34*l, d−c=21*l, b−d=34*l (car 89=55+34 et 34+21=55 puisque 
21,34,55,89 sont des termes consécutifs de la suite de Fibonacci).
On calcule f(c) et f(d) puis on réduit l’intervalle en un intervalle de
longueur (b−a)*55/89, par exemple si l’intervalle suivant est [a;d] et, si 
on recommence le processus, le point c est le futur point d.
Donc à chaque étape il suffit de calculer une seule valeur de f pour
passer de l’intervalle [a;b] (proportionnel à un) à l’intervalle 
[a;d] ou [c;b] (proportionnel à un−1). Il y a bien sûr le cas 
f(c)=f(d) où il faut à l’étape suivante calculer deux valeurs de f, 
mais dans ce cas on gagne 3 étapes car on passe de l’intervalle [a;b] 
(proportionnel à un) à l’intervalle [c;d] (proportionnel à 
un−3).
Selon la valeur eps de la longueur de l’encadrement, on calcule
k:=ceil(2*(b−a)/eps); et la première valeur t=un de la suite de 
Fibonacci supérieure à k. il faut alors diviser l’intervalle [a;b] en 
t parties égales. On applique alors plusieurs fois le processus et on 
s’arrête quand n=1, c’est à dire quand l’intervalle a été réduit 
à un intervalle de longueur 2*(b−a)/t qui est, grace au choix de t 
(t>k>2*(b−a)/eps) inférieur à eps.
//f(x):=2*x^4-10*x^3-4*x^2+100
//fibomin(f,1,5,0.000001)
//g(x):=2*x^4-10*x^3+4*x^2+100
//fibomin(g,1,5,1e-20)
//calcul la valeur du min d'une fonction ayant 
//un seul extrema sur [a,b]
fibomin(f,a,b,eps):={
  local c,d,F,k,n,t,g,h,l,fc,fd;
  if (a>b) {c:=a;a:=b;b:=c;}
  k:=ceil(2*(b-a)/eps);
  F:=1,2;
  n:=1;
  g:=1;
  t:=2;
  //construction de F=la suite de Fibonacci
  //h,g,t sont 3 termes consecutifs de F
  while (t<k) {
    n:=n+1;
    h:=g;
    g:=t;
    t:=h+g;
    F:=F,t;
  }
  l:=(b-a)/t;
  c:=a+h*l;
  d:=a+g*l;
  fc:=f(c);
  fd:=f(d);
  //on itere le processus et on s'arrete qd n=1
  while (n>1) {
    if (fc>fd) {
      a:=a+h*l;
      fc:=fd;
      t:=h;
      h:=g-h;
      g:=t;
      fd:=f(a+g*l);
      n:=n-1;
    }else{
      if (fc<fd) {
 b:=a+g*l;
 t:=h;
 h:=g-h;
 g:=t;
 fd:=fc;
 fc:=f(a+h*l);
 n:=n-1;
      }else{
 a:=a+h*l;
 b:=b-h*l;
 t:=g-h;
 g:=h-t;
 h:=t-g;
 fc:=f(a+h*l);
 fd:=f(a+g*l);
 n:=n-3;
      }
    }
  }
  return [a,b];
}
On tape :
f(x):=x^4-10
fibomin(f,-1,1,1e-10)
On obtient :
[(-1)/53316291173,1/53316291173]
On tape :
g(x):=2*x^4-10*x^3-4*x^2+100
fibomin(g,1,5,1e-10)
On obtient :
[86267571271/21566892818,86267571273/21566892818]
On tape :
h(x):=2*x^4-10*x^3+4*x^2+100
fibomin(h,1,5,1e-10)
On obtient :
[74644573011/21566892818,74644573013/21566892818]
 
 
