Vous êtes sur la page 1sur 13

Ecole Nationale Des Sciences

Appliquées de Tétouan- ENSA 2AP-1


– 2015/2016

Initiation à MATLAB

TP4
Exercice 1

Traduire en langage Matlab l’algorithme PGCD suivant :

a,b entiers positifs

tant-que a �b faire

si a > b alors a �a - b

sinon b � b - a

fin tant-que

PGCD � a

Corrigé de l’exercice 1

Pour traduire en langage Matlab l’algorithme PGCD considéré dans cet exercice, nous avons besoin
des structures de contrôle, en l’occurrence la boucle while et le test if-else-end. Nous proposons le
M-file suivant pour le programme traduisant cet algorithme:

clear all;

close all;

clc;

a=input('Entrer l''entier positif a ');

b=input('Entrer l''entier positif b ');

a0=a;

b0=b;

while a~=b

if a>b

a=a-b;

else

b=b-a;

1
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

end

end

str=['Le plus petit diviseur commun de ' num2str(a0) ' et '


num2str(b0) ' est ' num2str(a)];

disp(str);

Remarques:

*Le programme M-file constituant la réponse à cet exercice n’est pas unique. Chacun a sa façon
personnelle de programmer. Le programme proposé est donc un exemple seulement de solution. Il
existe cependant des critères à satisfaire: le programme doit être sans redondances, facile à lire et
optimisé.

*On a fait appel aux variables auxiliaires a0 et b0 pour stocker les valeurs initiales de a et b qui sont
modifiées dans la boucle while et ne gardent pas donc leurs valeurs d’entrées à la sortie de cette
boucle. Elles sont en fait écrasées dans les lignes 10 et 12.

*On peut tester le programme en faisant appel à la commande gcd de Matlab qui calcule le plus
grand diviseur commun de deux nombre entiers positifs. Pour cela, il suffit de taper dans notre cas
(a0=18 ; b0=5).

>> gcd(a0,b0)

ans =

* Il faut faire la distinction entre la commande disp qui affiche la valeur de la variable sans écrire le
nom de la variable et la commande display qui écrit le nom de la variable avant de l’afficher. Taper
pour cela les deux commandes suivantes:

>> display(str)

str =

Le plus petit diviseur commun de 18 et 25 est 1

>> disp(str)

Le plus petit diviseur commun de 18 et 25 est 1

2
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

Exercice 2

Ecrire la fonction vec2col.m qui transforme tout vecteur (ligne ou colonne) passé en argument
en vecteur colonne. Un traitement d’erreur testera que la variable passée à la fonction est bien
un vecteur et non une matrice (utiliser la commande size).

Corrigé de l’exercice 2

On propose le M-file de type fonction suivant :

function [y]=vect2col(x)

n=size(x);

n1=n(1);

n2=n(2);

if n1==1

y=x.';

elseif n2==1

y=x;

else

