COURTE INTRODUCTION A MATLAB
Contenu
Mise en route
Pour creer un raccourci de l'application Matlab, ajouter dans votre fichier .profile les lignes suivantes
# Set PATH variable
export PATH=/Applications/MATLAB_R2012b.app/bin:$PATH
Si le fichier .profile n'existe pas vous pouvez le creer. Relancez ensuite la fenetre de terminal pour que le raccourci fonctionne.
A l'invite de commande dans votre fenetre de terminal, tapez matlab pour lancez Matlab en mode graphique. Pour lancez Matlab en ligne de commande seulement (sans fenetre), tapez matlab -nodesktop. Ce tutoriel suppose que vous avez lance Matlab en mode graphique.
Elements de l'interface graphique
La fenetre Matlab est divisee en plusieurs espaces qui peuvent etre configures. L'espace le plus important est la Command Windows. Cette fenetre permet d'executer des commandes Matlab. L'autre espace important est l'editeur de texte, qui vous permet d'editer des fichier qui pourront etre executes par Matlab.
Philosophie
Matlab, qui est l'abbreviation de matrix laboratory, est optimise pour manipuler des matrices. Pour en tirer partie, il faut vectorialiser les expressions. En C, pour initialiser un vecteur x qui prendra les valeurs de l a 1000000 (un million), on procede de la facon suivante:
double *x; int i, sizex = 1000000; x = malloc(size*sizeof(double)); for ( i = 0; i < sizex; i++) { x[i] = i+1.0; }
Sous Matlab, la meme procedure se fait de la facon suivante:
x = 1:1000000;
L'initialisation est vectorialisee: le membre de droite (1:1000000) est le vecteur 1 a 1000000 est l'assignation se fait de vecteur a vecteur.
Notez qu'il n'est pas necessaire de declarer la variable x, elle est cree lors de l'initialization. Le type sera automatiquement un array de double:
class(x)
ans = double
Contrairement a C, les expressions n'ont pas a se terminer par un ;. Si le ; est omis, le resultat de l'expression sera affiche dans la Command Windows. L'expression
1+1;
ne produit aucin effet (mais le resultat est stocke dans une variable appelee ans). L'expression
1+1
ans = 2
renvoie le resultat escompte: 2.
Les valeurs scalaires sont des arrays 1x1, et ne sont pas different des arrays representant des vecteurs ou des matrices.
On aurait pu initialiser x comme en C, mais cela aurait ete beucoup plus long. Les commandes tic et toc permettent de calculer un intervalle de temps ecoule:
clear x; % on efface la variable x tic x = 1:1000000; toc
Elapsed time is 0.003285 seconds.
Maintenant, avec la boucle for
clear x; tic for i = 1:1000000 x(i) = i; end toc
Elapsed time is 0.573735 seconds.
La boucle for est beaucoup plus lente que l'assignation vectorielle! Conclusion, si on peut, on evite les boucles for en Matlab.
Variables, vecteurs, matrices
La type de variable de base de Matlab est l'array de double. Il existe d'autres types (class en Matlab) comme les char, cell, struct, int8, etc, mais les double sont utilisees la plupart du temps. Comme les variables creees sont de classe double par defaut, on suppose qu'on travaillera en double dans ce tutoriel. Un array de double A peut comporter plusieurs dimensions. Pour un array de dimension 2, c.-a-d. un matrice (le defaut), on accede a l'entree ligne i, colonne j par A(i,j). (Comparer a C: A[i-1][j-1].)
Voici un liste de commandes pour creer des vecteurs (mx1 pour un vecteur colonne, et 1xn pour un vecteur ligne).
m = 10; n = 10; xcol = ones(m,1); % cree un vecteur colonne de dimension 10 avec UNs partout xline = ones(1,n); % cree un vecteur ligne de dimension 10 avec UNs partout ycol = (1:m)'; % cree un vecteur colonne des entiers de 1 a m. Le ' est l'adjoint yline = 1:n; % cree un vecteur ligne des entiers de 1 a n. z1 = linspace(0,1,n); % cree le vecteur ligne des n doubles espaces lineairement entre 0 et 1. h = 1/(n-1); % definit la distance entre deux elements de z1 z2 = 0:h:1; % autre facon de definir le meme vecteur, mais attention aux erreurs d'arrondis! isequal(z1,z2) % on teste pour savoir si |z1 == z2|, le resultat est FAUX.
ans = 0
pour connaitre les dimensions des variables xcol et xline, on peut utiliser les commandes length et size. La commande size renvoie la taille de chaque dimension
size(xcol) size(xline)
ans = 10 1 ans = 1 10
La commande length renvoie la plus grande taille seulement, ce qui est pratique pour des expressions du type
mcols = length(xcol);
L'autre facon de connaitre l'etat des variables est la commande whos
whos
Name Size Bytes Class Attributes ans 1x2 16 double h 1x1 8 double i 1x1 8 double m 1x1 8 double n 1x1 8 double x 1x1000000 8000000 double xcol 10x1 80 double xline 1x10 80 double ycol 10x1 80 double yline 1x10 80 double z1 1x10 80 double z2 1x10 80 double
Cette commande affiche toutes les variables du workspace courant. Le workspace contient les variables definies par l'utilisateur.
De la meme facon que les vecteurs, on peut creer des matrices mxn.
A = ones(m,n); % cree une matrice 10x10 avec UNs partout Ar = rand(m,n); % cree une matrice 10x10 avec nombres aleatoires entre 0 et 1 A = vander(z1); % cree une matrice carree de Vandermonde de taille length(z1)
Aide
Pour de l'aide sur une commande, tapez
help nom_de_la_commande
Par exemple, pour afficher l'aide sur la commande ones
help ones
ONES Ones array. ONES(N) is an N-by-N matrix of ones. ONES(M,N) or ONES([M,N]) is an M-by-N matrix of ones. ONES(M,N,P,...) or ONES([M N P ...]) is an M-by-N-by-P-by-... array of ones. ONES(SIZE(A)) is the same size as A and all ones. ONES with no arguments is the scalar 1. ONES(..., CLASSNAME) is an array of ones of class specified by CLASSNAME. Note: The size inputs M, N, and P... should be nonnegative integers. Negative integers are treated as 0. Example: x = ones(2,3,'int8'); See also EYE, ZEROS. Overloaded methods: distributed/ones codistributor2dbc/ones codistributor1d/ones codistributed/ones gpuArray/ones Reference page in Help browser doc ones
La ligne See also est utile pour trouver des commandes similaire. Ici on trouve les commandes zeros et eye qui permettent d'initialiser des matrices (ou vecteurs) de zeros et la matrice identite.
Principales commandes et syntaxe sur les vecteurs et matrices
a = 2.0 % assigne la valeur 2 a la varialble a (a == 2) % teste l'egalite entre 2 et a find(x == 200) % trouve entrees i verifiant l'expression logique x(i) == 200 find(x < 10) % trouve entrees i verifiant l'expression logique x(i) < 10 A*xcol % multiplication matrice*vecteur xline*A % multiplication vecteur*matrice A\x % division a gauche (equivalent a A^(-1)*x) A(:,1:2:end) % colonnes impaires de A A([1 2 5 6],:) % lignes 1, 2, 5, et 6
Fonctions et scripts
Les fonctions Matlab sont le plus souvent ecrites dans un fichier texte separe. Le nom du fichier est le nom de la fonction. La fonction du fichier mafonction.m sera donc appelee par la commande mafonction. Construisons un fonction qui prend en argument deux vecteurs de meme taille, x et y, et qui renvoie les coefficients du polynome de degre n qui interpole au sens des moindres carres y aux points x: y ~ p(x).
edit monpolyfit.m
La premiere ligne doit etre
function p = monpolyfit(x,y,n)
Le mot cle function indique que le fichier est une fonction. p est la la variable retournee par la fonction et (x,y,n) sont les arguments de la fonction. La notation function [p1, p2] = mafonction(x,y) est utilisee s'il y a plusieurs variables de sortie et function mafunction(x,y) est utilisee si il n'y a pas de variable de sortie (pour une fonction qui genererait un graphique ou un fichier, par exemple).
La deuxieme ligne devrait etre un ligne descriptive de la fonction, et est en commentaire:
% MONPOLYFIT interpolation polynomiale par moindres carres
Cette ligne est utilisee pour afficher les descriptions courtes des fonction lorque, par exemple la commande lookfor est utilisee. Les lignes suivantes, en commentaire, decrivent l'usage de la fonction. C'est le moment de mettre le See also, pour faire un lien vers d'autres fonctions Matlab. Ici on pourrait faire un lien vers la fonction polyfit de Matlab.
% See also POLYFIT
(Les majuscules ne se verront pas avec la commande help).
Ensuite viens le corps de la fonction. Tout d'abord on verifie que les deux vecteurs x et y sont des vecteurs de meme taille, et que n+1 est inferieur ou egal a la taille de y.
sx = size(x); sy = size(y); if min(sx)>1 % alors pas un vecteur error('monpolyfit:tailledonnees','X n''est pas un vecteur'); end if min(sy)>1 % alors pas un vecteur error('monpolyfit:tailledonnees','Y n''est pas un vecteur'); end if sx(2) ~= 1 % alors pas un vecteur colonne (~= : pas egal) x = x.'; % on transpose (pas conjugue) sx = size(x); % on recalcule la taille de x end if sy(2) ~= 1 % alors pas un vecteur colonne (~= : pas egal) y = y.'; % on transpose (pas conjugue) sy = size(y); % on recalcule la taille de y end if (sx(1)~=sy(1)) % verifions les tailles de X et Y error('monpolyfit:tailledonnees','Les tailles de X et Y ne correspondent pas'); end if (n+1)>length(x) error('monpolyfit:tailledonnees','Le degre n du polynome a ajuster est trop eleve, il doit etre inferieur a la longueur de X'); end
Maintenant on etablit notre equation normale pour les moindres carres. On genere un matrice de Vandermonde A a l'aide de x:
A = vander(x);
A est une matrice de taille length(x). On ne retient de la matrice que les n+1 dernieres lignes
m = sx(1); A = A(:,(m-n):m);
On cherche les coefficients du polynome p qui approximent le mieux A*p=y. L'equation normale (en notation Matlab) est A'*A*p = A'*y. Si on fait une decomposition QR de la matrice A, on obtient l'equation R*p = Q'*y. On resoud ces equations a l'aide des fonctions householder, Qadj et backsubs.
[W,R]=householder(A); Qy = Qadjb(W,y); p = backsubs(R(1:(n+1),1:(n+1)),Qy(1:(n+1)));
Le code est termine, pas besoin de terminer le fichier avec un return et un end. Le vecteur p est a ete defini et sera retourne par la fonction. Toutes les variables creees dans la fonction sont locales a cette fonction et ne peuvent etre vues a l'exterieur de celle-ci. Les variables sont detruites lors du retour de la fonction, a moins de declarer ces variables persistent. Cela pourrait etre utile, par exemple si on voulait faire plusieurs interpolations de meme degre avec le meme vecteur x. Il serait alors plus efficace de ne pas recalculer A est sa decomposition a chaque appel de la fonction.
Pour resoudre un probleme, il est utile d'ecrire dans un fichier la liste des commandes a faire. Ce fichier n'est qu'une liste d'expressions a evaluer par Matlab. Tout fichier avec l'extension .m dans le chemin de Matlab peut etre appele de l'invite de commande. Un fichier .m est un fichier script si il ne commence pas par function. Les fichiers script sont executes ligne par ligne et les variables sont dans le workspace.
On cree un fichier script appele fit_polynome.m
edit fit_polynome.m
La premiere ligne devrait etre une description du fichier en commentaire:
%% fit_polynome: script pour ajuster un polynome a des donnees
Ensuite on definit les vecteur x et y.
x = 10*rand(34,1); % 34 points aleatoires dans l'intervalle [0, 10]; y = 10*rand(34,1) + x; % 34 points aleatoires correles avec x n = 3; % interpolation avec un polynome de degre 3 p = monpolyfit(x,y,n); % on trouve le polynome qui s'ajuste le mieux
En executant le script fit_polynome, on obtient le polynome p demande. Toutes les variables definies dans le script se retrouvent dans le workspace.
Graphiques
Matlab possede plusieurs commandes pour visualiser des donnees. Pour tracer des donnes en 2D, on utilise la commande plot. Rajoutons dans le fichier script fit_polynome les commandes pour visualiser les nuages de points (x,y) et le graphe du polynome p.
%% Visualisation 2D des donnees figure(1); % cree ou active la figure 1 clf; % clf efface la figure plot(x,y,'s') % trace les points avec des carres ('s' pour square) hold on % les prochains appels a plot n'effaceront pas les autres r = max(x)-min(x); % l'etendue de x a = min(x) - 0.1*r; % limite inferieure sur x pour tracer le polyome b = max(x) + 0.1*r; % limite superieure sur x pour tracer le polyome xp = linspace(a,b,100); % 100 points equirepartis sur [a,b] plot(xp,polyval(p,xp)) % trace le graphe de p aux valeurs xp xlabel('x') % etiquette abscisse ylabel('y') % etiquette ordonnees legend('donnees','polynome',2) % legende, les etiquettes sont dans % l'ordre d'aparition des plots
Pour voir le resultat, on execute le script,
fit_polynome

