Intro Matlab09

Télécharger au format pdf ou txt
Télécharger au format pdf ou txt
Vous êtes sur la page 1sur 21

Une Introduction à MATLAB

David Poulin
Département de Physique, Université de Sherbrooke, Qc, Canada
[email protected]
4 février 2010

Table des matières


1 Pourquoi utiliser MATLAB 1

2 Le mode interactif 4

3 Quelques fonctions élémentaires 5


3.1 Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.1.1 Créer une matrice . . . . . . . . . . . . . . . . . . . . . . 6
3.1.2 Opérations algébriques . . . . . . . . . . . . . . . . . . . . 7
3.1.3 Opérations élément par élément . . . . . . . . . . . . . . . 8
3.1.4 Conjugaison, transposition et adjoint . . . . . . . . . . . . 10
3.1.5 Diagonalisation . . . . . . . . . . . . . . . . . . . . . . . . 10
3.1.6 Fonctions analytiques . . . . . . . . . . . . . . . . . . . . 12
3.1.7 Éléments d’une matrice . . . . . . . . . . . . . . . . . . . 12
3.1.8 Matrices éparses . . . . . . . . . . . . . . . . . . . . . . . 14
3.2 Écriture et lecture . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.3 Graphique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4 Les scripts 17

5 Les fonctions 20
5.1 Fonctions anonymes . . . . . . . . . . . . . . . . . . . . . . . . . 21

1 Pourquoi utiliser MATLAB


Contrairement au langage C++ avec lequel vous êtes tous familiers, le lan-
gage MATLAB n’est pas un langage compilé ; c’est un langage interprété. MAT-
LAB possède une riche bibliothèque de fonctions pré-définies qui simplifie gran-
dement l’élaboration de programmes plus complexes. MATLAB n’est toutefois
pas toujours optimal lorsque nous voulons développer un algorithme très per-
formant avec une certaine longévité. Par contre, c’est un langage idéal lorsque

1
nous devons résoudre un certain problème une seule fois ou lorsque les ressources
requises par le calcul ne sont pas très importantes.
À titre d’exemple, supposons que l’on désire résoudre le problème d’équations
linéaires suivant     
3 1 3 x1 −1
 1 5 9   x2  =  3  . (1)
