TD 3 Eléments de programmation, suites numériques et fonction Zeta

I. Les instructions conditionnelles et les boucles

Pour exécuter des instructions répétitives sur une suite de valeurs repérées par un indice, on a la structure suivante :

for i from début by pas to fin

do
suite d'instructions ;
od ;

Exemple

> somme:=0;for i from 1 to 10 do somme:=somme+i*i;od;

somme := 0

somme := 1

somme := 5

somme := 14

somme := 30

somme := 55

somme := 91

somme := 140

somme := 204

somme := 285

somme := 385

Veuillez noter la syntaxe de l'exemple donné ci-dessus. Que se passe-t-il quand on remplace la dernière ligne par od :

Les nombres de Fibonacci sont définis par la relation de récurrence suivante

F0=0 F1=1 Fn=Fn-1+Fn-2 pour n>2
Calculer avec une boucle
for les valeurs de F3 à F10.

Rappel: || est l'opérateur de concaténation et peut être utilisé pour définir des variables successives dans une boucle.

> F0:=0;F1:=1;

F0 := 0

F1 := 1

> for i from 2 to 10 do F||i:=F||(i-1)+F||(i-2);od;

F2 := 1

F3 := 2

F4 := 3

F5 := 5

F6 := 8

F7 := 13

F8 := 21

F9 := 34

F10 := 55

>

La boucle while:

Pour répéter une séquence d'instructions tant qu'une condition est vraie, on a la structure suivante :

while condition

do
suite d'instructions ;
od ;

En reprenant l'exemple des nombres de Fibonacci déterminer la plus grande valeur de n telle que Fn<200.

> F0:=0;F1:=1;i:=1;

F0 := 0

F1 := 1

i := 1

> i:=1;while (F||i < 200) do F||(i+1):=F||i+F||(i-1);print(i,F||i);i:=i+1;od:

i := 1

1, 1

2, 1

3, 2

4, 3

5, 5

6, 8

7, 13

8, 21

9, 34

10, 55

11, 89

12, 144

Les instructions conditionnelles sont définies par la séquence suivante
if condition then
suite d'instructions 1 ;
else
suite d'instructions 2 ;
fi ;
Si la condition est vraie, la suite d'instructions 1 est exécutée, sinon la suite d'instructions 2 l'est.
Dans le cas où une séquence de choix est supérieure à 2, la syntaxe est la suivante
if condition then
suite d'instructions 1 ;
elif condition2 then
suite d'instructions 2 ;
elif condition3 then
suite d'instructions 3 ;

else
suite d'instructions n
fi ;

II Les procédures

Nous avons un moyen de définir des fonctions simples.

Par exemple, f := x-> x^2+1 ; définit une fonction f qui pour toute valeur de x associe la valeur x^2+1 .

Il est parfois nécessaire de définir des fonctions comprenant des instructions conditionnelles et/ou des boucles.

La structure d'une procédure est la suivante :


proc (suite de variables)
local suite de variables locales ;
options suite d'options ;
instruction1 ;
instruction2 ;
¯
instruction n ;
end ;

L'instruction
local permet de définir des variables durant le temps de l'exécution de la procédure et qui disparaissent une fois la procédure terminée. Cette instruction n'est présente que si des variables supplémentaires sont nécessaires à l'exécution de la procédure.
Reprenons la fonction donnée ci-dessus, on a alors la suite d'instructions suivantes
f:=proc(x)
x^2+1 ;
end;

Pour les nombres de Fibonacci, on peut définir la procédure suivante

> Fib:=proc(n::nonnegint)
if n=0 then 0

> elif n=1 then 1

> else Fib(n-1)+Fib(n-2)fi
end ;

Fib := proc (n::nonnegint) if n = 0 then 0 elif n =...

La directive negposint signifie que la procédure n'accepte comme variables d'entrée que des nombres entiers positifs ou nuls.

Attention, cette fois-ci Fib est une procédure et non pas une suite de nombres comme dans l'exemple précédent.

Calculer Fib(30) à partir de cette procédure. Que remarque-t-on ?
Ajouter l'option
remember dans la procedure et calculer Fib(40).

> Fib(10);

55

> Fib:=proc(n::nonnegint)
option remember;
if n=0 then 0

> elif n=1 then 1