Resoudre un systeme d'equations differentielles ordinaires
Matlab possede plusieurs solveurs EDO, dont une suite edo*. Le solveur multi-usage a utiliser par default est ode45 (prononce ode quatre cinq) un solveur Runge-Kutta a pas de temps adaptatif d'ordre 4 et 5. Les autres solveurs utiles sont ode23, un solveur d'ordre ode15s. Tous les solveurs ont la meme syntaxe:
[t,x] = ode45(@monedo,[t0 tfinal],CI); sol = ode45(@monedo,[t0 tfinal],CI);
La premiere syntaxe renvoie la solution x au temps t. La deuxieme syntaxe renvoie une structure sol qui contient la solution ainsi que des informations sur le solveur utilise. La fonction monedo est une fonction Matlab qui definit le systeme d'EDO. Le systeme est integre sur l'intervalle [t0 tfinal], avec conditions initiales CI. L'equation differentielle est de la forme
avec un vecteur de taille
. La fonction EDO doit suivre une structure bien definie, avec une premiere ligne
function dxdt = monedo(t,x)
La fonction prend en argument le temps t et l'etat du systeme x. La variable x est un vecteur colonne de taille n. La fonction retourne la derivee de x au temps t dans dxdt un vecteur colonne de taille n. Les conditions initiales sont un vecteur de la meme dimension que x. Comme premier exemple, on prend le systeme de Lotka-Volterra. La fonction lotkavolterra.m specifie le systeme suivant:
Le systeme est resolu de la facon suivante:
CI = [30; 2]; tspan = [0 20]; sol = ode23(@lotkavolterra,tspan,CI);
On trace la solution a l'aide de deval, qui permet d'evaluer la solution sol a n'importe quel temps.
xint = linspace(0,20,200); yint = deval(sol,xint); figure(2); clf; plot(xint,yint) xlabel('temps'); ylabel('population');

