> restart;
VII.1
>
fibo1:=proc(n::integer)
local resultat,u,v,k,garage;
#Initialisation
u:=1;v:=1;
#Calcul des termes successifs
if n=0 then resultat:=u
elif n=1 then resultat:=v
else for k from 2 to n
do
garage:=v;
v:=u+v;
u:=garage;
resultat:=v;
od;
fi;
# On peut arranger la procédure et supprimer # resultat.
resultat;
end;
> fibo1(1);
> fibo1(9);
>
fibo2:=proc(n::integer)
option remember;
if n=0 then 1
elif n=1 then 1
else fibo2(n-1)+fibo2(n-2)
fi;
end;
> fibo2(9);
> restart;
VII.2
Par un procédé itératif
>
Tn_2:=1:Tn_1:=X:
for k from 2 to 11
do
T:=2*X*Tn_1-Tn_2;
garage:=Tn_1;
Tn_1:=T;Tn_2:=garage;
od:
> collect(T,X);
Avec l'option remembe r
>
T:=proc(n::integer)
option remember;
if n=0 then 1
elif n=1 then X
else sort(simplify(2*X*T(n-1)-T(n-2)))
fi;
end;
> T(11);
> time(T(50));
> time(T(100));
> time(T(200));
> time(T(200));
> time(T(210));
> restart;
Sans l'option remembe r
>
T2:=proc(n::integer)
if n=0 then 1
elif n=1 then X
else sort(simplify(2*X*T2(n-1)-T2(n-2)))
fi;
end;
> T2(11);
> time(T2(25));
> restart;
VII.3
>
binom:=proc(n::integer,k::integer)
option remember;
if k>n then 0
elif k=0 or k=n then 1
else binom(n-1,k)+binom(n-1,k-1);
fi;
end;
> binom(10,2);
> binomial(10,2);
> restart;
VII.4
On commence par écrire une procédure qui calcule la somme de tous les diviseurs propres d'un entier n.
>
`somme des diviseurs`:=proc(n::integer)
local s,i;
s:=1;
for i from 2 to n-1
do
if irem(n,i)=0
then s:=s+i
fi
od;
s;
end;
>
amiable:=proc(n::integer)
local i,j,sol; # On va créer une séquence de liste qui seront les
solutions.
sol:=NULL; # initialisation de la séquence à vide
for i from 3 to n # boucle pour parcourir tous les entiers
do
j:=`somme des diviseurs`(i); # Le seul candidat pour être amiable avec i
est j
if j>=i
and # Pour éviter d'avoir 2 fois la même
solution
`somme des diviseurs`(j)=i
then sol:=sol,[i,j];
fi
od;
sol;
end;
> amiable(30);
> amiable(300);
> amiable(1500);
> restart;
VII.5
> sum(1/k,k=1..100);
> S:=0: for k to 100 do S:=S+1/k od: S;
> A:=5;
> for n while (sum(1/'k','k'=1..n)<A) do od; n; # Mauvaise méthode. À chaque étape, on recalcule toute la somme, alors qu'à chaque étape il suffit d'ajouter 1/k.
> S:=0: for n while S<A do S:=S+1/n od: n-1;
>
> A:=7;
>
for n while (sum(1/'k','k'=1..n)<A) do od; n;
# Mauvaise méthode. À chaque étape, on recalcule toute la somme, alors
qu'à chaque étape il suffit d'ajouter 1/k.
> S:=0: for n while S<A do S:=S+1/n od: n-1;
> restart;
VII.6
1. Calcul de Sn pour de grandes valeurs de n :
> Sn:=sum(1/k!,k=0..n);
> subs(n=100,Sn);
> evalf(%);
On fait la conjecture que la limite cherchée est e
2. Calcul direct de l'erreur :
> n:=100;d:=floor(log10(n!));
> Digits:=d+6;
> A100:=evalf(exp(1)-sum(1/k!,k=0..100));
3. Calcul de l'erreur par une méthode itérative :
> s:=1: for k from 100 to 1 by -1 do s:=1+(1/k)*s od:
> evalf(exp(1)-s);
4. Comparaison des deux méthodes :
>
A1:=proc(n) local d,k;
d:=floor(log10(n!)); Digits:=d+6;
evalf(exp(1)-sum(1/k!,k=0..n));
end;
>
A2:=proc(n) local d,s,k;
d:=floor(log10(n!)); Digits:=d+6;
s:=1:
for k from n to 1 by -1 do s:=1+(1/k)*s od:
evalf(exp(1)-s);
end;
> A1(255);
> A2(255);
> time(A2(255));
> time(A1(255));
>
Pas le même temps de calcul.