2 6 5 x3 −3
Une petite recherche sur Google nous permet de trouver un programme écrit en
C++ qui accomplit cette tâche (source, http ://seehuhn.de/pages/linear)
#include <stdio.h>
#include <atlas_enum.h>
#include "clapack.h"

double m[] = {
3, 1, 3,
1, 5, 9,
2, 6, 5
};

double x[] = {
-1, 3, -3
};

int
main()
{
int ipiv[3];
int i, j;
int info;

info = clapack_dgesv(CblasRowMajor, 3, 1, m, 3, ipiv, x, 3);


if (info != 0) fprintf(stderr, "failure with error %d\n", info);

for (i=0; i<3; ++i) printf("%5.1f %3d\n", x[i], ipiv[i]);

return 0;
}
Ce code doit ensuite être compilé avec la commande gcc programme.c -o
a.out -llapack atlas -llapack -lblas -latlas -lm, sans oublier d’avoir
bien installé le fichier clapack.h. On l’exécute ensuite à l’aide de la commande
./a.out. Voici maintenant un code MATLAB effectuant la même tâche :
>> A = [3 1 3; 1 5 9; 2 6 5];
>> x = [-1; 3;-3];
>> y = A\x

2
Il y a évidemment une différence notable entre la taille de ces deux pro-
grammes. On observe en particulier que la majorité des commandes du code
en C++ servent à «mettre la table» en ce sens qu’elles ne s’attaquent pas
au problème mais définissent les paramètres du calcul. En particulier, un bon
nombre de commandes définissent les bibliothèques utilisées par le programme
ou définissent le type de chaque variable. Par exemple, la variable x qui contient
la solution à notre système d’équations est un tableau de type entier. En MAT-
LAB par contre, l’appel des bibliothèques nécessaires et la déclaration de type se
fait automatiquement. Nous n’avons pas à spécifier le type ou même la taille des
tableaux : ceux-ci sont extraits du contexte. Ainsi, la même ligne de commande
MATLAB pourrait résoudre un système d’équations linéaires avec coefficients
complexes, alors qu’une routine différente serait requise en C++.
Cela illustre quelques uns des nombreux avantages d’un langage de haut ni-
veau tel que MATLAB. En contrepartie, un langage interprété est généralement
plus lent qu’un langage compilé. Pour toutes les opérations matricielles, MAT-
LAB utilise la bibliothèque LAPACK, tout comme la majorité des programmes
développés dans le langage C++. Ainsi, MATLAB est tout aussi rapide que
le C++ pour les opérations matricielles, tant que l’on l’utilise correcte-
ment. Afin d’illustrer l’importance d’utiliser les fonctions pré-définies, com-
parons les performances d’une de ces fonctions à celles d’une fonction «faite
maison». Définissons d’abord deux vecteurs aléatoires de taille 1 000 000 :
>> X = rand(1000000,1);
>> Y = rand(1000000,1);
On peut additionner ces vecteurs tout simplement avec le symbole +. Dans ce
qui suit, nous mesurons la performance du calcul à l’aide de la fonction cputime
qui retourne le temps en secondes utilisé par le processeur
>> t = cputime; Z = X+Y; cputime-t

ans =

0.0200

Essayons maintenant en additionnant les éléments de chaque vecteur un à la


fois à l’aide d’une boucle for.
>> t = cputime;
for j=1:1000000
W(j) = X(j)+Y(j);
end
cputime-t

ans =

55.490000000000009

3
Puisqu’elle ne fait pas appel aux fonctions matricielles pré-définies dans MAT-
LAB, la seconde méthode requière 2000 fois plus de temps ! (Note : le temps
d’exécution de la seconde commande est très instable... peut fluctuer considérablement
d’une machine à l’autre.)
Le département de physique possède une dizaine de licences MATLAB qui
peuvent être utilisées simultanément. Le programme Octave (http ://www.gnu.org/software/octave/)
est en gros une version gratuite de MATLAB. Il existe quelques petites différences
au niveau de la syntaxe, mais elles sont très rares et en général Octave est plus
permissif que MATLAB. Tous les programmes que nous présentons dans ces
notes peuvent aussi bien être exécutés avec Octave qu’avec MATLAB.
Bien que MATLAB soit équipé d’une bibliothèque pour le calcul symbolique,
il est principalement utilisé (et performant) pour le calcul numérique. Pour le
calcul symbolique, les programmes Mathematica ou Maple sont habituellement
plus puissants.

2 Le mode interactif
Il existe trois façons d’utiliser MATLAB, soit en mode interactif, à l’aide
de scripts ou de fonctions. Nous abordons d’abord le mode interactif, les deux
autres méthodes seront discutées aux sections 4 et 5 respectivement. En mode
interactif, on inscrit directement les commandes dans un terminal et celles-ci
sont exécutées dès que l’on appuie sur la touche «enter». Le symbole >> (ou
octave-3.0.1 :1> avec Octave) apparaı̂t lorsque le terminal est prêt à recevoir
une commande, c’est-à-dire lorsque l’exécution de la commande précédente est
terminée. Voici quelques exemples d’exécution en mode interactif :
>> 5+6

ans =

11

>> a = 3 + 2

a =

>> b = 1+4;
>> a+b

ans =

10

4
On remarque une différence entre la commande a = 3 + 2 et b = 1 + 4 ;.
Dans le premier cas, la réponse a = 5 est affichée au terminal alors que dans
le second elle ne l’est pas. C’est l’effet du point-virgule. Si l’on désire faire une
opération sans voir le résultat immédiatement, on ajoute un point-virgule à la
fin de la commande. On peut toujours afficher la valeur d’une variable plus tard
en entrant son nom comme ligne de commande, par exemple
>> b

b =

5
Le nom des variables doit débuter par une lettre et peut être suivi par une
combinaison arbitraire d’au plus 32 chiffres et lettres. Il est important d’essayer
de choisir des noms de variables qui expliquent du mieux possible le rôle de
chaque variable. On observe qu’il n’est pas nécessaire d’assigner de type aux
variables. Toute variable en MATLAB est une matrice (ou tenseur) dont le type
(complexe, réel, entier) est déterminé par le contexte et se modifie automati-
quement au besoin. On peut connaı̂tre toutes les variables en mémoire à l’aide
de la commande whos :
>> whos
Name Size Bytes Class Attributes

A 3x3 72 double
X 10000000x1 80000000 double
Y 10000000x1 80000000 double
Z 10000000x1 80000000 double
a 1x1 8 double
ans 1x1 8 double
b 1x1 8 double
t 1x1 8 double
x 3x1 24 double
y 3x1 24 double
ce qui correspond bien aux variables que nous avons définies jusqu’à maintenant.
On vide le contenu d’une variable à l’aide de la commande clear suivi du nom
de la variable et clear all pour libérer toute la mémoire.

3 Quelques fonctions élémentaires


MATLAB possède une importante bibliothèque de fonctions, impossible ici
d’en faire le tour. Heureusement, la rubrique d’aide (dont une version se retrouve
en ligne à l’adresse
http ://www.mathworks.com/support/product/product.html ?product=ML ) per-
met en général de rapidement repérer les fonctions dont nous avons besoin. En

5
particulier, on retrouve au bas de chaque page d’aide une liste de fonctions si-
milaires ou reliées de quelconque façon à la fonction principale. C’est ainsi que
de fil en aiguille on arrive généralement à identifier la fonction qu’il nous faut.
Un autre outil indispensable pour la recherche de fonctions MATLAB est bien
entendu Google. Par exemple, une simple recherche «matlab valeurs propres»
ou encore «matlab intégrale» nous enseigne comment diagonaliser les matrices
ou intégrer des fonctions.
Un certain nombre de constantes sont pré-définies : pi est le nombre π, inf
est le résultat de la division par 0, eps est la précision numérique qui dépend
de l’ordinateur, realmax et realmin sont le plus grand et le plus petit nombre
qu’on peut représenter
√ dans MATLAB, NAN est résultat de 0/0 et i et j sont
tous deux égaux à −1. Il faut faire attention car on peut écraser ces valeurs en
les utilisant en tant que variables et en leur assignant de nouvelles valeurs, par
exemple i=3. Il en va de même de toutes les fonctions pré-définies en MATLAB,
on peut les détruire si on n’est pas prudent. Par exemple sin = 4 nous empêche
d’utiliser subséquemment la fonction sinus. Vaut mieux éviter d’utiliser les noms
pré-assignés en tant que variables sinon on se réserve de belles surprises !

3.1 Matrices
3.1.1 Créer une matrice
Nous avons déjà vu comment définir une matrice en MATLAB, il suffit de
mettre ses éléments entre crochets [ ]. Les éléments d’une même ligne sont
séparés d’un espace et un point-virgule marque la fin d’une ligne. Les vecteurs
ligne sont définis en tant que matrices de taille 1 × m alors que les vecteurs
colonne sont de taille m × 1. La matrice nulle de taille m × n s’obtient avec la
commande zeros(m,n). Lorsque m = n, on utilise plus simplement zeros(m),
ce qui sous-entend une matrice carrée. La matrice identité de taille n s’obtient
avec eye(n). On peut obtenir une matrice dont les éléments sont aléatoirement
distribués dans l’intervalle [0, 1] à l’aide de rand :
>> A = rand(4)

A =

0.4237 0.1538 0.7883 0.3294


0.8035 0.6031 0.7314 0.8815
0.1124 0.7876 0.9797 0.1105
0.0453 0.1185 0.6286 0.3511

Il est à noter qu’avant l’exécution de cette commande, la variable A était une ma-
trice de taille 3×3 puisque nous l’avions définie ainsi dans un exemple précédent
et ne l’avions pas libérée. Cela n’est pas un problème, MATLAB se charge de
libérer la mémoire et de donner à A les bonnes dimensions. Bien entendu, la
valeur précédente de A est perdue. Les dimensions d’une matrice sont données
par la fonction size, qui retourne un vecteur [m n] contenant les dimensions.

6
On peut donc combiner cette fonction comme eye(size(A)) qui retourne la
matrice identité de taille 4 × 4.
On peut créer un vecteur contenant les entiers de k à h comme suit
>> c = 5:13

c =

5 6 7 8 9 10 11 12 13
On peut également spécifier un espacement différent entre chaque valeur, par
exemple
>> c = 5:-0.3:2.9

c =

5.0000 4.7000 4.4000 4.1000 3.8000 3.5000 3.2000 2.9000

3.1.2 Opérations algébriques


Les opérations algébriques sont définies de façon naturelle sur les matrices :
on peut additionner et soustraire des matrices de même taille à l’aide des
opérateurs + et −. On peut multiplier ou diviser une matrice par un scalaire à
l’aide de ∗ et /, et élever une matrice carrée à la puissance d’un scalaire avec
∧. Si on additionne un scalaire à une matrice, cela a pour effet d’additionner le
scalaire à chaque élément de la matrice. Attention, il ne faut pas confondre cette
opération avec l’addition d’un multiple scalaire de la matrice identité. On peut
multiplier deux matrices A et B de taille m1 × n1 et m2 × n2 lorsque n1 = m2 .
Cela se fait avec le symbole ∗.
>> B = [1 2 3 4;5 6 7 8;9 10 11 12; 13 14 15 16];
>> C = rand(4,2)

C =

0.6500 0.7586
0.7829 0.2753
0.2136 0.2930
0.9265 0.4861

>> A+B

ans =

1.4237 2.1538 3.7883 4.3294


5.8035 6.6031 7.7314 8.8815
9.1124 10.7876 11.9797 12.1105

7
13.0453 14.1185 15.6286 16.3511

>> 2.2*C

ans =

1.4300 1.6688
1.7224 0.6056
0.4698 0.6445
2.0383 1.0693

>> B^2

ans =

90 100 110 120


202 228 254 280
314 356 398 440
426 484 542 600

>> A*C

ans =

0.8693 0.7548
1.9673 1.4182
1.0013 0.6428
0.5817 0.4217

>> A+3

ans =

3.4237 3.1538 3.7883 3.3294


3.8035 3.6031 3.7314 3.8815
3.1124 3.7876 3.9797 3.1105
3.0453 3.1185 3.6286 3.3511
De même, la division à droite et à gauche se font à l’aide des symboles / et \.
La division produit le même effet que la multiplication par l’inverse, c’est-à-dire
que A/B produit le même effet que A*B∧(-1) et que A\B produit le même effet
que A∧(-1)*B.

3.1.3 Opérations élément par élément


MATLAB permet également de faire certaines opérations élément par élément.
Par exemple, on peut multiplier chaque élément de la matrice A par l’élément

8
correspondant de la matrice B
>> A.*B

ans =

0.4237 0.3075 2.3649 1.3176


4.0175 3.6186 5.1197 7.0517
1.0115 7.8761 10.7769 1.3261
0.5887 1.6583 9.4285 5.6175
ce qui diffère clairement du produit matriciel

>> A*B

ans =

12.5694 14.2646 15.9597 17.6549


21.8606 24.8800 27.8995 30.9189
14.3045 16.2948 18.2850 20.2752
10.8588 12.0022 13.1456 14.2890
De façon similaire, A.∧ B élève chaque élément Ajk de A à la puissance Bjk ,
A./B divise chaque élément de A par l’élément associé de B et finalement A.\ B
divise chaque élément de B par l’élément associé de A. On peut également élever
chaque élément à la puissance d’un scalaire :
>> A.^2

ans =

0.1795 0.0236 0.6214 0.1085


0.6456 0.3637 0.5349 0.7770
0.0126 0.6203 0.9598 0.0122
0.0021 0.0140 0.3951 0.1233

>> A^2

ans =

0.4066 0.8178 1.4258 0.4779


0.9472 1.1677 2.3451 1.1866
0.7956 1.2770 1.6940 0.8783
0.2009 0.6151 0.9588 0.3121
La première commande retourne le carré de chaque élément alors que la seconde
agit de façon identique à A*A.

9
3.1.4 Conjugaison, transposition et adjoint
On obtient donc des matrices complexes à l’aide du nombre imaginaire i,
par exemple
>> D = A+i*B

D =

0.4237 + 1.0000i 0.1538 + 2.0000i 0.7883 + 3.0000i 0.3294 + 4.0000i


0.8035 + 5.0000i 0.6031 + 6.0000i 0.7314 + 7.0000i 0.8815 + 8.0000i
0.1124 + 9.0000i 0.7876 +10.0000i 0.9797 +11.0000i 0.1105 +12.0000i
0.0453 +13.0000i 0.1185 +14.0000i 0.6286 +15.0000i 0.3511 +16.0000i
Le conjugué, transposition et adjoint d’une matrice (ou d’un scalaire) s’ob-
tiennent ainsi
>> conj(D)

ans =

0.4237 - 1.0000i 0.1538 - 2.0000i 0.7883 - 3.0000i 0.3294 - 4.0000i


0.8035 - 5.0000i 0.6031 - 6.0000i 0.7314 - 7.0000i 0.8815 - 8.0000i
0.1124 - 9.0000i 0.7876 -10.0000i 0.9797 -11.0000i 0.1105 -12.0000i
0.0453 -13.0000i 0.1185 -14.0000i 0.6286 -15.0000i 0.3511 -16.0000i

>> transpose(D)

ans =

0.4237 + 1.0000i 0.8035 + 5.0000i 0.1124 + 9.0000i 0.0453 +13.0000i


0.1538 + 2.0000i 0.6031 + 6.0000i 0.7876 +10.0000i 0.1185 +14.0000i
0.7883 + 3.0000i 0.7314 + 7.0000i 0.9797 +11.0000i 0.6286 +15.0000i
0.3294 + 4.0000i 0.8815 + 8.0000i 0.1105 +12.0000i 0.3511 +16.0000i

>> D’

ans =

0.4237 - 1.0000i 0.8035 - 5.0000i 0.1124 - 9.0000i 0.0453 -13.0000i


0.1538 - 2.0000i 0.6031 - 6.0000i 0.7876 -10.0000i 0.1185 -14.0000i
0.7883 - 3.0000i 0.7314 - 7.0000i 0.9797 -11.0000i 0.6286 -15.0000i
0.3294 - 4.0000i 0.8815 - 8.0000i 0.1105 -12.0000i 0.3511 -16.0000i

3.1.5 Diagonalisation
Une matrice normale, c’est-à-dire une matrice qui commute avec son adjoint,
possède une décomposition en valeur propre : D = U ΛU † ou Λ est une matrice

10
diagonale et U U † = U † U = I est une matrice unitaire. MATLAB permet d’ob-
tenir la décomposition spectrale comme suit (dans cet exemple, on s’assure que D
est normale en l’additionnant à son adjoint de sorte à ce qu’elle soit Hermitique)
>> D = D+D’;
>> [U,Lambda] = eig(D)

U =

0.1999 - 0.5753i -0.4853 + 0.0528i 0.2476 - 0.0722i -0.1271 - 0.5551i


-0.0313 - 0.3545i 0.8354 - 0.0103i 0.0254 + 0.0010i 0.1364 - 0.3952i
-0.3122 - 0.1423i -0.2157 - 0.0092i -0.8027 + 0.0728i 0.3658 - 0.2285i
-0.6203 -0.1310 0.5322 0.5612

Lambda =

-11.4616 0 0 0
0 -0.1216 0 0
0 0 0.6080 0
0 0 0 15.6906
On remarque ici que la fonction eig produit deux réponses (la matrice contenant
les valeurs propres et celle contenant les vecteurs propres). Cette fonction permet
d’utiliser un nombre variable de sorties, si on ne veut que les valeurs propres,
on utilise plutôt
>> Lambda2 = eig(D)

Lambda2 =

-11.4616
-0.1216
0.6080
15.6906
Cette fois, la fonction ne retourne que la diagonale de la matrice puisque les
autres éléments sont tous nuls. On passe facilement d’une représentation à
l’autre à l’aide de la fonction diag
>> diag(Lambda)

ans =

-11.4616
-0.1216
0.6080
15.6906

11
>> diag(Lambda2)

ans =

-11.4616 0 0 0
0 -0.1216 0 0
0 0 0.6080 0
0 0 0 15.6906
Pour une matrice non-diagonalisable, eig retourne les vecteurs et valeurs
propres comme nous l’avons vu. Par contre, les vecteurs propres ne sont pas
linéairement indépendants, donc la matrice U ne serait pas unitaire, ni même
inversible.

3.1.6 Fonctions analytiques


Les fonctions analytiques de matrices sont définies à partir de leur décomposition
spectrale, par exemple si D = U ΛU † , alors f (D) = U f (Λ)U † où f (Λ) s’obtient
en remplaçant chaque élément de la diagonale de Λ par la fonction évaluée à
cette valeur. Les fonctions de matrices sont définies en MATLAB avec le suf-
fix m (pour matrice). Ainsi, expm, sqrtm et logm sont quelques exemples de
fonctions matricielles. Le m est crucial, par exemple on vérifie que si —tt A
est une matrice positive, sqrtm(A*A) = abs(A) alors que sqrt A*A ne l’est pas
puisqu’il retourne la racine carrée de chaque élément.

>> A = A+eye(size(A))*abs(min(eig(A)));
>> norm(sqrtm(A*A)-A)

ans =

1.8119e-15

>> norm(sqrt(A*A)-A)

ans =

1.8502

3.1.7 Éléments d’une matrice


On accède aux éléments d’une matrice à l’aide de parenthèses, par exemple
A(2,3) retourne l’élément correspondant à la deuxième ligne et la troisième
colonne de A. Lorsque la matrice est un vecteur, c’est-à-dire lorsque le nombre
de lignes ou de colonnes est égal à 1, on ne spécifie qu’un seul indice. Nous
pouvons utiliser cette notation pour lire un élément ainsi que pour le modifier :

12
>> A(2,3)

ans =

0.7314

>> A(2,3) = 3

A =

0.4237 0.1538 0.7883 0.3294


0.8035 0.6031 3.0000 0.8815
0.1124 0.7876 0.9797 0.1105
0.0453 0.1185 0.6286 0.3511
Il est possible d’accéder à une ligne ou colonne entière en utilisant les deux
points :

>> A(:,2)

ans =

0.1538
0.6031
0.7876
0.1185

>> A(3,:)

ans =

0.1124 0.7876 0.9797 0.1105


Finalement, on peut accéder à toute sous-matrice d’une matrice en spécifiant
les indices dans un vecteur

>> A([2:4],[1,3])

ans =

0.8035 3.0000
0.1124 0.9797
0.0453 0.6286
qui retourne l’intersection des lignes 2 à 4 et des colonnes 1 et 3.

13
3.1.8 Matrices éparses
Lorsque la majorité des éléments d’une matrice sont nuls, il est plus pratique
de mettre la matrice en mémoire sous une autre forme. En gros, plutôt que de
spécifier la valeur de chaque élément, on spécifie uniquement que la valeur des
éléments non-nuls ainsi que leur emplacement.
>> C = [0 3.1 0 0 1.3; 2 0 0 0 0; 0 0 0 2.9 0]

C =

0 3.1000 0 0 1.3000
2.0000 0 0 0 0
0 0 0 2.9000 0

>> sparse(C)

ans =

(2,1) 2.0000
(1,2) 3.1000
(3,4) 2.9000
(1,5) 1.3000

Certaines opérations algébriques, telle l’addition, sont beaucoup plus rapides


lorsque la matrice est stockée de façon éparse. Un bon nombre de fonctions
sont adaptées au cas de matrices éparses. Dans certains cas elles sont affligées
d’un préfixe sp (pour «sparse»). Par exemple speye crée une matrice identité
stockée sous forme éparse. La fonction full sert à convertir du stockage éparse
au format régulier.

3.2 Écriture et lecture


La commande save sert à sauvegarder les variables en mémoire dans MAT-
LAB dans un fichier. Si on désire enregistrer toutes les variables, on utilise save
nomdefichier.mat. Si on désire enregistrer que certaines variables, disons var1
et var2, on utilise save nomdefichier.mat var1 var2. On peut alors quitter
MATLAB et récupérer les données lors de notre prochaine session à l’aide de la
commande load nomdefichier.mat. Il est à noter que l’écriture et la lecture
se font directement dans le répertoire courant. On peut spécifier un parcours
différent et changer de répertoire en utilisant la même syntaxe que dans linux,
par exemple load ../documents/monprojet.mat et cd ../home/documents/.
Le fichier généré par la fonction save n’est reconnaissable que par MATLAB.
Si on désire enregistrer les données afin qu’elles soient lisibles par un humain,
on utilise plutôt save nomdefichier.mat var1 -ascii. Pour un plus grand
contrôle de l’écriture dans un fichier, par exemple pour préparer un fichier de
résultats, on utilise la fonction fprintf. Par exemple, les commandes

14
>> txt = fopen(’fichier.txt’,’w’);
>> fprintf(txt,’voici la matrice A:’);
>> fprintf(txt,’%10.5f %10.5f %10.5f %10.5f \n’,A);
>> fclose(txt);
produisent un fichier fichier.txt dans le répertoire courant dont on devine le
contenu.

3.3 Graphique
MATLAB possède un riche environnement graphique. La fonction plot sert
à tracer des courbes à partir de données stockées dans des vecteurs ou matrices.
>> clear all;
>> x=[0:0.1:20];
>> plot(x, [cos(x); 1./(2+sin(x)).^2]);

À partir de cet interface, on peut facilement contrôler les paramètres du


graphique en se servant de la souris. On peut ajouter des titres aux axes, changer
la police des caractères, ajouter une légende, passer à une échelle logarithmique,
modifier le style des courbes, etc. Ces options peuvent également être spécifiées
à partir du terminal, par exemple
>> xlabel(’Temps’);
>> ylabel(’Puissance’, ’fontsize’,14);
ajoute le titre «Temps» à l’abscisse et «Puissance», de taille 14 points, à l’or-
donné.

15
La rubrique d’aide de la fonction plot est un bon point de départ pour
apprendre les différentes options graphiques. Il est à noter que l’environnement
graphique de Octave n’offre pas la possibilité de contrôler les paramètres d’un
graphique avec la souris : il faut donc tout spécifier à partir de la console.
Sous l’onglet «File» de la fenêtre graphique, on retrouve la commande «Ge-
nerate M-file» qui génère les commandes de terminal nécessaires pour repro-
duire le graphique. Cela constitue une bonne façon d’apprendre les commandes
graphiques et est très pratique lorsque l’on doit produire plusieurs graphiques
avec des données différentes mais suivant toutes le même style. Dans ce cas, on
peaufine un premier graphique, génère les commandes de terminal qui lui sont
associées et pouvons ainsi automatiser la production des autres graphiques.
MATLAB offre également la possibilité de générer des graphiques en trois
dimensions. Les fonctions plot3, contour, contour3, bar3, mesh et surf en
sont quelques exemples.
>> f = @(x,y)(exp(-(x-1).^2-(y-1).^2) - 0.3*exp(-(x+y).^2));
>> [X,Y] = meshgrid(-3:0.1:3,-3:0.1:3);
>> surfc(X,Y,f(X,Y))

On peut générer une image en une variété de formats à partir d’un graphique
à partir de l’onglet «File» et «Save As». On peut créer une seconde fenêtre
graphique sans affecter le contenu d’une première à l’aide de la commande
figure(2) et ainsi de suite.

16
4 Les scripts
Un script est simplement une séquence de commandes que l’on regroupent
dans un fichier plutôt que de les entrer au terminal. Le nom du fichier doit se
terminer par «.m». Une bonne habitude consiste à choisir un nom de script
qui nous informe du contenu de celui-ci et de bien commenter les scripts. Il est
également important d’éviter des noms de fonctions pré-définies dans MATLAB
afin d’éviter les conflits. Le contenu du fichier doit être sauvegardé en format
ascii, comme le permet tout éditeur de texte de base. La séquence de commandes
est exécutée en entrant le nom du script dans le terminal MATLAB. Il est
nécessaire pour cela de se trouver dans le même répertoire que le script ou
d’indiquer le chemin complet du répertoire où se situe le script. Par exemple,
nous pouvons créer un fichier «/user/home/mon script.m» et y inscrire les lignes
suivantes :

% Définition des deux matrices


A = [1 2; 3 4]
B = [0.1 0.3; -0.1 2.2]
% Addition des matrices
C = A+B
% Multiplication des matrices
D = A*B;
%Division des résultats
E = C/D
On s’assure d’abord que le terminal MATLAB est dans le bon répertoire, cd
/user/home/. Ensuite on entre le nom du script, ce qui produit
>> mon_script

A =

1 2
3 4

B =

0.1000 0.3000
-0.1000 2.2000

C =

1.1000 2.3000
2.9000 6.2000

17
E =

-21.8000 10.8000
-57.5000 28.5000
On remarque que la ligne D = A*B ; n’a pas générée d’écriture au terminal, ce
qui s’explique par le point-virgule. Les lignes débutant par le symbole % sont
des commentaires. Il est important de bien commenter les scripts afin de s’y re-
trouver soi-même et afin qu’ils soient compréhensibles pour d’autres utilisateurs
potentiels.
Afin de répéter l’exécution d’un certain nombre de commandes un grand
nombre de fois, on peut utiliser une boucle for. Par exemple, le script suivant
calcule
P∞ une approximation au cosinus basée sur la série de Taylor cos(x) =
j (
j=0 (−1) x 2j)/j!.

% Série de taylor pour l’approximation de cos(x), nombre fixe de termes

n = 5; % Nombre de termes dans la série


x = 0.22; % Point où est évaluée la fonction

cos_n = 1;
for j=1:n
cos_n = cos_n + (-1)^j * x^(2*j)/factorial(2*j);
end

cos_n
Dans cet exemple, nous avons défini les paramètres n et x à l’intérieur du script.
Il est également possible de définir ces paramètres dans le terminal avant de faire
appel au script. Cela est un aspect très important des scripts qui les distinguent
des fonctions : les variables utilisées dans les scripts et celles utilisées en
mode interactif sont les mêmes. Ainsi, un script peut accéder aux variables
définies en mode interactif et modifier leurs valeurs. À l’inverse, toutes les va-
riables définies dans un script demeurent accessibles en mode interactif suite à
l’exécution du script. Par exemple, si on tape j au terminal suite à l’exécution
du script ci-haut, on obtient ans = 5, ce qui correspond bien à la dernière va-
leur assignée à j par le script. Cette possibilité d’accéder de façon interactive
aux variables d’un script est très utile au développement et déverminage d’un
programme.
De façon plus générale, on peut utiliser la boucle for avec les paramètres
de boucle de forme j = j init:dj:j final qui représentent respectivement la
valeur initiale, l’incrément et la valeur finale de j dans la boucle. La commande
while est utilisée lorsque la boucle doit être répétée conditionnellement à la
valeur d’un énoncé. Par exemple, on peut modifier le script précédent afin de
calculer le cosinus à une précision donnée.
% Série de taylor pour l’approximation de cos(x), précision requise

18
precision = 1.0e-18; % Précision requise
x = 0.22; % Point où est évaluée la fonction

cos_n = 1;
dcos = 1;
j = 0;
while abs(dcos) > precision
j = j+1;
dcos = (-1)^j * x^(2*j)/factorial(2*j);
cos_n = cos_n + dcos;
end

cos_n
j
L’appel du script produit cos n = 0.9759 et j = 7. La boucle se termine
lorsque la condition abs(dcos) > presision retourne la valeur 0, ce qui cor-
respond à faux. Une condition est en général une variable binaire que l’on peut
construire à l’aide de relations entre expressions arithmétiques. Les opérateurs
de relation sont == pour l’égalité, <= pour plus petit ou égal, ∼= pour la non-
égalité, etc. Les conditions peuvent également se combiner à l’aide d’opérateurs
logiques «et» &, «ou» | et la négation ∼.
Finalement, les commandes if, else et elseif permettent d’exécuter un
ensemble de commandes conditionnellement à une condition :
% Vérifie si le nombre N est composé ou premier
N_max = 1000; % facteur maximal

facteurs = [];
M = N;
j=2; % premier facteur que l’on vérifie
while j < min(N_max,ceil(sqrt(M))) %Facteurs sont inférieurs à la racine carré du nombre
if mod(M,j) == 0
facteur = 1;
facteurs = [facteurs,j];
M = M/j;
else
j = j+1;
end
end

if numel(facteurs) == 0 & sqrt(N) > N_max


’N est premier ou ses facteurs sont plus grand que Nmax’
elseif numel(facteurs) == 0
’N est premier’
else

19
[facteurs,M]
end
On tape N = 103857 et appel ce script, ce qui produit ans = 3 13 2663, alors
que l’entrée N = 13 produit ans = N est premier et finalement N = 2∧20-3
donne ans = N est premier ou ses facteurs sont plus grand que Nmax.
Il est à noter que les commandes for, if et while peuvent être utilisées en mode
interactif également, quoi que cela est moins naturel. Comme nous l’avons vu,
les boucles sont très lentes. Il est donc préférable d’utiliser des opérations ma-
tricielles lorsque cela est possible. Par exemple, le script calculant les n premiers
termes de la série de Taylor du cosinus est beaucoup plus rapide sous la forme
% Série de taylor pour l’approximation de cos(x), nombre fixe de termes

n = 5; % Nombre de termes dans la série


x = 0.22; % Point où est évaluée la fonction

j = [1:n];
cos_n = 1 + sum((-1).^j .* x.^(2*j) ./ factorial(2*j))

5 Les fonctions
Nous avons déjà rencontré un bon nombre de fonctions pré-définies dans
MATLAB, par exemple la fonction cos. Il est également possible de définir ses
propres fonctions. Cela est très similaire à la création d’un script. Toutefois, les
variables définies à l’intérieur d’une fonction sont distinctes de celles définies en
mode interactif ou dans des scripts et elles sont détruites lorsque l’exécution de
la fonction est terminée. Ainsi, une fonction doit avoir des entrées et des sorties
bien définies. Cela se fait à la première ligne du fichier contenant la descrip-
tion de la fonction qui doit être de la forme fonction variable de sortie =
nom de la fonction(variables entrée). Le nom du fichier doit être le même
que le nom de la fonction, suivi de l’extension .m. Par exemple, on peut transfor-
mer notre script calculant les n premiers termes de la série de Taylor du cosinus
et en faire une fonction
% Série de taylor pour l’approximation de cos(x), nombre fixe de termes
function y = cos_n(x,n)
% x est le point où est évaluée la fonction
% n est le nombre de termes dans la série
% y retourne le résultat

j = [1:n];
y = 1 + sum((-1).^j .* x.^(2*j) ./ factorial(2*j));
À partir du terminal, on peut faire l’appel w = cos n(0.22,5), ce qui produit
le résultat y = 0.9759. La variable j n’est pas affectée par l’exécution de cette
fonction.

20
Il est également possible de créer des fonctions à plusieurs variables de sorties.
Nous avons déjà rencontré la fonction eig qui retourne les vecteurs propres et les
valeurs propres d’une matrice. De façon générale, il suffit de placer les multiples
variables de sortie entre crochets dans la définition et dans l’appel de la fonction.
Par exemple, on peut déterminer les racines d’une fonction quadratique à l’aide
de la fonction
% Trouver les racines d’une fonction quadratique
% ax^2 + bx + c étant donnés les coefficients a, b et c.
function [x1,x2] = racine_quad(a,b,c)

d = b*b-4*a*c;
r1 = (-b+sqrt(d))/(2*a);
r2 = (-b-sqrt(d))/(2*a);
que l’on appelle avec la commande [r1,r2] = racine quad(a,b,c).

5.1 Fonctions anonymes


Il est possible de définir une fonction sans créer un fichier qui lui est associé.
La syntaxe à utiliser est la suivante nom de fonction = @(liste des arguments)
expression. Cela peut se faire directement dans le terminal, dans un script ou
même dans une fonction. Par exemple, on entre dans le terminal

>> cosXtanY = @(x,y) cos(x)*tan(y);


>> cosXtanY(0.3,2.4)

ans =

-0.8751

Les fonctions anonymes permettent également de passer une fonction en tant


qu’argument d’une autre fonction. Par exemple, la recherche du minimum d’une
fonction dans un intervalle donné peut se faire à l’aide de la fonction fminbnd
qui prend comme entrée la fonction à minimiser et l’intervalle en question. Par
exemple, on trouve le minimum de la fonction f (x) = sin(x2 ) + (1 − x)2 dans
l’intervalle [0,1] comme suit.
>> f = @(x) sin(x^2)+(1-x)^2;
>> fminbnd(f,0,1)

ans =

0.5084

21

Vous aimerez peut-être aussi