Dans cet exemple, il n'est pas possible de facilement changer les parametres du systeme, qui sont code dans le fichier lotkavolterra.m. De plus, pour chaque resolution du systeme, il faut definir les conditions initiales et l'intervalle d'integration. Un fichier script peut aider, mais ne permet pas d'acceder aux parametres, qui sont variables locales a lotkavolterra. Un moyen de s'en sortir est d'utiliser une fonction imbriquee. Une fonction imbriquee est une sous-fonction, mais qui partage certaines variables avec la fonction principale dans laquelle elle se trouve.
A lieu de definir un script pour resoudre le systeme d'EDO, on definit une fonction run_lotka.m
function sol = run_lotka() % RUN_LOTKA simulation du systeme de Lotka-Volterra
% parametres d'integration
CI = [30; 2];
tspan = [0 20];
% parametres du systeme pars = [0.1 1 2 ]; % Les variables a, b, c, d sont partagees b = 0.01; % avec la fonction imbriquee lotka c = 1; d = 0.02;
% resolution du systeme pour 3 jeux de parametres differents for i = 1:3 a = pars(i); % on met a jour la valeur de a sol{i} = ode23(@lotka,tspan,CI); end
% plot des 3 solutions nx = 200; xint = linspace(tspan(1),tspan(2),nx); figure(2); clf; newplot; % met en place un nouveau plot hold on % qui ne s'effacera pas a chaque appel de plot cols = 'kbr'; % couleurs k: noir, b: bleu, r:rouge for i = 1:3 yint = deval(sol{i},xint); plot(xint,yint,'Color',cols(i)) end xlabel('temps'); ylabel('population');
function dxdt = lotka(~,xx) % fonction imbriquee % LOTKA systeme d'EDO
x = xx(1); y = xx(2);
dxdt = [ x * (a - b * y) -y * (c - d * x)]; end % on termine d'abord la fonction imbriquee
end % on termine ensuite la fonction principale
De cette facon, on peut resoudre le systeme pour n'importe quelle condition initiale, intervalle de temps et parametres du systeme. Le fichier run_lotka.m peut etre lance:
run_lotka;

Codes
Les fichiers matlab peuvent etre telecharges ici: householder.m, Qadjb.m, backsubs.m, lotkavolterra.m, run_lotka.m
La démo enti�re peut �tre téléchargée ici: tutorielmatlab.m. Ce fichier est un fichier script, qui peut exécuté par la commande tutorielmatlab, mais vous pouvez aussi l'exécuter en mode démo avec la commande echodemo tutorielmatlab. Assurez-vous d'avoir tous les fichiers nécessaires dans votre répertoire courant.