erreur=['la variable entrée n''est pas un vecteur ligne ou


colonne'];

display(erreur)

end

On peut le tester avec les commandes

>> vect2col([1 1 1])

ans =

>> vect2col([1; 1; 1])

ans =

3
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

>> vect2col([1 1; 1 2])

erreur =

la variable entrée n'est pas un vecteur ligne ou colonne

Exercice 3

Ecrire un script qui permet selon le choix de transformer les cordonnées cartésiennes (x,y,z)
en coordonnés cylindriques (r, q,z) ou bien en coordonnées sphériques (r, q, j) .

Corrigé de l’exercice 3

Un exemple de script répondant à l’énoncé est donné dans la suite. Remarquer que l’on sort les
coordonnées cylindriques selon l’ordre : ( r, q,z ) et les coordonnées sphériques selon l’ordre
( r, q, j) .
function [a,b,c]=transformation(x,y,z,choix)

switch choix

case 'cylindrique'

a=sqrt(x^2+y^2);

b=atan(y/x);

c=z;

case 'sphérique'

a=sqrt(x^2+y^2+z^2);

b=atan(y/x);

c=atan(sqrt(x^2+y^2)/z);

otherwise

display('Vous n''avez pas préciser la nature de la


tansformation')

end

4
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

end

Exemples d’utilisation :

>> [a,b,c]=transformation(1,1,1,'cylindrique')

a=

1.4142

b=

0.7854

c=

>> [a,b,c]=transformation(2,3,4,'sphérique')

a=

5.3852

b=

0.9828

c=

0.7336

Avec Matlab vous avez quatre commandes qui vous permettent de faire la transformation des
coordonnées cartésiennes en coordonnées cylindriques ou bien des coordonnées cartésiennes en
coordonnées sphériques, ainsi que leurs inverses.

[theta,rho,z]=cart2pol(x,y,z) % transforamtion catésiennes en cylindriques

[x,y,z]=pol2cart(theta,rho,z) % transforamtion cylindriques en cartésiennes

[theta,phi,r]=cart2pol(x,y,z) % transforamtion catésiennes en sphériques

[x,y,z]=sph2cart(theta,phi,r) % transforamtion sphériques en catésiennes

5
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

Attention:

* Ici tous les angles sont calculés en radians (Matlab utilise cette unité
par défaut).

* Matlab sort les coordonnées cylindriques selon l’ordre ( q,r,z ) et les

coordonnées sphériques selon l’ordre ( q, j,r ) .

* Dans Matlab l’angle phi est compté à partir du plan horizontal et non pas
à partir de l’axe des z comme le montre la figure suivante :

Notre
choix 

Définition des coordonnées sphériques selon Matlab :

phi est compté à partir du plan: phi=90-

Exercice 4

On considère l’algorithme suivant pour calculer π: on génère n couples { ( x k ,y k ) } de nombres


aléatoires dans l’intervalle [0, 1], puis on calcule le nombre m de ceux qui se trouvent dans le
premier quart du cercle unité, c'est-à-dire vérifiant la condition: x 2k + y 2k �.
1

4m
Naturellement, π est la limite de la suite u n = . Ecrire un programme Matlab pour calculer
n
cette suite et observer comment évolue l’erreur quand n augmente.

Corrigé de l’exercice 4

On peut proposer le script suivant :

6
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

clear all;

close all;

clc;

format long;

N=input('Entrer N? ')

x=rand(N,1);

y=rand(N,1);

z=x.^2+y.^2;

m=sum(z<=1);

uN=4*m/N;

display(uN);

erreur=(pi-uN)/pi;

display(erreur);

A l’exécution, on obtient :

Entrer N? 2.e7

N=

20000000

uN =

3.141851800000000

erreur =

-8.248886433788238e-005

La convergence est très lente avec le processus de Monte Carlo. Sur ma machine, on ne peut pas
dépasser N = 2.e7 car la mémoire se sature.

Ceux qui préfèrent les boucles et les tests peuvent être intéressés par la variante suivante:

7
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

clear all;

close all;

clc;

format long;

N=input('Entrer N? ')

m=0;

tic;

for k=1:N

xk=rand(1);

yk=rand(1);

if xk^2+yk^2<=1

m=m+1;

else

end

end

uN=4*m/N;

display(uN);

erreur=(pi-uN)/pi;

display(erreur);

toc;

En exécutant ce script, on obtient :

Entrer N? 2.e7

N=

20000000

uN =

3.141854000000000

erreur =

8
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

-8.318914608747151e-005

Elapsed time is 106.232164 seconds.

On a placé tic et toc pour compter la durée d’exécution, c'est-à-dire celle que l’on mesurerait en
consultant une horloge étalonnée déclenchée avant de lancer le programme et arrêtée à la fin de
l’exécution du programme (A ne pas confondre avec le temps CPU que l’on peut obtenir avec la
commande cputime). On a attendu dans ce cas à peu près 106 s.

Avec la première version, on obtient

Entrer N? 2.e7

N=

20000000

uN =

3.141189800000000

erreur =

1.282322803158388e-004

Elapsed time is 3.452282 seconds.

La durée d’exécution est meilleure avec la première version du programme. Elle est seulement de
3.3% de celle qui est exigée avec la deuxième version. Cependant la deuxième version ne souffre
pas de limitation au niveau de l’occupation de la mémoire car on peut dépasser facilement un
nombre de tirages supérieur à N = 2.e7 , du fait que l’on ne stocke pas en mémoire les variables: on
les écrase.

Un programme n’est jamais unique, mais il existe des critères qui font qu’une version de script est
meilleure que l’autre: la clarté, la vitesse d’exécution et l’occupation de la mémoire sont des
éléments importants.

L’étude de la convergence est résumée dans le tableau suivant:

N 1.e3 1.e4 1.e5 1.e6 1.e7 2.e7

Erreur 1.4513e-2 4.3267e-3 1.0973e-3 2.5612e-4 -7.0494e-6 1.5446e-4

Il faut remarquer que ces erreurs varient d’un tirage à l’autre et que le tableau représente le
résultat d’un tirage particulier. Par ailleurs la convergence n’est pas monotone comme le montre les
deux dernières colonnes.

9
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

Exercice 5

Ecrire un script qui permet de calculer par la méthode de dichotomie la racine de l’équation
nonlinéaire suivante: 5sin(x) - exp(x / 2) = 0 sur l’intervalle [0,1] .

Le script devra permettre de calculer par l’algorithme de dichotomie une approximation à h


près de la solution de l’équation f(x) = 0 dans l’intervalle [a,b], a, b et h étant saisis par
l’utilisateur et la fonction f étant définie par la commande inline.

Principe de la méthode de dichotomie :

Soit f une fonction continue sur [a, b] telle que f(a)f(b) < 0. Nécessairement f a au moins un
zéro dans ]a, b[ (ce résultat est un cas particulier du théorème des valeurs intermédiaires).
Supposons pour simplifier qu’il est unique et notons le α (dans le cas où il y a plusieurs zéros,
on peut localiser graphiquement, à l’aide de la commande plot, un intervalle qui n’en contient
qu’un).
La méthode de dichotomie consiste à diviser en deux un intervalle donné, et à choisir
le sous-intervalle où f change de signe. Plus précisément, si on note I(0) =]a, b[ et I(k) le
sous-intervalle retenu à l’étape k, on choisit le sous-intervalle I(k+1) de I(k) pour lequel f a un
signe différent à ses deux extrémités. En répétant cette procédure, on est assuré que chaque
I(k) ainsi construit contiendra α. La suite {m(k)} des milieux des intervalles I(k) convergera
vers α puisque la longueur de ces intervalles tend vers zéro quand k tend vers l’infini.
La méthode est initialisée en posant
a(0) = a, b(0) = b, I(0) =]a(0), b(0)[, m(0) = (a(0) + b(0))/2.
A chaque étape k ≥ 1, on choisit le sous-intervalle I(k)=]a(k), b(k)[ de
I(k−1)=]a(k−1), b(k−1)[ comme suit
étant donné m(k−1) = (a(k−1) + b(k−1))/2,
si f(m(k−1)) = 0,
alors α = m(k−1)
et on s’arrête ;
sinon, si f(a(k−1))f(m(k−1)) < 0
poser a(k) = a(k−1), b(k) = m(k−1);
si f(m(k−1))f(b(k−1)) < 0
poser a(k) = m(k−1), b(k) = b(k−1).
On définit alors m(k) = (a(k) + b(k))/2 et on incrémente k de 1.
A l’itération N la racine de f(x) = 0 est approximée par m(N) à h près si b(N) - a(N) �h .
�b - a �
On démontre que le nombre minimum des itérations est N min �log 2 � � -1 .
�h �
Corrigé de l’exercice 5
�b - a �
En fait, on démontre que le nombre minimum des itérations est N min �log 2 � � +1 et non
�h �
�b - a �
pas N min �log 2 � � -1 . Une solution possible pour cet exercice est donnée par le script
�h �
suivant :

10
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

clear all;

close all;

clc;

format long;

f=inline('5*sin(x)-exp(x/2)');

eta=1.e-12;

a0=0;

b0=1;

N=log2((b0-a0)/eta)+1;

for k=1:N

m0=(a0+b0)/2;

if f(m0)==0

elseif f(a0)*f(m0)<0

a1=a0; b1=m0;

else

a1=m0; b1=b0;

end

a0=a1;

b0=b1;

end

erreur=b0-a0;

display(erreur);

solution=m0;

display(solution);

%On peut vérifier que f(solution) est à peu près égal à zéro

valeurdef=f(m0);

display(valeurdef);

Noter que la fonction logarithme en base 2 s’écrit log2.

11
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

On n’était pas obligé de fixer le nombre des itérations a priori. En utilisant la boucle while sur
l’erreur avec un mouchard qui indique les itérations effectuées, le script devient

clear all;

close all;

clc;

format long;

f=inline('5*sin(x)-exp(x/2)');

eta=1.e-12;

a0=0;

b0=1;

N=log2((b0-a0)/eta)+1;

erreur=b0-a0;

n=0;

while erreur>eta

n=n+1;

m0=(a0+b0)/2;

if f(m0)==0

elseif f(a0)*f(m0)<0

a1=a0; b1=m0;

else

a1=m0; b1=b0;

end

a0=a1;

b0=b1;

erreur=b0-a0;

end

display(n);

display(erreur);

12
Ecole Nationale Des Sciences
Appliquées de Tétouan- ENSA 2AP-1
– 2015/2016

solution=m0;

display(solution);

%On peut vérifier que f(solution) est à peu près égal à zéro

valeurdef=f(m0);

display(valeurdef);

13