> else Fib(n-1)+Fib(n-2)fi
end ;

Fib := proc (n::nonnegint) option remember; if n = ...
Fib := proc (n::nonnegint) option remember; if n = ...
Fib := proc (n::nonnegint) option remember; if n = ...
Fib := proc (n::nonnegint) option remember; if n = ...

> Fib(40);

102334155

Ecrire une procédure qui définit les polynômes de Legendre qui satisfont la relation de récurrence suivante
Leg[0](x) = 1 , Leg[1](x) = x

Leg[n](x) =((2n-1) x Leg[n-1](x) -(n-1) Leg[n-2](x) )/n

> Leg:=proc(n::nonnegint,x)
option remember;

> if n=0 then 1

> elif n=1 then x

> else expand(((2*n-1)*x*Leg(n-1,x)-(n-1)*Leg(n-2,x))/n) fi

> end;

Leg := proc (n::nonnegint, x) option remember; if n...
Leg := proc (n::nonnegint, x) option remember; if n...
Leg := proc (n::nonnegint, x) option remember; if n...
Leg := proc (n::nonnegint, x) option remember; if n...
Leg := proc (n::nonnegint, x) option remember; if n...
Leg := proc (n::nonnegint, x) option remember; if n...
Leg := proc (n::nonnegint, x) option remember; if n...

> Leg(12,x);

676039/1024*x^12-969969/512*x^10+2078505/1024*x^8-2...

>

En utilisant la bibliothèque des polynomes orthogonaux, vérifier les résultats obtenus sur les polynomes de Legendre.

> with(orthopoly):

> P(12,x);

676039/1024*x^12-969969/512*x^10+2078505/1024*x^8-2...

III Suites numériques

Pour une fonction FF , on considère la suite x[n] définie par x[0] = -.5 et x[n+1] = FF(x[n])
Soit
FF(x) = x^2+.1875

Definissez les 10 premières valeurs de x[n] l'aide d'une boucle. Rangez les valeurs dans x.i pour i=1 à 10.

> FF:=x->x^2+0.1875;

FF := proc (x) options operator, arrow; x^2+.1875 e...

> x0:=-0.5;

x0 := -.5

> for i from 1 to 10 do

> x||i:=(FF(x||(i-1)));

> od;

x1 := .4375

x2 := .37890625

x3 := .3310699463

x4 := .2971073093

x5 := .2757727532

x6 := .2635506114

x7 := .2569589248

x8 := .2535278890

x9 := .2517763905

x10 := .2508913508

