Introduction au langage MATLAB
Introduction au langage MATLAB
MATrix LABoratory :
Ce tour d’horizon fournit une familiarisation rapide mais néanmoins rigoureuse de la
programmation MATLAB. En effet, MATLAB n’est pas une application "pousse-bouton", mais
un langage de programmation interprété (i.e. dont les instructions sont exécutées à la volée). Ce
langage a été conçu pour soulager l’utilisateur scientifique de la plupart des difficultés
informatiques inhérentes aux langages à usage universel comme C/C++ ou Java. Sa syntaxe,
compacte et élégante, est bien adaptée pour le calcul matriciel. Sa plate-forme permet d’acquérir, de
traiter, d’analyser et de visualiser pratiquement n’importe quelles données. Elle est constituée d’un
noyau de routines compilées (i.e. traduites, une fois pour toute, en code machine après analyse
lexicale, syntaxique et contextuelle de leur code source), particulièrement robustes et optimisées,
auquel peuvent se greffer des bibliothèques spécialisées, appelées "toolboxes". À cela s’ajoute un
IDE (s.s. un environnement de développement intégré) complet qui permet d’implémenter
efficacement de nouveaux algorithmes et de construire des interfaces graphiques conviviales, le
tout, directement utilisable sous Linux, MacOS, UNIX et Windows !
Lancement de MATLAB :
Matlab version 6 pour Windows est installé sur les PCs des salles de TP. L’application
s’ouvre sous la forme d’une fenêtre cadre hébergeant (de haut en bas) une barre de titre, une barre de
menu, une barre d’outils, trois fenêtres vue et une barre d’état.
La barre de menu et la barre d’outils offrent les commandes habituelles comme la création de
document, l’ouverture de fichier, l’édition de texte, le réglage des préférences, et l’accès à l’aide
interactive via le menu «Help» et la commande «MATLAB Help». Écrite en HTML, (s.s. Hyper
Text Markup Language) cette dernière est classée thématiquement et est largement illustrée.
Dans la barre d’outils, le combo (s.s. la liste combinée) intitulé «Current Directory» (s.s.
dossier courant) permet d’éditer le chemin du répertoire de travail. Par défaut, MATLAB recherche
les programmes et les données de l’utilisateur dans «'C:\MATLAB…\work'». Le bouton «…» ouvre
un explorateur qui permet de sélectionner un nouvel emplacement dans l’arborescence du
système de fichiers. Pour les TPs, il est judicieux de créer un dossier sur le bureau (i.e. dans le
profil personnel et itinérant de l’utilisateur) puis de le rajouter définitivement à la fin de la
hiérarchie de recherche de MATLAB, via le menu «File» et la commande «Set Path…».
La vue intitulée «Command Window» est la console de MATLAB. Les commandes en ligne doivent
êtres saisies à la suite du prompt (i.e. l’invite de commande de la forme «>>»), et sont exécutées
par l’interpréteur MATLAB après validation sur la touche entrée. Il est recommandé de suivre la
démo qui s’obtient avec la commande « demo », puis de lancer des commandes d’aide en ligne
comme « help », « help ops », « help elfun », « help sqrt » et de faire des recherches par mot
clé comme « lookfor 'square root' ». Il est possible d’économiser les frappes au clavier grâce à
la touche tabulation qui appelle la complétion (s.s. le complément) du lexème en cours de frappe.
De même, les touches haut et bas rappèlent, avec ou sans complétion, les commandes passées.
1
La page intitulée «Workspace» contient une table détaillée des variables présente dans l’espace de
travail (i.e. stockées en mémoire). La barre d’outils permet de charger, sauvegarder, éditer et
effacer les variables sans avoir à taper de commande en ligne.
La vue intitulée «Command History» affiche une liste chronologique des commandes passées. Un
double-clic suffit pour relancer la commande sélectionnée.
Valeurs et variables :
La console peut être utilisée comme une simple calculatrice. Les résultats sont
automatiquement affectés à la variable « ans » (s.s. un diminutif de "answer").
>> 1 + 1
ans =
2
Une variable est un identificateur (i.e. un nom symbolique, de préférence évocateur et non
ambigu) désignant l’allocation mémoire d’une valeur. Cette dernière est évidemment modifiable,
contrairement à celle d’une constante (e.g. « pi », « true », « eps », …). Pour conserver un calcul
intermédiaire, il suffit donc de déclarer une nouvelle variable et de l’initialiser avec l’expression
souhaitée. L’identificateur est une chaîne de caractères alphanumériques (i.e. composés de lettres
et de chiffres) non accentués et sensibles à la casse (i.e. aux majuscules et aux minuscules), qui ne
doit pas contenir d’espace et dont le premier caractère doit être purement alphabétique.
>> MaVariable = ans + 1
MaVariable =
3
>> MaVariable * ans
ans =
6
L’attribut principal d’une variable est son type, c’est-à-dire la longueur et la signification du code
binaire sérialisé en mémoire physique à partir de l’adresse indiquée par la variable. C’est lui qui
détermine les opérations possibles avec la variable. La fonction « whos » montre que MATLAB
stocke (quasiment) tout, sous la forme de tableaux multidimensionnels. Par exemple, l’entier
naturel 42 est devenu un «double array» de taille 1x1, c’est-à-dire un tableau bidimensionnel de
nombre décimaux codés en virgule flottante et en double précision, ne contenant qu’un seul élément.
En fait, les tableaux dynamiques (i.e. dont la taille et donc l’occupation mémoire peuvent varier
librement) bidimensionnels de décimaux constituent la structure de donnée la plus naturelle pour
manipuler des matrices (i.e. le fond de commerce de MATLAB).
>> clear % Efface les variables de l'espace de travail.
>> Var1 = 42; % Un nombre entier.
>> Var2 = 3.14; % Un nombre décimal.
>> Var3 = 1 + 2i; % Un nombre complexe.
>> Var4 = [1 2; 2 3; 3 4]; % Une matrice entière 3x2.
>> Var5 = 'Hello World'; % Une chaîne de caractères.
>> whos
2
MATLAB est un langage faiblement typé, ce qui masque une bonne part de la complexité des
types informatiques sous-jacents (e.g. entiers, flottants, caractères, booléens, pointeurs,
références, tableaux, structures, unions, ...). C’est ainsi que les opérations de transtypage (s.s. les
conversions de type) sont généralement implicites. Toutefois, autant de souplesse sémantique
n’est pas forcément une qualité puisque cela autorise le meilleur comme le pire...
>> 'ABC' + 0 % Une chaîne de caractères additionnée à un entier.
ans =
65 66 67 % Un tableau d'entiers (les codes ASCII de 'ABC').
Les erreurs d’arrondis rendent plus ou moins rapidement le résultat imprécis. Si l’inverse de
l’inverse de «49» ne vaut pas exactement«49», c’est parce que l’expression «1/49» n’est qu’une
valeur arrondie à environ 16 chiffres significatifs de la vraie constante mathématique (rationnelle).
>> VarNum = 1/49
VarNum =
2.040816326530612e-002
>> 49 - 1/VarNum
ans =
-7.105427357601002e-015
Une solution élégante, consiste à travailler avec la «Symbolic Math Toolbox», qui sait manipuler
et résoudre les expressions symboliquement (e.g. résolution d’équation différentielle, …).
>> syms x y % Déclaration des variables symboliques x et y.
>> y = 1/x; % Initialisation de la variable y.
>> x - 1/y
ans =
0
Si une expression symbolique doit finalement être évaluée numériquement, le calcul peut être
effectué avec une précision arithmétique variable, réglée par défaut à 32 chiffres significatifs.
3.1415926535897932384626433832795028841971693993751058209749445923078164062862090
3
Expressions et opérateurs :
Les expressions représentent le niveau supérieur dans la structure d’un programme
MATLAB. L’interpréteur évalue une expression pour calculer sa valeur. Les expressions les plus
simples sont les littéraux, les constantes et les variables.
>> 3.14 % Un littéral.
ans =
3.1400
Les expressions plus complexes sont construites à l’aide d’opérateurs. L’expression suivante
utilise l’opérateur « * » pour combiner un littéral et une constante au sein d’une expression de
multiplication.
>> 2 * pi
ans =
6.2832
La commande d’aide « help ops » fournit la liste des opérateurs et des caractères spéciaux (i.e.
ponctuation, parenthèsage, …). Une page d’aide existe pour décrire la fonction ainsi que le
nombre, l’ordre et le type des opérandes de chaque opérateur. C’est ainsi que « help uminus »
décrit le "moins monadique" comme un opérateur unaire (i.e. agissant sur un opérande unique)
qui change le signe des éléments du tableau qui lui est passé par la droite. De même, «help
punct» indique que la virgule sépare les instructions multiples et que le point-virgule permet en
plus d’empêcher l’affichage du résultat.
>> Tab = [1 -2]; -Tab
ans =
-1 2
La commande d’aide « help precedence » fournit la hiérarchie de priorités des opérateurs. Une
expression doit être composée en prenant garde à la précédence des opérateurs et des caractères
spéciaux utilisés.
>> 1 + 2 * 3, (1 + 2) * 3
ans =
7
ans =
9
4
Tableaux et matrices :
La façon la plus naturelle d’initialiser une matrice est d’utiliser un agrégat de littéraux
placés entre crochets. Les colonnes sont séparées par des espaces ou des virgules et les lignes par
des point-virgules.
>> RVect = [1 3 5 7] % Un vecteur ligne.
RVect =
1 3 5 7
>> size(RVect)
ans =
1 4
Il existe une syntaxe intuitive pour initialiser un vecteur sous la forme d’une suite arithmétique
bornée de raison entière ou réelle.
>> -2:1 % Incrément de 1, équivalent à "-2:1:1".
ans =
-2 -1 0 1
Par défaut, les fonctions «linspace() » et «logspace() » créent une suite de 100 éléments
repartis linéairement ou logarithmiquement entre deux bornes.
>> x = linspace(0, 2*pi);
>> y = sin(x);
>> plot(x,y) % Affichage de sin(x) sur l'intervalle [0, 2].
>> logspace(1, 5, 3)
ans =
10 1000 100000
Des fonctions existent pour créer des matricesaux propriétés remarquablescomme «ones()»,
«zeros()», «eye()», «rand()»,«magic()», «pascal() », «hadamard()», etc.
>> rand(3,3) % Création d'une matrice 3x3 pseudo-aléatoire.
ans =
5
Les éléments d’une matrice sont indexés séquentiellement, à partir de 1. MATLAB respecte la
convention surnommée "licol" (s.s. ligne-colonne), puisque la première dimension représente les
lignes et la deuxième dimension les colonnes. Il est possible d’utiliser des tableaux d’indices ainsi
que le mot réservé «end».
Il est aussi possible de construire des matrices par concaténation horizontale ou verticale.
>> a = 0:4; b = 5:9; c = [a b; b a]
c =
0 1 2 3 4 5 6 7 8 9
5 6 7 8 9 0 1 2 3 4
L’opérateur de transposition permet de changer l’orientation d’une matrice. Toutefois, il sert aussi
à calculer le conjugué d’un nombre complexe, et possède une précédence élevée.
>> T = 1:2;
>> T * T'
ans =
5
>> T' * T
ans =
1 2
2 4
Les opérateurs «.*», «./», «.\», et «.^» se distinguent des opérateurs matriciels traditionnels
puisqu’ils agissent élément par élément, sur des tableaux de tailles identiques.
>> [1 2] .\ [2 4] % Division gauche A\B == "inv(A)*B"
ans =
2 2
6
Persistance des variables :
Lorsque que l’application MATLAB quitte, l’espace de travail est définitivement perdu. Pour
reprendre ultérieurement une session, il faut avoir préalablement sauvegardé les variables utiles,
dans un ou plusieurs fichiers enregistrés sur un support persistant (e.g. disque dur, CD-ROM...).
>> save MesVariables V1 V2 V3 % Sauvegarde les variables.
>> dir *.mat % Liste du dossier de travail filtrée
[Link] % par l'expression régulière "*.mat".
MATLAB sérialise les données dans un format binaire propriétaire, puis écrit le flux d’octets dans
un fichier MAT (i.e. avec une extension ".mat"). MATLAB propose des fonctionnalités de
sérialisation et de désérialisation analogues à celles du langage C (e.g. « fprintf », « fscanf », ...),
mais la solution la plus simple pour échanger des données avec d’autres applications est de passer
par un fichier texte au format ASCII 8 bits (i.e. un jeu de caractère limité à 256 codes
alphanumériques), avec retours chariot et tabulations pour délimiter les éléments.
>> V4 = [1 2; 2 3; 3 4];
>> save [Link] V4 -ascii –tabs % Format ASCII avec tabulation.
>> type [Link] % Lecture du fichier dans la console.
1.0000000e+000 2.0000000e+000
2.0000000e+000 3.0000000e+000
3.0000000e+000 4.0000000e+000
Scripts et fonctions :
Il est pratique de pouvoir exécuter les instructions (i.e. les unités syntaxiques du langage,
comme les expressions), manuellement, les unes à la suite des autres, directement depuis la
console. Mais il est encore plus intéressant de pouvoir répartir ces mêmes instructions dans un ou
plusieurs scripts (s.s. fichiers de commandes) de manière à disposer de procédures (s.s. sous-
programmes) réutilisables. Un traitement de texte capable de sauvegarder en ASCII (i.e. dans un
format textuel pur) suffit pour créer un fichier M (i.e. avec une extension ".m") mais l’éditeur
intégré de MATLAB offre des facilitées d’édition comme la syntaxe colorée ou l’indentation
automatique ainsi que des fonctionnalités de déboguage comme l’insertion de breakpoint, etc.
%EPURATION Purge l'espace de travail et efface la console.
% EPURATION détruit les variables de l'espace de travail,
% efface la console et réinitialise la position du curseur.
%
% Voir aussi CLEAR, CLC, HOME
7
>> exist epuration % Test d'existence de l'identificateur.
ans =
2
Un fichier M supporte l’aide en ligne si son code source (i.e. l’ensemble des instructions) est
précédé par un en-tête composé d’un continuum de lignes de commentaire. La première de ces
lignes est aussi utilisée pour la recherche par mot clé.
>> help epuration
Les variables déclarées à l’intérieur d’un script appartiennent à l’espace de travail. Elles sont donc
partagées avec les autres scripts et, à moins que le programmeur ne les efface (e.g. par un appel à
«clear()»), elles perdurent jusqu’à la fin de la session MATLAB. Les scripts sont donc très
pratiques comme procédures à effet de bord sur les variables d’environnement de MATLAB,
mais sont inadaptés pour la programmation modulaire (i.e. le partitionnement des programmes
de telle façon que les données soient cachées dans des procédures indépendantes). Pour cela, il
faut rédiger des fonctions MATLAB, c’est-à-dire des fichiers M qui commencent par une ligne
définissant le nom de la fonction ainsi que ses paramètres d’appel et de retour. Le nom du fichier
doit correspondre à celui de la fonction.
function outTab = isqrt(inTab)
%ISQRT calcule l'inverse de la racine carrée de inTab.
% isqrt est "vectorisée" (i.e. sait gérer plusieurs éléments en parallèle).
%
% Voir aussi SQRT
outTab = 1./sqrt(inTab);
>> isqrt(1:4)
ans =
1.0000 0.7071 0.5774 0.5000
Par défaut, les variables internes ont une portée locale à la fonction et n’existent (en mémoire) que
le temps de l’appel de cette dernière. Si une variable doit être visible par plusieurs fonctions, elle
doit être déclarée globale dans chacune d’elles.
function tick
%TICK démarre le chronomètre. Voir aussi TIC.
function tock
%TOCK arrête le chronomètre. Voir aussi TOC.
global g_Clock;
disp(sprintf('Temps écoulé: %f sec.', ... % Formatage de type "C/C++".
etime(clock, g_Clock)));
clear global g_Clock; % Destruction de la globale.
8
Une fonction peut s’appeler directement ou indirectement de façon récursive. Chaque niveau
d’appel possède son propre espace de travail, indépendant du précédent. Comme il faut stocker
une pile de valeurs intermédiaires, la récursion n’est pas synonyme d’économie de mémoire, mais
les algorithmes de ce type sont souvent très compacts et élégants.
function outInt = factorielle(inInt)
%FACTORIELLE calcule récursivement la factorielle de inInt, qui doit être
% un entier positif ou nul. Compte tenu de la précision du type double,
% le résultat n'est correct que si inInt est inférieur ou égal à 21.
%
% Voir aussi FACTORIAL
if (inInt <= 1)
outInt = 1; % Cas trivial.
else
outInt = inInt * factorielle(inInt - 1); % Cas général.
end
>> factorielle(10)
ans =
3628800
Les fonctions MATLAB les plus simples ressemblent un peu à des équations algébriques de la
forme "y = f(x)", où l’argument "x" fait référence à une valeur inconnue et où "y" prend la valeur
de l’image de "x" par "f()". Mais les fonctions MATLAB les plus complexes peuvent posséder
plusieurs arguments tant en entrée qu’en sortie et même en utiliser un nombre variable. La page
d’aide «matlab/lang» décrit les variables spécialisées dans la transmission de paramètre comme
«nargin», «nargout », «varargin » et «varargout ». En principe, une fonction MATLAB
retourne ses valeurs de sortie au programme appelant, lorsque la fin de son code source est
atteinte. Toutefois, à n’importe quel moment, l’instruction «return » permet de sortir
normalement de la fonction alors que la fonction «error()» sert à provoquer la fin anormale du
programme complet. Il est aussi possible de forcer l’arrêt d’un programme en cours d’exécution
(e.g. en cas de récursion ou de boucle infini), en appliquant le raccourci clavier «Ctrl-C» sur la
console. Le cas échéant, il faut essayer de tuer le processus MATLAB en appelant le gestionnaire
de tache grâce à la combinaison «Ctrl-Alt-Delete».
function [outMin, outMax] = minmax(inTab, inDim)
%MINMAX est une encapsulation simplifiée des fonctions MIN et MAX.
if nargin == 1
outMin = min(inTab); outMax = max(inTab);
else
outMin = min(inTab, [], inDim); outMax = max(inTab, [], inDim);
end
La première fois que MATLAB exécute une fonction, celle-ci est analysée puis compilée dans un
byte-code (i.e. traduite dans une représentation interne plus efficace) qui est directement stocké en
mémoire. Cette étape permet de déclarer plusieurs fonctions dans un même fichier-M. Dans ce
cas, les sous-fonctions ont une porté de fichier (i.e. sont invisibles depuis les autres fichiers).
9
Tests et instructions de contrôle :
MATLAB gère les booléens (i.e. les valeurs logiques) comme des nombres. C’est ainsi que «0» est
interprété comme «false» et toute les autres valeurs comme «true».
>> if pi, disp('c''est vrai'), end
c'est vrai
>> ~false
ans =
1
L’instruction «if-elseif-else-end» permet d’exprimer des prises de décision basées sur des
tests construits avec des opérateurs relationnels «<», «<=», «>», «>=», «==», «~=», ou logiques
«&», «|», «~», et des fonctions comme «isreal()», «ischar()», «isequal()», etc.
if ~isreal(inInt), error('inInt n''est pas un nombre!')
elseif isempty(inInt), error('inInt n''est pas initialisé !')
elseif (isinf(inInt) | isnan(inInt)), error('inInt n''est pas déterminable!')
elseif fix(inInt) ~= n, error('inInt n''est pas un entier!')
elseif inInt < 0, error('inInt n''est pas positif !')
else, disp 'Test factorielle réussi!'
end
L’instruction «break» provoque la sortie d’une boucle «for» ou «while» avant sa fin logique.
En cas de boucle imbriquée, seule la boucle courante est interrompue, laissant la boucle
immédiatement supérieure se poursuivre normalement. L’instruction «continue» permet de
sauter une itération pour passer directement à la suivante.
10
Figures et graphiques :
MATLAB dispose de nombreuses fonctions graphiques aux usages plus ou moins
complexes. Le programmeur aura tout intérêt à découvrir les exemples illustrés de l’aide
interactive avant de parcourir l’inventaire "à la Prévert" proposé par les pages de l’aide en ligne
comme «graph2d», «graph3d», «specgraph » et «graphics ». Le rendu se fait de manière
vectorielle et dans une figure MATLAB, c’est-à-dire une fenêtre vue comportant une barre de menu
et une barre d’outils aux fonctionnalités similaires à celle d’un logiciel de PAO (cf. figure 1).
Figure 1: Tracés de courbes 2D dans une figure MATLAB et édition manuelle du graphique.
MATLAB attribue automatiquement un handle (s.s. un descripteur) aux objets graphiques. Utilisé
avec les fonctions «get() » et «set() » cet identifiant numérique permet de consulter et de
modifier les propriétés des objets graphiques directement depuis un programme. Par exemple,
l’instruction «get(gcf) » fournit la liste complète des propriétés de la figure active alors que
l’instruction «set(gca) » se limite aux propriétés modifiables du graphe actif. Toutes ces
propriétés sont décrites dans l’aide interactive à la page «Handle Graphics Property Browser».
>> thePoly = [-1 1 0 0]; % Définition du polynôme "-x^3 +x^2".
>> x = linspace(-1, 2, 200); % Définition de l'intervalle [-1, 2].
>> y = polyval(thePoly, x); % Evaluation du polynôme.
>> thePolyH = plot(x, y); % Tracé 2D.
>> theWidth = get(thePolyH, 'LineWidth'); % Epaisseur du tracé.
>> set(thePolyH, 'LineWidth', theWidth + 1); % Modification de l'épaisseur.
>> set(gcf, 'Name', 'Exemple of 2D plot'); % Définition du titre de la figure.
Par défaut, le graphe actif est effacé (e.q. «cla()») avant chaque nouveau tracé. Pour que les
tracés se superposent, il faut préalablement le spécifier avec la fonction «hold()» ou une
instruction tel que «set(gca, 'NextPlot', 'add')».
>> theDer = polyder(thePoly) % Dérivée du polynôme.
>> y = polyval(theDer, x); % Evaluation de la dérivée.
>> hold on % Superposition des tracés.
>> plot(x, y, 'r-'); % Tracé 2D avec chaîne de formatage.
>> hold off % Fin de la superposition des tracés.
11
Par défaut, MATLAB adapte l’échelle des axes en fonction de l’étendue des valeurs à afficher. La
fonction «axis()» permet de spécifier beaucoup d’autres comportements. Il est aussi possible
d’associer des légendes aux axes, d’afficher une grille, etc.
>> axis([-2 2 -2 2]) % Etendue des axes.
>> grid on % Affichage de la grille.
>> xlabel('Abscisses') % Légende de l'axe des abscisses.
>> ylabel('Ordonnées') % Légende de l'axe des ordonnées.
>> title('Dérivation de polynômes') % Titre du graphique.
>> theDer = polyder(thePoly) % Dérivée du polynôme.
Une figure peut héberger plusieurs graphes. Par exemple, la fonction «subplot()» subdivise une
figure en mosaïque et spécifie le graphe actif. Les graphes sont numérotés depuis le coin
supérieur gauche et de gauche à droite. La figure 2 a été obtenue en sauvegardant au format EPS
(i.e. sous une forme vectorielle) le contenu de la figure MATLAB via son propre menu «File» et
la commande «Exporte…».
>> clear all, close all % Ferme toutes les figures.
>> x = linspace(-1, 1, 200);
>> y = exp((-x.^2));
>> subplot(2,2,1), plot(x, y), title('Courbe pleine'), axis([-2 2 0 1])
>> subplot(2,2,2), stem(x, y), title('Diagramme en bâton'), axis([-2 2 0 1])
>> subplot(2,2,3), stairs(x, y), title('Diagramme en escalier'), axis([-2 2 0 1])
>> subplot(2,2,4), bar(x, y), title('Diagramme en barre'), axis([-2 2 0 1])
0.8 0.8
0.6 0.6
0.4 0.4
0.2 0.2
0 0
ï2 ï1 0 1 2 ï2 ï1 0 1 2
0.8 0.8
0.6 0.6
0.4 0.4
0.2 0.2
0 0
ï2 ï1 0 1 2 ï2 ï1 0 1 2
Figure 2: Export au format EPS d’une figure MATLAB contenant quatre sous-graphes.
Pour créer ou activer une figure il suffit de donner son numéro en argument à la fonction
«figure()». Ensuite l’instruction «close(gcf)» permet de fermer la figure courante.
12
Construction d’une interface graphique :
Dans le cadre de cette introduction, nous nous limiterons à l’étude d’un cas concret: la
création d’une GUI (s.s. Graphical User Interface) pour un algorithme de compression d’image
basé sur la DCT (s.s. Discrete Cosinus Transform). La DCT est une variante de la transformation
de Fourier qui est couramment utilisée en traitement du signal (e.g. JPEG, MP3, MPEG) car
contrairement à cette dernière, elle transforme un signal réel en un signal réel (et non complexe).
Un signal discret de longueur N est ainsi décomposé en une somme de N termes sinusoïdaux aux
fréquences croissantes et multiples de 1/2N. Ces sinusoïdes sont appelées les harmoniques du signal
et l’ensemble des termes de la décomposition harmonique forme le spectre du signal. La
transformation est inversible et le spectre en amplitude (i.e. l’ensemble des amplitudes signées des
harmoniques) suffit à décrire le signal. En fait, le signal et son spectre correspondent à deux
signatures duales de la même réalité: l’une spatiale ou temporelle et l’autre fréquentielle. Les
fonctions «dct()» et «idct()» ainsi que leurs homologues bidimensionnelles «dct2()» et
«idct2()» sont décrites dans l’aide interactive de la «Signal Processing Toolbox». Il faut
noter que MATLAB indices les harmoniques sur [1, N] et non sur [0, N-1].
Voici un script qui utilise les capacités graphiques de MATLAB pour illustrer les principales
propriétés de la DCT (cf. figure 3).
%DECOMPOSITION Montre un exemple de décomposition de signal par DCT.
>> decomposition
theHar =
3 86 92
theMag =
6.0000 8.0000 7.0000
13
Exemple de décomposition par DCT
H92
H86
H03
S(t)
Figure 3: Décomposition harmonique par transformation en cosinus d’un signal discret de longueur 1024.
Le signal S est en fait la somme des contributions de ses harmoniques de rang 3, 86 et 92.
Dans cet exemple, six nombres (i.e. trois harmoniques caractérisés par leur fréquence et leur
amplitude) suffisent pour décrire un signal (en apparence) compliquée. Dans le cas général, les
données ne sont pas compressibles de manière aussi triviale. L’exemple suivant montre qu’elles
sont néanmoins encodées sous une forme favorable. Ce script ouvre une image en niveaux de
gris et au format TIFF puis enregistre une version rehaussée (i.e. visuellement analysable) de son
image spectrale (cf. figure 4). Comme les pixels de l’image TIFF sont de type «uint8» (i.e. des
entiers non signés et codés sur 8 bits, soit de 0 à 255), l’image doit être convertie en une matrice
réelle avant de pouvoir être utilisée par les fonctions MATLAB traditionnelles.
%MAGNITUDE enregistre l'image spectrale d'une image TIFF en niveaux de gris.
14
Figure 4: Transformée en cosinus d’une image en niveaux de gris (Source: NASA mission sts-97).
Le coin supérieur gauche de l’image spectrale renferme l’essentiel de l’énergie de l’image.
Figure 5: Compression d’image par filtrage fréquentiel simpl(ist)e. Avec une image de taille 256x256 et
une fréquence de coupure de rang 57, le taux de compression est de (57/256)^2 = 1/20.
15
Figure 6: Le designer de GUI fonctionne comme un logiciel de PAO (s.s. Publication Assistée par Ordinateur).
La commande «guide» lance l’interface du designer de GUI. Par défaut, elle s’ouvre sur une
figure MATLAB (i.e. une fenêtre vue) vierge qui apparaît sous la forme d’un canevas quadrillé.
On peut déjà enregistrer cette figure sous le nom qui servira à lancer l’application depuis la
console. MATLAB génère alors un fichier M et un fichier FIG du même nom. Le fichier M
contient le code source nécessaire au fonctionnement de l’interface ainsi que de nombreux
commentaires explicatifs invitant le programmeur à compléter les fonctions réflexes (e.q. callback
functions) des contrôles (i.e. les composants de l’interface qui réagissent aux actions de l’utilisateur).
De son côté, le fichier FIG contient les ressources graphiques de l’interface. Ce format binaire est
éditable par le designer en lançant la commande «guide» avec pour argument le nom du fichier.
La palette d’outils permet de placer des contrôles sur le canevas. La figure «ImgDCT» héberge quatre
axes, un cadre (e.q. frame), deux boutons, une zone de texte non éditable, et une barre de
défilement (e.q. slider). La fenêtre flottante intitulée «Property Inspector» s’obtient en double-
cliquant sur le contrôle désiré ou via son menu contextuel. Les propriétés propres aux contrôles sont
décrites dans l’aide interactive à la page «MATLAB: Handle Graphics Property Browser». En
pratique, seule une poignée de champs nécessite l’intervention du programmeur. C’est ainsi que le
champ «Callback» est remplis automatiquement par l’IDE. Ce champ définit le nom de la sous-
fonction du fichier M qui est appelée lorsque que le contrôle est sollicité par l’utilisateur.
Pour définir précisément l’emplacement et la taille d’un contrôle il est conseillé de régler son
champ «Units» sur «pixels » avant de modifier son vecteur «Position ». Il faut noter que
l’origine du système de coordonnée est située dans le coin inférieur gauche de l’objet parent (i.e.
l’écran s’il s’agit d’une figure MATLAB) et que l’axe des «y» est orienté vers le haut. Les outils
de la palette flottante intitulée «Align Objects» servent à disposer les objets, relativement les uns
par rapport aux autres. Pour finir, le bouton «Run» situé à droite de la barre d’outils permet de
contrôler l’apparence de l’interface en lançant directement l’application.
16
Le champ «Tag» doit être unique pour chaque contrôle. En effet, c’est grâce à ce nom
symbolique que l’on peut facilement obtenir le handle du contrôle et donc accéder à ses
propriétés. Cet exemple montre le mécanisme de feedback (s.s. la boucle de retour) qui met à jour
la zone de texte lorsque l’utilisateur règle le taux de compression depuis la barre de défilement.
theSliderH = findobj('Tag','SliderRatio'); % Handle de la barre de défilement.
theValue = get(theSliderH, 'Value'); % Consulte la propriété 'Value'.
theString = sprintf('%2.1f %%', theValue); % Formatage de type C/C++.
theTextH = findobj('Tag','TextRatio'); % Handle la zone de texte.
set(theTextH, 'String', theString); % Modifie la propriété 'String'.
Les champs «Max», «Min» et «SliderStep:x» de la barre de défilement ont été fixés à «100»,
«0» et «0.001 » ce qui revient à régler l’incrément des valeurs sur «(100-0)*0.001 == 0,1».
Les champs «Position:height» et «SliderStep:y» valent «300» et«0.04» ce qui donne une
taille de «300*0.04 == 12» pixels à l’ascenseur. Le champ «Value » initialise la position de
l’ascenseur sur la valeur «5.0 », en accord avec la chaîne de caractère «'5.0 %'» du champ
«String» de la zone de texte.
Afin que les propriétés des axes (e.g. leur «Tag») ne soient pas réinitialisées à chaque nouveau
tracé, leur champ «NextPlot» a été réglé sur «replacechildren».
Pour finir voici un récapitulatif des contrôles et de leurs propriétés qui ont été modifiéesainsi que
le code source des sous-fonctions qui ont été complétées ou rajoutées:
Tag: figure1 Tag : frame1
Name: ImgDCT BackgroundColor : gris foncé
Position: [0 32 720 640] Position : [0 0 80 640]
ImgClip
ImgStuff
17
function outExit = ImgLoad
theImage = double(imread(theFullName));
[g_NbR, g_NbC] = size(theImage);
g_DCT = dct2(theImage);
g_Mag = sqrt(abs(g_DCT));
g_Mag = 255*g_Mag/max(max(g_Mag));
g_Mag = g_Mag * sqrt(g_NbR*g_NbC)/20;
g_Mag(find(g_Mag > 255)) = 255;
function ImgClip
theRatio = 10*sqrt(theValue);
g_MaxR = round(g_NbR * theRatio/100);
g_MaxC = round(g_NbC * theRatio/100);
cla(findobj('Tag','AxesCompressed'));
function ImgStuff
theIDCT = idct2(theCDCT);
theCGray(find(theCGray > 255)) = 255; % correction numérique.
theCGray(find(theCGray < 0.0)) = 0.0; % correction numérique.
18
Le standard de la compression d’image JPEG utilise un algorithme nettement plus subtil pour
sélectionner et coder les fréquences et décompose l’image est en tuiles de taille modérée (e.g. 8x8
ou 16x16). Ainsi le contrôle de la qualité visuelle finale et le rapport qualité/efficacité se révèlent
être excellent alors que dans le cas de «ImgDCT», la qualité dépend non seulement du taux de
compression mais aussi de la taille de l’image. Et pour ne rien arranger la complexité de l’algorithme
(i.e. l'incidence de l'augmentation du nombre de donnée sur la durée d'exécution ou l’occupation
mémoire du programme) est de type «O(N^4)». C’est ainsi que le temps de calcul est multiplié
par seize chaque fois que la définition de l’image est doublée. Ce qui devient très vite dissuasif.
«ImgDCT» n’est pas vraiment une application professionnelle. Pour cela il faudrait commencer
par améliorer la robustesse du programme (e.g. en contrôlant le format et la taille de l’image).
Néanmoins, cet exemple montre qu’une application MATLAB comportant à la fois du calcul, de
l’affichage, et une interface graphique, nécessite finalement très peu de lignes de code !
Conclusion :
Cette (courte) introduction se concentre essentiellement sur les principes fondamentaux
de la programmation MATLAB et ne présente donc qu’une infime partie des fonctionnalités de la
plateforme. Le lecteur qui se serait laissé convaincre par le potentiel de cet outil est donc invité à
poursuivre son apprentissage par la lecture de la bibliographie spécialisée, et surtout par
l’expérimentation personnelle. Une expérience qui a personnellement été très gratifiante puisque
MATLAB m’aide considérablement dans mes travaux de recherche.
19