Académique Documents
Professionnel Documents
Culture Documents
, PNT ,MEC
Initiation à Matlab
M. AFIFI
1
1. Généralités
MAT (matrix) LAB (laboratory) est un logiciel puissant doté à la fois d'un langage de
programmation haut niveau et d'outils dédiés au calcul numérique et à la visualisation numérique.
Développé en C par la société Mathworks, Matlab était initialement destiné à faire simplement du
calcul matriciel. Actuellement, Matlab recouvre d'autres domaines d'applications de l'informatique
scientifique :
visualisation graphique 2D et 3D
optimisation
traitement du signal
traitement de l'image
etc …
Matlab est un outil puissant qui permet la résolution de nombreux problèmes en beaucoup
moins de temps qu'il n'en faudrait pour les formuler en C ou en Pascal.
Matlab se divise en deux parties :
le noyau Matlab, qui comprend :
l'environnement de travail offrant plusieurs facilités pour la manipulation des données. Son
interpréteur permet de tester rapidement ses propres programmes Matlab.
le système graphique Matlab (interfaces homme-machine, graphiques, images, animations).
le langage de programmation Matlab.
une librairie de fonctions mathématiques Matlab.
un système d'interfaçage facilitant l'exécution de programmes C ou Fortran sous Matlab.
une collection de toolboxes (boîtes à outils) regroupant un ensemble de fonctions spécifiques à un
thème.
C'est un langage interprété, c'est-à-dire que les instructions sont exécutées immédiatement après
avoir été introduites. Il n'est pas nécessaire de compiler un programme avant de l'exécuter et toute
commande introduite dans la fenêtre de commande est immédiatement exécutée. C'est dans cette
fenêtre que l'on peut écrire les instructions Matlab (à la suite des chevrons >>).
La réponse est affichée et stockée dans la variable ans (answer en anglais est la réponse).
La plupart des fonctions mathématiques usuelles sont définies dans Matlab, et ceci sous une
forme naturelle (sin, cos, exp, ...). de même que certaines constantes (pi ...).
>> 2*sin(pi/4) ans = 1.4142
1.1. Variables
On peut indiquer le nom de la variable dans laquelle le résultat doit être stocké (commence par
une lettre, moins de 19 caractères).
2
>> x = pi/4 x = 0.7854
Le nom de cette variable ainsi que le résultat sont affichés.
Un point-virgule à la fin de la ligne permet de ne pas afficher ce résultat.
On peut taper plusieurs commandes par ligne, séparées par un point-virgule.
>> x = pi/2; y = sin(x);
Il existe un certain nombre de variables prédéfinies : pi inf i realmin realmax eps ans
>> eps ans = 2.2204e-16
>> realmax ans = 1.7977e+308
>> realmin ans = 2.2251e-308
3
On peut remarquer que la taille du vecteur x a été ajustée en remplissant les éléments non précisés
par 0.
On peut aussi créer des matrices avec les fonctions zeros, ones, rand et eye, ces fonctions créent
des matrices de la taille précisée, respectivement remplies de zéros, de un, et de un sur la diagonale
et des zéros ailleurs (eye = prononciation anglaise de I comme identité).
>> length (x) ans = 5 C’est en fait sup (nb de lignes, nb de colonnes)
Concaténation
On peut ajouter des lignes et des colonnes à des matrices déjà existantes.
>> r1 = [10, 11, 12];
1 2 3
>> A = [A ; r1] A = 4 5 6
7 8 9
10 11 12
>> r2 = zeros(4,1);
1 2 3 0
>> A = [A, r2] A = 4 5 6 0
7 8 9 0
10 11 12 0
Transformations de Matrice
On peut avoir le transposé ou le transposé conjugué d'une matrice :
>> A' % Transposée conjuguée de A
>> A.' % Transposée de A
4
mais aussi des retournements horizontaux (flipud : Up/Down), verticaux (fliplr :
Left/Right), ou des rotations de matrices :
7 8 9
>> A = [1, 2, 3 ; 4, 5, 6 ; 7, 8, 9] ;flipud(A) % Retournement vertical de A 4 5 6
1 2 3
3 2 1
>> fliplr(A) % Retournement horizontal de A 6 5 4
9 8 7
3 6 9
>> rot90(A) % Rotation de A de 90 degrés 2 5 8
1 4 7
On peut également remettre en forme des matrices et vecteurs sur un nombre de lignes et de
colonnes donnés (à condition que le nombre total d'éléments corresponde) :
>> B = [ 1 2 3 4 5 6 ];
5
>> A(:) % Vecteur colonne contenant tous les éléments lus colonne par colonne.
>> A = [ 1, 2, 3 ; 4, 5, 6 ; 7, 8, 9 ];
Cancatenation
>> ch1 = ‘ Flane ’;
>> n=size(ch,2)-size(ch1,2);
Conversions
6
On peut convertir des nombres en chaîne de caractères à l'aide des fonctions
num2str : nombre chaîne
str2num : chaîne nombre
double ou abs : chaîne codes ascii
char ou setstr : codes ascii chaîne
>> text = sprintf(‘ le carré de pi vaut %3.2f ’, pi2) text = le carré de pi vaut 9.87
On peut même écrire des caractères spéciaux comme retour à la ligne : \n et tabulation : \t
Comparaison de chaînes
>>s2=lower(s1);
>>strcmp(s1,s2) ans = 0
>>strcmpi(s1,s2) ans = 1
>>strncmp(s1,s2,8) ans = 1
7
strmatch(str,T) : renvoie les numéros de lignes qui commence par str
findstr(s1,s2) : renvoie les indices de début de la chaîne la plus courte dans l’autre
Deux fonctions peuvent être très utiles lors de manipulations de chaînes de caractères : eval et
feval. Si l'on possède une instruction Matlab dans une chaîne de caractères, la commande eval
évaluera cette chaîne de caractères comme si elle avait été introduite à la ligne de commande de
Matlab :
>> eval([ nom-var, '1 = sqrt(-1)']) x1 = 0.0000 + 1.0000i
2. Opérations matricielles
Les opérations usuelles sont définies de façon naturelle pour les matrices :
8
>> inv(A) % Inversion d'une matrice carrée inversible (message % d'alerte éventuel)
La plupart des fonctions mathématiques n'ayant pas de signification particulière pour des matrices
les considèrent comme un simple tableau de valeur, par exemple :
>> exp(A) renverra une matrice dans laquelle tous les éléments seront l'exponentielle des
éléments de A, de même pour log, sqrt, round, rem (correspond au modulo), sign. Pour calculer
l'exponentielle matricielle, le logarithme matriciel ou la racine carrée d'une matrice on utilisera
respectivement expm, logm et sqrtm.
Certaines fonctions de Matlab agissent indépendamment sur chaque colonnes de la matrice. C'est le
cas de la fonction max (et min ) :
>> max(A) renverra un vecteur ligne dont chaque élément sera le maximum (minimum) de la
colonne correspondante. C'est aussi le cas des fonctions sum, prod et median qui donnent
respectivement les sommes, produit, et la valeur médiane des colonnes de la matrice. Les fonctions
cumsum, cumprod et sort renvoient une matrice dont chaque colonne contient les sommes et
produits cumulés et un tri des colonnes de la matrice initiale.
D'autres fonctions sont très utiles sur les matrices :
>> [V, D] = eig(A) % Renvoie les vecteurs propres et les valeurs propres de A
9
3. Affichages graphiques
On voit que les axes s'adaptent automatiquement aux valeurs extrémales des abscisses et ordonnées.
On remarquera que tout ce que demande plot,
c'est un vecteur d'abscisses et un vecteur
d'ordonnées. Les abscisses peuvent donc être une
fonction de x plutôt que x lui même. En d'autres
termes, il est donc possible de tracer des courbes
paramétrées :>> plot(cos(x), sin(x))
10
Superposer plusieurs courbes
Il suffit de spécifier autant de couples (abscisses,
ordonnées) qu'il y a de courbes à tracer. Par
exemple pour superposer sin et cos :
>> plot(x,cos(x),x,sin(x))
Les deux courbes étant en réalité dans des couleurs différentes. Cette méthode fonctionne même si
les abscisses des deux courbes ne sont pas les mêmes. Dans le cas plus fréquent où les abscisses
sont les mêmes, il existe un autre moyen de superposer les courbes. On a toujours le vecteur des
abscisses, commun aux deux courbes, et on a autant de vecteurs d'ordonnées qu'il y a de courbes.
Tous ces vecteurs d'ordonnées sont regroupés plot ( vecteur d'abscisses, tableau d'ordonnées
dans un même tableau, chaque ligne du tableau
représentant un vecteur d'ordonnées :
Par exemple, pour superposer sin et cos, on devra fournir à plot les arguments suivants :
Lorsque l'on utilise seulement un style de points, MATLAB ne trace plus de droites entre les points
successifs, mais seulement les points eux même. Ceci peut être pratique par exemple pour présenter
11
des résultats expérimentaux. Les codes peuvent être combinés entre eux. Par exemple >>
plot(x,sin(x),':',x,cos(x),'r-.')
Décoration des graphiques
Titre : C'est l'instruction title à laquelle il faut fournir une
chaîne de caractéres2. Le titre apparaît en haut de la
fenêtre graphique :
>> plot(x,cos(x),x,sin(x)),
>>title('Fonctions sin et cos')
Tracer un quadrillage : C'est l'instruction grid, qui utilisé après une instruction plot affiche un
quadrillage sur la courbe.
Afficher plusieurs graphiques (subplot)
Il s’agit de découper la fenêtre graphique en pavés de même taille, et d'afficher un graphe dans
chaque pavé. On utilise l'instruction subplot en lui spécifiant le nombre de pavés sur la hauteur, le
nombre de pavés sur la largeur, et le numéro du pavé dans lequel on va tracer :
subplot (Nbre pavés sur hauteur, Nbre pavés sur largeur, Numéro pavé)
Les pavés sont numérotés dans le sens de la lecture d'un texte de gauche à droite et de haut en bas.
Une fois que l'on a tapé une commande subplot,
toutes les commandes graphiques suivantes seront exécutées dans le pavé spécifié.
Exemple :
>> subplot(2,2,1), plot(x,sin(x))
>> subplot(2,2,2),plot(x,cos(x),x,sin(x),'-.')
>> subplot(2,2,3),plot(cos(x),sin(x))
12
>> subplot(2,2,4),plot(sin(2*x),sin(3*x))
Axes et zoom
Il y a deux manières de modifier les valeurs extrêmes sur les axes, autrement dit de faire du
zooming sur les courbes. La plus simple est de la fenêtre graphique. Vous pouvez alors :
encadrer une zone à zoomer avec le bouton de gauche de la souris
cliquer sur un point avec le bouton de gauche. Le point cliqué sera le centre du zoom, ce dernier
étant effectué avec un facteur arbitraire
cliquer sur un point avec le bouton de droite pour dézoomer
Pour faire des zooms plus précis, utiliser la commande axis.
13
Une courbe en 3D est définie par une liste de
triplets (x; y; z). L'instruction correspondant plot3
attend donc trois arguments. Voici un exemple de
courbe 3d : >> plot3 (exp(-t/10).*sin(t),
exp(-t/10).*cos(t), exp(-t)), grid
3.1.2. Surfaces
Génération des points (meshgrid)
Pour définir une surface, il faut un ensemble de triplets (x; y; z). Le nombre de points nécessaires
pour tracer la surface est le produit de deux entiers m x n. Cela signifie que l'on a m x n valeurs de
x, m x n valeurs de y et m x n valeurs de z. Il apparaît donc qu’abscisses, ordonnées et cotes des
points de la surface peuvent être stockés dans des tableaux de taille m x n.
Toutes les instructions du tracé de la surface, par exemple surf auront donc la syntaxe suivante :
[ ] [ ]
x1 x2 . . . xm y1 y1 . . . y1
x1 x2 . . . xm y2 y2 . . . y2
X= . . . . . . Y= . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
x1 x2 . . . xm yn yn . . . yn
14
surf qui <peint> la surface avec une couleur
fonction de la cote
surfl qui <peint> la surface comme si elle était
éclairée.
surfc qui est comme mesh mais ajoute les
courbes de niveau dans le plan (x; y)
Notons enfin qu'il existe des fonctions de conversion entre les coordonnées cartésiennes,
cylindriques et sphériques, permettant de tracer facilement des courbes définies dans l'un de ces
systèmes de coordonnées. On regardera par exemple la documentation de cart2pol.
Contrôle de l'angle de vue
Il existe la commande view, mais le plus simple de points, elle met beaucoup de temps se
est de fenêtre graphique. Cliquez avec le bouton réafficher.
gauche de la souris pour faire tourner la figure.
ATTENTION : tout clic de la souris provoque un
réaffichage, et si votre surface contient beaucoup
15
4. Environnement de travail, scripts et fonctions
16
x1 y1 z1 ...
x2 y2 z2 ...
...
xn yn zn ...
Cette structure est obligatoire pour que la méthode simple exposée ici fonctionne correctement. Ce
fichier doit porter une extension, qui peut être quelconque, mais différente de .m ou .mat.
Admettons qu'il s'appelle toto.txt, tapez dans MATLAB :
>> load data.txt
Ce faisant, vous créez un nouveau tableau MATLAB, qui porte le nom du fichier sans extension,
soit data. Vous pouvez maintenant extraire les colonnes de ce tableau, et les mettre dans des
vecteurs, par exemple :
>> x = data(:,1); y = data(:,2); z = data(:,3)
et vous n'avez plus qu'à tracer l'un de ces vecteurs en fonction d'un autre.
4.3. Scripts
Il est parfois (souvent) souhaitable, pour ne pas avoir à taper plusieurs fois une même séquence
d'instructions, de la stocker dans un fichier. Ainsi on pourra réutiliser cette séquence dans une autre
session de travail. Un tel fichier est dénommé script.
Il suffit d'ouvrir un fichier avec le menu file, new, de taper la séquence de commande et de
sauver le fichier avec une extension " .m " (nom-fich.m). En tapant le nom du fichier sous Matlab, la
suite d'instructions s'exécute.
Les variables définies dans l'espace de travail sont accessibles pour le script. De même les
variables définies (ou modifiées) dans le script sont accessibles dans l'espace de travail.
On peut (doit) mettre des commentaires à l'aide du caractère pour-cent " % ". Toute commande
située après " % " n'est pas prise en compte par Matlab, jusqu'à la ligne suivante. De plus Matlab ne
voit pas les espaces blancs (lorsqu'il n'y a pas d'ambiguïté), ce qui permet de bien indenter ses
fichiers.
4.4. Fonctions
17
Exemple de fonction :
function y = sinuscardinal(x)
z = sin(x); % Variable de stockage
y = z./x; % Résultat de la fonction % Il faudra se méfier de la division pour x=0
Cette fonction pourra être appelée par :
>> sincpi = sinuscardinal(pi);
Exemple de fonction à plusieurs variables de sortie :
function [mini, maxi] = minetmax(x)
mini = min(x); % Première variable de sortie
maxi = max(x); % Deuxième variable de sortie
Cette fonction pourra être appelée par :
>> [miny, maxy] = minetmax(y);
Le nom de la fonction doit impérativement être le même que le nom du fichier dans lequel elle
est stockée (sinon Matlab ne prendra pas en compte ce nom mais uniquement celui du fichier).
Les nombres d'arguments en entrée et en sortie ne sont pas fixes et peuvent être récupérés par
nargin et nargout. Cela nous permet donc de faire des fonctions Matlab pouvant dépendre d'un
nombre variable de paramètres.
Les variables de l'espace de travail ne sont pas accessibles à la fonction sauf si elles sont entrées
comme variable d'entrée. De même les variables définies dans une fonction ne sont pas accessibles
dans l'espace de travail.
18
De plus vous pouvez créer une aide sur les fonctions et scripts que vous créez et sur vos
répertoires. Pour une fonction et un script, Matlab prendra comme help toutes les lignes de
commentaires placés en début de fichier. Pour un répertoire, il faut créer un fichier Contents.m dans
lequel on place (en commentaires) en première ligne l'aide général sur le répertoire, ensuite les
aides sur les différentes fonctions et scripts contenus dans le répertoire. Ces aides que vous créez
pour vos fonctions et scripts, peuvent évidement être intéressantes pour un utilisateur éventuel, mais
peuvent aussi vous être utiles, pour vous rappeler le but de telle fonction ou pour vous souvenir de
sa syntaxe. Exemple simple :
function [mini, maxi] = minetmax(x)
% [mini, maxi] = minetmax(x)
% Cette fonction renvoie les éléments minimum et maximum d'un % vecteur
% Réalisée le 21 octobre 2006 : M. Afifi
5. Structures de contrôle
On va parler ici de tests et de boucles. Commençons par les opérateurs de comparaison et les
opérateurs logiques
19
Les termes de A supérieur à 2 donnent 1 (vrai), les autres 0 (faux). C’est très utile pour construire
des fonctions par morceaux. Imaginons que l'on veuille définir la fonction suivante :
f(x) = sin x si x > 0
sin 2x sinon
>> f = inline('sin(x).*(x>0) + sin(2*x).*(~(x>0))')
On ajoute les deux expressions sin x et sin 2x en les pondérant par la condition logique définissant
leurs domaines de validité.
>> x = [ -1.2 0 3.1 6.2 -3.3 -2.1] x = -1.2000 0 3.1000 6.2000 -3.3000 -2.1000
On peut ensuite facilement extraire le sous tableau ne contenant que les éléments négatifs de x en
écrivant simplement :
>> y = x(inds) y = -1.2000 -3.3000 -2.1000
Retenez bien cet exemple. Ce type de séquence s'avère très utile dans la pratique.
20
Notons qu'il est souvent possible d'éviter les blocs de ce type en exploitant directement les
opérateurs de comparaison sur les tableaux ainsi que find.
Il existe aussi une structure des conditions multiples : switch…case dont la syntaxe est :
switch variable
case expression1
instructions 1
case expression2
instructions 2
..........
Otherwise
instructions (erreur)
end
21
6. Les polynômes
Matlab est un outil très puissant également pour faire des opérations sur des fonctions
polynomiales. Par défaut, Matlab utilise un vecteur pour représenter un polynôme. Ainsi le vecteur
suivant
>> p = [2 4 8];%représente le polynôme suivant: p = 2x2 + 4x + 8
Comment différencier alors un vecteur normal d'un polynôme ? En fait c'est simplement par le
genre d'opérations qu'on effectuer sur la variable p. Ainsi si on fait l'opération suivante:
4 8 16
>> p'*p ans = 8 16 32
16 32 64
Matlab interprète p, comme un vecteur et effectue le produit de la transposée de p fois le vecteur p.
Si par contre on utilise la fonction suivante:
>> y =polyint(p) y = 0.6667 2.0000 8.0000 0
on effectue l'intégrale du polynôme p, car la fonction polyfun interprète p comme un polynôme. La
fonction roots est très utilie également pour trouver les racines d'un polynôme :
>> roots(p) ans = -1.0000 + 1.7321i
-1.0000 - 1.7321i
Pour plus de détails sur les fonctions appliquées aux polynômes tapez :
>> help polyfun
roots - Find polynomial roots. polyfit - Fit polynomial to data.
poly - Convert roots to polynomial. polyder - Differentiate polynomial.
polyval - Evaluate polynomial. polyint - Integrate polynomial analytically.
polyvalm - Evaluate polynomial with matrix argument. conv - Multiply polynomials.
residue - Partial-fraction expansion (residues). deconv - Divide polynomials.
22
la valeur estimée choisie. La fonction f peut être définie par une directive inline ou bien écrite
dans un fichier.
Par exemple on cherche le zero de f(x) = cos On peut donc écrire, en utilisant inline :
x – x. Une approche graphique permet
souvent de trouver une estimation de x0. La
figure suivante montre ainsi que les fonctions
x x et x cos x se coupent en un point sur
[-,]. Une valeur raisonnable pour
l'estimation de x0 est par exemple 0.
>> f = inline('x-cos(x)')
>> fzero(f,0) % Zero found in the interval: [-0.9051, 0.9051]. ans = 0.7391
On remarquera que la variable f envoyée à la fonction fzero est elle même une fonction. On peut
également écrire la fonction dans un fichier f.m :
function y = f(x)
y = x-cos(x);
et ensuite on écrira :
>> fzero('f',0)
Un dernier point important : comment faire lorsque la définition de la fonction dépend en plus d'un
paramètre ? Par exemple, on veut chercher le zéro de la fonction f(x) = cos(mx) – x où m est un
paramètre susceptible de varier entre deux exécutions. On ne peut pas rajouter un argument à la
définition de notre fonction f car fzero impose que f ne dépende que d'une variable. Une solution
serait d'affecter m dans le corps de la fonction mais elle est mauvaise car :
lorsque l'on veut changer la valeur de m il faut modifier la fonction,
cette fonction sera peut être appelée des dizaines voire des centaines de fois par fzero, et on
répétera à chaque fois la même instruction d'affectation de m.
La bonne solution est d'utiliser la directive globale. La fonction f s'écrira donc :
function y = f(x)
global m
y = x-cos(m*x);
et on cherchera son zéro en écrivant :
>> global m
>> m = 1;
>> fzero(‘f’,0)
Notons que l'on aura tout intérêt à mettre les trois lignes ci-dessus dans un fichier de commandes, et
à lancer ce fichier de commandes en bloc.
23
Si on a la toolbox optimisation, on peut déterminer plusieurs racines à l’aide de fsolve au
voisinage des éléments d’un vecteur que l’on donne en argument d’entrée. La syntaxe est :
fsolve(‘ fonc_nl ’, [x1 x2 … xn]). Exemple :
>> fun = inline('sin(3*x)');
>> x = fsolve(fun,[1 4 9]) x = 1.0472 4.1888 10.4720
7.3. Interpolation
Le problème : connaissant des points tabulés (xi; yi), construire une fonction polynomiale par
morceaux passant par ces points. En termes plus simples, c'est ce que fait la fonction plot quand elle
relie les points que vous lui donnez : elle fait passer un polynôme de degré 1 entre deux points
consécutifs. La fonction interp1 résout le problème. Il suffit de lui donner les valeurs tabulées ainsi
qu'une série d'abscisses où l'on souhaite connaître les ordonnées interpolées. Sur chaque intervalle
on peut interpoler par un polynôme de degré 1qui est le comportement par défaut (option 'linear') ou
de degré 3 (option 'cubic').
Les lignes suivantes fournissent un exemple générique : à partir de cinq points (xi; yi) et on cherche
une interpolation f(x) entre ces cinq points.
>> xi = [1 1/2 0 1/2 1];
>> yi = [1.5 1 0 1 1/2];
>> x = 1:0.1:1;
>> ylinear = interp1 (xi, yi, x);
>> ycubic = interp1 (xi, yi, x, 'cubic');
>> plot(xi,yi,'*', x,ylinear,'-', x,ycubic,'--')
La figure suivante illustre les interpolations linéaires (en traits pleins) et cubiques (en traits
pointillés) obtenues par interp1 sur ces 5 points (illustrés par des cercles).
24
7.4. Approximation (estimation de paramètres ou <fitting>)
Problème : faire passer une courbe d'équation connue au milieu d'un nuage de points de telle
sorte que la courbe soit la plus proche possible de l'ensemble des points. Comme on cherche à
minimiser une distance entre deux fonctions, on parle en général d'approximation aux moindres
carrés ou encore de régression.
7.4.1 Linéaire
Supposons que l'on dispose de n données expérimentales (xi; yi) et que l'on cherche à déduire
une loi y = f(x) dépendant linéairement de m coefficients :
Idéalement, les (xi; yi) vérifieraient cette relation, auquel cas on aurait le système de n équations
linéaires à m inconnues (a1; ... am) :
soit sous forme matricielle Y = F A auquel cas on trouverait simplement les coefficients a i par
inversion :
A = F-1 Y
En MATLAB, ce genre d'instruction peut se programmer simplement à l'aide de l'opérateur \ , et on
écrirait alors A = F \Y;
Cela dit le nombre d'équations n'est pas égal au nombre d'inconnues dans le système linéaire ci-
dessus, il est (normalement) supérieur, et le système est surcontraint. Ça ne fait rien, l'opérateur \ le
résout alors au mieux c'est-à-dire qu'il trouve les ai qui minimise la somme des carrés des résidus :
Voici un exemple : on cherche à fitter des points expérimentaux (xi; yi) par une fonction de la
a2 a3
forme : f ( x )=a1 + +
x x2
La séquence d'instructions est la suivante :
25
>> x = [1/4 1/2 1 2 3]; x = x';
>> y = [18 7 4 2 1.1]; y = y'; % en colonnes
>> F = [ones(sze(x)) 1./x 1./(x.^2)];
>> A = F \ y
>> xx = 1/4:1/16:3; >> plot(x,y,'o', xx, A(1) +
… A(2)./xx + A(3)./(xx.^2))
Ce programme trace la courbe fittée ainsi que les
points expérimentaux :
Cette méthode marche dés que la fonction cherchée dépend linéairement des coefficients inconnus.
Ça marche en particulier pour faire de l'approximation polynomiale (les f j sont des monômes xj),
mais dans ce cas on peut utiliser directement la fonction polyfit, qui en plus des coefficients du
polynôme renvoie des informations sur la qualité de l'approximation réalisée. Polyfit attend en
entrée simplement les xi, les yi et l'ordre du polynôme recherché. La fonction polyval peut être
utilisée pour recalculer le polynôme d'approximation en tout point.
L'exemple suivant calcule deux polynômes d'approximation, un d'ordre 3, l'autre d'ordre 4 et trace
le résultat.
>> x = [-2 -1.5 -1 0 1 1.5 2];
>> y = [3.5 2 1.5 0 1.3 2.5 3.9];
>> A4 = polyfit (x, y, 4)
>> A3 = polyfit (x, y, 3)
>> xx = -2:0.1:2;
>> plot(x, y, 'o', xx, polyval(A4,xx), xx,
polyval(A3,xx), '--' )
avec
La fonction F dépend non linéairement des paramètres a1; a2; ... am et un algorithme d'optimisation
doit être utilisé. MATLAB possède des routines d'optimisation utiles pour ce genre de problème
notamment si on dispose de la toolbox « Optimisation ».
26
Si on n’a pas cette toolbox, il faut utiliser la routine de minimisation fournie dans la version
MATLAB de base qui s'appelle fminsearch. Pour cela il faut simplement programmer la fonction F
à minimiser et d'écrire la fonction de fitting f dans une sous fonction séparée. Voici comment
procéder dans l'exemple suivant : des analyses spectrométriques fournissent des pics que l'on
cherche à fitter (par exemple) par des gaussiennes. Par exemple dans le cas de deux pics :
Il y a 6 paramètres B1, B2, x1, x2, 1 et 2 que nous regroupons dans un tableau a avec a(1) = B1,
a(2) = B2, a(3) = 1, a(4) = 2, a(5) = x1, a(6) = x2.
Ecrivons tout d'abord la fonction de fitting :
Function y = f (a, x)
y = a(1)*exp(- ( (x-a(5))/a(3) ).^2) + a(2)*exp(- ( (x-a(6))/a(4) ).^2)
Il est important que cette fonction puisse accepter un tableau en entrée, d'où l'usage des points
devant les opérateurs puissance. Ensuite on écrit la fonction F représentant le résidu à optimiser :
function out = F (a)
global xi yi
out = sum ( (yi - f(a,xi)).^2 );
L'usage de global pour passer les points expérimentaux xi yi est nécessaire car l'entête de la
fonction F à optimiser est imposée par fminsearch. Il reste à appeler l'optimiseur dans un
programme principal :
% Pour passer les points expérimentaux à F
global xi yi
% Définition des points expérimentaux (en général chargés depuis un fichier)
xi=[20 40 60 80 100 120 140 145 155 156 176 196 216 236 256 276 296 316 336 346 356 360 380
400 420 440]
yi=[0.0025 0.0162 0.0846 0.3073 0.7528 1.4288 1.9315 1.9962 2.1083 2.0104 1.6617 0.8970
0.4343 0.3466 0.5393 1.0182 1.7069 2.4561 2.9957 3.1671 3.0137 2.9506 2.6111 1.9578 1.2067
0.5896]
% Estimation de la solution. Le succès de l'opération dépend de cette
a0=[2,3,50,70,150,350]; % correspond à B1, B2 ,sigma1, sigma2, x1, x2
% Appel de l'optimiseur.
asol = fminsearch ( 'F', a0);
% Superposition points expérimentaux et fittés.
plot (xi, yi, '*', xi, f(asol, xi))
27
L'algorithme utilisé par fminsearch est parfois insuffisant. La toolbox optimisation fourni un
grand nombre de routines d'optimisation. Pour le problème d'estimation de paramètres proposé ci-
dessus, la routine dédiée est lsqcurvefit (least squares curve fit>). Elle permet de ne programmer
que la fonction f et forme elle-même la somme des carrés. Voici ce qu'il faut écrire pour résoudre le
problème précédent :
function y = f (a, x)
y = a(1)*exp(- ( (x-a(5))/a(3) ).^2) + a(2)*exp(- ( (x-a(6))/a(4) ).^2)
C'est en fait la même que précédemment. Maintenant on peut appeler directement lsqcurvefit :
% Definition des points expérimentaux
xi = ...
yi = ...
% Estimation de la solution.
a0=[2,3,50,70,150,350]; % correspond à B1, B2 ,sigma1, sigma2, x1, x2
% Appel de l'optimiseur. On remarque que la fonction à passer est maintenant f et % plus F et
qu'on passe les points expérimentaux directement au solveur.
asol = lsqcurvefit ( 'f', a0, xi, yi);
% Superposition points expérimentaux et fittés.
plot (xi, yi, '*', xi, f(asol, xi))
28
On remarquera que les yi et les
ẏ i sont regroupés dans des vecteurs, ce qui fait que la forme de
cette fonction est exploitable quel que soit le nombre d'équations du système différentiel. La
dernière ligne est nécessaire car la fonction doit ressortir un vecteur colonne et non un vecteur ligne.
Ensuite, pour résoudre cette équation différentielle, il faut appeler un solveur et lui transmettre
au minimum :
le nom de la fonction.
les bornes d'intégration (tmin et tmax).
les conditions initiales.
Le solveur fournit en sortie un vecteur colonne représentant les instants d'intégration t, et une
matrice dont la première colonne représente les y1 calculés à ces instants, la deuxième les y2, et la
nième les yn.
L'appel du solveur prend donc en général la forme suivante :
[t, y] = ode45 ('f', [tmin tmax], [y10 y20 ... yn0] );
y1 = y(:,1);
y2 = y(:,2);
...
yn = y(:,n);
plot(t, y1, t, y2) % par exemple on trace y1(t) et y2(t)
plot(y1,y2) % ou bien y2(y1) (plan de phase pour les oscillateurs)
Les lignes y1 = ... servent à extraire les différentes fonctions yi dans des colonnes simples. Nous
avons utilisé ici ode45 qui est un Runge-Kutta-Merson imbriqué d'ordre 4 et 5. C'est le plus courant
et celui par lequel il faut commencer, mais il en existe d'autres.
Exemple : On considère l'équation de Matthieu amortie :
où a, b et sont des paramètres. On prend comme conditions initiales y(0) = 10-3 et ẏ (0) = 0. En
posant y1 = y et y2 = ẏ on se ramène à la forme canonique :
ẏ 1 = y2
ẏ 2 = -by2 - a(1 + cos t)y1
Ecrivons la fonction matthieu définissant cette équation dans un fichier matthieu.m. Comme pour le
problème de recherche de zéro, on passera généralement les paramètres de l'équation dans une
directive global :
function ypoint = matthieu (y, t)
global a b epsilon
29
ypoint(1) = y(2);
ypoint(2) = -b*y(2) -a*(1+epsilon*cos(t))*y(1);
ypoint = ypoint';
La séquence d'instructions (à mettre dans un autre fichier .m) qui appelle le solveur sera par
exemple :
global a b epsilon subplot(212)
% Parametres plot(y1,y2) % Plan de phase
a = 1;
b = 0.1;
epsilon = 1;
tfinal = 10*pi; % Temps final
y01 = 1e-3; % Conditions initiales
y02 = 0;
[t,y] = ode45('matthieu', [0 tfinal], [y01 y02]);
y1 = y(:,1); % Extraction de y1 et y2
y2 = y(:,2);
subplot(221)
plot(t,y1) % y1 fonction du temps %
subplot(222),plot(t,y2) (représente dy(t)/dt))
Ce programme trace la figure suivante qui représente les grandeurs y(t) et ẏ (t) de l'équation
originale en fonction du temps, plus le plan de phase.
30