Visualisation de la convergence de la suite.
La liste de points à construire dans cet exercice est de la forme
listeP := [[x[0], x[0]], [x[0], x[1]], [x[1], x[1]]... . On souhaite aussi tracer le graphe y=FF(x), la suite listeP ainsi que la diagonale y=x. en utilisant la commande plot . Pour déterminer la fenêtre de visualisation, on calculera la plus grande valeur et la plus petite valeur de la suite des x avec les instructions min et max .

> res:=seq(op([[x||i,x||i],[x||i,x||(i+1)]]),i=0..9);

res := [-.5, -.5], [-.5, .4375], [.4375, .4375], [....
res := [-.5, -.5], [-.5, .4375], [.4375, .4375], [....
res := [-.5, -.5], [-.5, .4375], [.4375, .4375], [....
res := [-.5, -.5], [-.5, .4375], [.4375, .4375], [....
res := [-.5, -.5], [-.5, .4375], [.4375, .4375], [....
res := [-.5, -.5], [-.5, .4375], [.4375, .4375], [....

> xmin:=min(seq(x||i,i=0..9));xmax:=max(seq(x||i,i=0..9));

xmin := -.5

xmax := .4375

> plot([[res],FF(x),x],x=xmin..xmax,color=[blue,red,green]);

[Maple Plot]

Créer une procédure dessin dont les variables d'entrée seront le nombre de points, la condition initiale x[0] , le nom de la fonction et dont la sortie sera un graphique. Tester cette procédure pour les conditions intiales x[0] suivantes: en premier x[0] =0, puis x[0] =-0.5

> dessin:=proc(n,y,f)

> local x0,i,res,xmin,xmax;

> x||0:=y;

> for i from 0 to n-1 do x||(i+1):=f(x||i); od;
xmin:=min(seq(x||i,i=0..n));
xmax:=max(seq(x||i,i=0..n));

> res:=seq(op([[x||i,x||i],[x||i,x||(i+1)]]),i=0..n-1);

> plot([[res],f(x),x],x=xmin..xmax,color=[blue,red,green]);

> end;

dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...
dessin := proc (n, y, f) local x0, i, res, xmin, xm...

> dessin(10,0.3,FF);

[Maple Plot]

> dessin(10,-0.5,FF);

[Maple Plot]

En utilisant la procédure dessin, visualiser les suites pour la fonction 1-x^2 pour les conditions initiales x[0] =-0.7 et x[0] =-1.618

> FF1:=x->1-x^2;

FF1 := proc (x) options operator, arrow; 1-x^2 end ...

> dessin(20,0.6,FF1);

[Maple Plot]

> dessin(20,-1.618,FF1);

[Maple Plot]

IV Programmation évoluée: affectation multiple, apprendre à copier, modules...

Une possibilité intéressante de Maple est de permettre les affectations simultanées L'opérateur correspondant est la paire de parenthèses.

Par ex: a1:=9; a2:=13;;
(a1,a2):=(a2,a1);
Vérifier la valeur de chacune des variables après cette opération.

Soit maintenant les variables a3:=6;a4:=-7;

Donner en une ligne l'instruction qui affecte la valeur de a4 à a1, de a3 à a2, a1 à a3 et a2 à a4.

Vérifier le résultat. Commenter.

Une façon politiquement incorrecte pour apprendre à programmer consiste à copier ce que vos brillants prédécesseurs ont fait. (Cela peut vous laisser rêveur pour les concours!). Maple permet et encourage ce type de pratique, qui est très utile pour progresser rapidement.

L'instruction interface(verboseproc=2) associée à l'instruction eval vous permet de connaître la manière dont les instructions de Maple sont écrites.

Ecrire:

interface(verboseproc=2);

with(combinat);

eval(fibonacci);

Afficher le code Maple pour les nombres de Bernouilli.

>

Les modules sont un ensemble de procédures avec la notion de variables à exporter et la notion de variables locales.

Ex:

> fonc:=module()

> export integre,suite,trace;

> suite:=proc(n,a,b,f) local i;

> seq(f(a+i*(b-a)/n),i=0..n);

> end;

> integre:=proc(a,b,f)

> int(f(x),x=a..b);

> end;
trace:=proc(a,b,f) plot(f,a..b) end;

> end module;

fonc := module () export integre, suite, trace; int...

> FF:=x->x^2+1;

FF := proc (x) options operator, arrow; x^2+1 end p...

> fonc:-integre(0,1,FF);

4/3

> fonc:-suite(10,0,1,FF);

1, 101/100, 26/25, 109/100, 29/25, 5/4, 34/25, 149/...

> fonc:-trace(0,1,FF);

[Maple Plot]

V.La fonction Zeta et la conjecture de Riemann

La fonction Zeta est définie comme sum(1/(n^z),n = 1 .. infinity) pour i allant de 1 à l'infini pour toute valeur de z

telle que Re(z>1).

Un prolongement analytique permet en fait de prolonger cette fonction pour toute valeur de z

complexe différente de 1. Riemann a montré que Zeta(-2*n) s'annule pour tout entier n

strictement positif et a conjecturé que les autres zéros de Zeta sont tous situés sur

l'axe z=1/2+iy, appelé ligne critique. Depuis la preuve du théorème de Fermat en 1995

par Wiles, la conjecture de Riemann reste l'un des problèmes mathématiques importants

non résolus.

Tracer le module de la fonction Zeta entre 0 et 60 le long de la ligne critique.

> plot(abs(Zeta(1/2+y*I)),y=0..56,numpoints=200);

[Maple Plot]

Calculer en utilisant une boucle tous les zéros entre 0 et 60 le long de la ligne critique.

> j:=0;for i from 12 to 60 do res:=fsolve(abs(Zeta(1/2+y*I)),y=i..i+1);if type(res,realcons) then zero||j:=res; print(zero||j);j:=j+1; fi;od:print(j-1);

j := 0

14.13472514

21.02203964

25.01085758

30.42487613

37.58617816

40.91871901

43.32707328

49.77383248

56.44624770

59.34704400

9