KM05_exo1.mw

Exercice 1

> Question a)

>

> Méthode itérative
  

> iteration:=proc(a,b,n)  
local s,an,bn,temp,k;

an:=a;bn:=b;
initialisation des valeurs de la suite an et bn représentent ici a0 et bo
for k from 1 to n do  

   on utilise des variables temporaires atemp et btemp pour ne pas interferer dans le calcul du nouveau an et bn en fonction des anciens

 temp:=sqrt(an*bn);bn:=(an+bn)/2;

 an:=temp;  
les anciennes valeurs de an et bn deviennent ici les nouvelles
od:

[an,bn];

end:

>

> iteration(0.5,1,25); Calcul de [a(25),b(25)] pour a0=0.5 et b0=1

[.7283955156, .7283955156]

>

> Méthode récursive

> iteration:=proc(a,b,n) option remember;
local s,u;

if n=0 then s:=[a,b]
la recursion doit pouvoir s'arrêter pour donner une valeur effective ici [a0,b0]
 else

    u:=iteration(a,b,n-1);
on fait appel à notre propre procédure pour connaitre les valeurs a(n-1) et b(n-1)
    s:=[sqrt(u[1]*u[2]),(u[1]+u[2])/2];
on en déduit an et bn
fi:

s;

end:

>

> iteration(0.5,1,25); Calcul de [a(25),b(25)] pour a0=0.5 et b0=1

[.7283955156, .7283955156]

>

>

Question b

> Calcul d'une limite approchée

>

Méthode naive

> limite:=proc(a,b,epsilon)
local an,bn,u,n;

an:=a;bn:=b;n:=0;

while is(abs(an-bn)>epsilon) do
tant que la distance séparant an, bn (suites adjacentes) dépasse epsilon, le calcul continue
n:=n+1:u:=iteration(a,b,n);an:=u[1];bn:=u[2];

od;

['an'=an,'n'=n];

end:

>

> limite(0.5,3,1/1000000); limite approchée à 10^(-6) près avec a0=0.5 et b0=3

[an = 1.475664371, n = 4]

>

Méthode itérative

> limite:=proc(a,b,epsilon)
local s,an,bn,temp,n;

an:=a;bn:=b;

n:=0;

while is(abs(an-bn)>epsilon) do

    n:=n+1:temp:=sqrt(an*bn);bn:=(an+bn)/2;

 an:=temp;

od:

['an'=an,'n'=n];

end:

>

>

>

> limite(0.5,3,1/1000000); limite approchée à 10^(-6) près avec a0=0.5 et b0=3

[an = 1.475664371, n = 4]

>

> Méthode récursive

> limite:=proc(a,b,epsilon) option remember;
local s,u;

if is(abs(a-b)<=epsilon) then s:=[a,b,0];
la recursion doit pouvoir s'arrêter pour donner une valeur effective ici [a0,b0]
 else

   s:=limite(sqrt(a*b),(a+b)/2,epsilon);
on en déduit an et bn
   s:=[s[1],s[2],s[3]+1];

fi:

s;

end:

>

> limite(0.5,3,1/1000000); limite approchée à 10^(-6) près avec a0=0.5 et b0=3

[1.475664371, 1.475664372, 4]

>

>

> Question c

Méthode naïve

> erreur:=proc(a,b,n)
local souvenir,i,un;

souvenir:=b-a;

for i from 1 to n do

un:=iteration(a,b,i);souvenir:=souvenir,un[2]-un[1];

od;

[sol];

end:

> evalf(erreur(1,3,5));

[2., .267949192, 0.4815686e-2, 0.1555e-5, -0.1e-8, 0.]

>

> Méthode itérative

> erreur:=proc(a,b,n)
 local s,an,bn,temp,k,souvenir;

an:=a;bn:=b;

souvenir:=bn-an;

for k from 1 to n do  

   
 temp:=sqrt(an*bn);bn:=(an+bn)/2;
 an:=temp;  

 souvenir:=souvenir,bn-an;

od:

[souvenir];

end:

>

> evalf(erreur(1,3,5));

[2., .267949192, 0.4815686e-2, 0.1555e-5, -0.1e-8, 0.]

>

> Méthode récursive

> val_suite:=proc(a,b,n)
 option remember;

local s,u;

if n=0 then s:= [[a,b]]
la recursion doit pouvoir s'arrêter pour donner une valeur effective ici [a0,b0]
 else

    u:=val_suite(a,b,n-1);
on fait appel à notre propre procédure pour connaitre les valeurs a(n-1) et b(n-1)
    s:=[op(u),[sqrt(u[n][1]*u[n][2]),(u[n][1]+u[n][2])/2]];
on en déduit an et bn
fi:

s;

end:

> val_suite(a,b,2);

[[a, b], [(a*b)^(1/2), 1/2*a+1/2*b], [((a*b)^(1/2)*(1/2*a+1/2*b))^(1/2), 1/2*(a*b)^(1/2)+1/4*a+1/4*b]]

>

> erreur:=proc(a,b,n)
 local suite,k,sol,suiten;

suite:=val_suite(a,b,n);

sol:=NULL;  

for k from 1 to n+1 do

  suiten:=suite[k];

  sol:=sol,suiten[2]-suiten[1];   

od:

[sol];

end:

>

> evalf(erreur(1,3,5));

[2., .267949192, 0.4815686e-2, 0.1555e-5, -0.1e-8, 0.]

>

Commentons ces valeurs, il apparait des choses étranges comme la valeur néagtive pour b4-a4 alors que celle-ci devrait être positive (suites adjacentes)

Par ailleurs la différence b5-a5 est suspecte car on imagine mal la suite devenir stationnaire comme nous le montre le calcul des valeurs suivantes

>

> evalf(erreur(1,3,15));

[2., .267949192, 0.4815686e-2, 0.1555e-5, -0.1e-8, 0., 0., 0., 0., 0., 0., 0., 0., 0.1e-8, 0.1e-8, -0.1e-8]

En fait les choses deviennent plus claires lorsque l'on change la précision des calculs

>

> Digits:=50;

Digits := 50

> evalf(erreur(1,3,5));

[2., .2679491924311227064725536584941276330571947461896, 0.48156855802394488812856767864680079689941755500e-2, 0.15554986824695853852523738017062669132559152e-5, 0.162290349397348530459166233744616622...

La convergence étant si rapide et les expressions si complexes que les résultats approchés sont très sensibles à la précision qu'on se fixe.