• Aucun résultat trouvé

[PDF] Ressource de formation approfondie en Matlab | Cours informatique

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Ressource de formation approfondie en Matlab | Cours informatique"

Copied!
19
0
0

Texte intégral

(1)

Introduction à 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.

(2)

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

Name Size Bytes Class

Var1 1x1 8 double array Var2 1x1 8 double array

Var3 1x1 16 double array (complex) Var4 3x2 48 double array

Var5 1x10 20 char array Grand total is 19 elements using 100 bytes

(3)

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').

Variables numériques et symboliques:

Un «double» est une valeur décimale codée en virgule flottante et en double précision. Cette

chaîne de 64 bits (e.q. 8 bytes ou octets) représente, une fois traduite en base 10, une mantisse signée à 16 chiffres significatifs, et un exposant signé à trois chiffres. Les constantes «realmax»,

«realmin», «eps», «Inf» et «NaN» sont spécifiques au calcul numérique. >> format long e % Notation scientifique étendue.

>> realmax % Plus grande valeur positive représentable.

ans = % e.g. "2 * realmax == Inf".

1.797693134862316e+308

>> eps % Plus petite nombre "n" tel que "n + 1 > 1".

ans = % e.g. "(eps/2 + 1) == 1".

2.220446049250313e-016 >> 1/0 ans = Inf % Infini. >> 0/0 ans = NaN % Not-a-Number.

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.

>> format % Notation par défaut.

>> vpa('pi', 80) % Approximation à 80 chiffres significatifs de la

ans = % constante  (irrationnelle et transcendante).

(4)

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 >> pi % Une constante. ans = 3.1416

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

Lorsqu’une expression implique des opérations possédant une précédence équivalente, l’associativité (i.e. l’ordre d’évaluation des opérandes) des opérateurs définit l’ordre dans lequel les opérations sont exécutées. Mis à part l’affectation et les opérateurs monadiques, les opérateurs possèdent une associativité de la gauche vers la droite.

>> 3 * (5 \ 15) % Equivalent à "3 * (15 / 5)". ans = 9 >> 3 * 5 \ 15 % Equivalent à "15 / (3 * 5)". ans = 1

En langage MATLAB, l’expression d’affectation est particulière puisqu’elle ne possède qu’un effet de bord (i.e. son évaluation modifie l’état du programme mais ne retourne pas de valeur).

(5)

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

>> CVEct = [1; 3; 5; 7] % Un vecteur colonne. CVEct = 1 3 5 7 >> size(CVect) ans = 4 1 >> Mat34 = [11 12 13 14; ... 21 22 23 24; ... 31 32 33 34] % Une matrice 3x4. Mat34 = 11 12 13 14 21 22 23 24 31 32 33 34 >> size(Mat34) ans = 3 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 >> 7:-2:1 % Incrément de -2. ans = 7 5 3 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 =

0.9501 0.4860 0.4565 0.2311 0.8913 0.0185 0.6068 0.7621 0.8214

(6)

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».

>> Mat34(8) % Indexage façon FORTRAN, BLAS, etc.

ans = 23

>> Mat34(2, 3) % "I = L + NL*(C-1)" donne "8 = 2 + 3(3-1)". ans =

23

>> Mat34([1 3], [1 4]) % Extraction d'une sous matrice. ans =

11 14 31 34

>> Mat34(:, end) = 0 % Equivalent à "Mat34(1:3, 4) = 0". Mat34 =

11 12 13 0 21 22 23 0 31 32 33 0

>> Mat34(:, end) = [] % Suppression de la dernière colonne. Mat34 =

11 12 13 21 22 23 31 32 33

>> Mat34(2, 4) = 24 % Construction par agrégation successive. Mat34 =

11 12 13 0 21 22 23 24 31 32 33 0

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 >> T = 1:3' % Equivalent à "1:(3')" avec "3' == 3". ans = 1 2 3

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 =

(7)

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

MesVariables.mat % par l'expression régulière "*.mat". >> clear V1 V2 V3 % Efface les variables.

>> load MesVariables % Recharge les variables.

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 MaMatrice.dat V4 -ascii –tabs % Format ASCII avec tabulation. >> type MaMatrice.dat % Lecture du fichier dans la console. 1.0000000e+000 2.0000000e+000

2.0000000e+000 3.0000000e+000 3.0000000e+000 4.0000000e+000

>> V6 = load('MaMatrice.dat') ; % Chargement dans une variable.

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

clear % Purge l'espace de travail.

clc % Efface la console.

Si un fichier M est présent dans le répertoire de travail ou la hiérarchie de recherche, il suffit de saisir son nom de base (i.e. sans chemin et sans extension) pour qu’il soit trouvé. Toutefois, ce nom ne doit pas être surchargé (i.e. désigner plusieurs objets à la fois). En effet, le langage MATLAB ne dispose pas de mécanisme pour résoudre ce genre d’ambiguïté. C’est ainsi que la résolution de nom s’arrête au premier homonyme trouvé parmi les variables, puis les fonctions internes, le répertoire de travail, et enfin la hiérarchie de recherche.

(8)

>> exist epuration % Test d'existence de l'identificateur. ans =

2

>> which epuration % Recherche le nom complet du fichier. C:\Documents and Settings\Virtual\Bureau\TP MATLAB\epuration.m

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

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

>> lookfor purge

EPURATION Purge l'espace de travail et efface la console.

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.

global g_Clock; % Déclaration d'une globale. g_Clock = clock; % Horaire et Date.

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)));

(9)

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 «r e t u r n» 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 == 0, error('Pas le bon nombre d''argumentsen entrée !'), end if isempty(inTab), outMin = []; outMax = []; return, end

if nargin == 1

outMin = min(inTab); outMax = max(inTab); else

outMin = min(inTab, [], inDim); outMax = max(inTab, [], inDim); end

>> [min, max] = minmax([ 1 2 5 3; 4 8 2 3], 2) min = 1 2 max = 5 8

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).

(10)

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 «swicth-case-otherwise-end » permet d’exprimer des prises de décision basées

sur des choix multiples comme pour ce convertisseur d’unité:

switch inUnit % Convertit x en mètres.

case 'cm'

y = x / 100;

case { 'millimeter', 'mm' } y = x / 1000;

otherwise

disp(['Unité inconnue: ' inUnit]) y = NaN;

end

L’instruction «for-end» permet de répéter un bloc d’instruction un nombre de fois fixe et

prédéterminé. Il faut initialiser la boucle avec une variable et un tableau de valeurs que prendra successivement la variable.

outInt = 1;

if (inInt <= 1), return, end % Factorielle, cas trivial.

for Cpt = 2:inInt % Factorielle, cas général.

outInt = outInt * Cpt; end

L’instruction «while-end» permet de répéter un bloc d’instruction un nombre de fois variable et

indéterminé, en se basant sur l’évaluation d’une expression conditionnelle.

outInt = 1;

if (inInt <= 1), return, end % Factorielle, cas trivial. Cpt = inInt;

while Cpt > 1 % Factorielle, cas général. outInt = outInt * Cpt;

Cpt = Cpt - 1; 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

(11)

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.

(12)

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])

ï2 ï1 0 1 2 0 0.2 0.4 0.6 0.8 1 Courbe pleine ï2 ï1 0 1 2 0 0.2 0.4 0.6 0.8 1 Diagramme en bâton ï2 ï1 0 1 2 0 0.2 0.4 0.6 0.8 1 Diagramme en barre ï2 ï1 0 1 2 0 0.2 0.4 0.6 0.8 1 Diagramme en escalier

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.

(13)

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. N = 1024; % Nombre d'échantillons. n = 1:N; % Indices des échantillons. t = linspace(0, 2*pi, N+1); % Définition d'un domaine t(end) = []; % temporel sur [0, 2[. y2 = sqrt(2/N)*6*cos(pi*(2*n-1)*(04-1)/(2*N)); % Harmonique de rang 3. y3 = sqrt(2/N)*8*cos(pi*(2*n-1)*(87-1)/(2*N)); % Harmonique de rang 86. y4 = sqrt(2/N)*7*cos(pi*(2*n-1)*(93-1)/(2*N)); % Harmonique de rang 92. y = y2 + y3 + y4; % Reconstruction du signal. theSpc = dct(y); % Calcul le spectre du signal. thePos = find( abs(theSpc) > 10^(-13) ); % Indices des harmoniques. theHar = thePos -1 % Rang des harmoniques. theMag = theSpc(thePos) % Amplitudes des harmoniques. theFigH = figure; % Création d'une figure vierge. plot(t, y, '.- ') % Affichage par points reliés. axis equal % Echelles des axes identiques. grid on % Affichage de la grille. xlabel('variable t'), ylabel('variable y') % Labels des axes.

title('Exemple de décomposition par DCT') % Titre du graphique. gtext('S(t)') % Annotation manuelle. hold on % Superposition des tracés . plot(t, y2 + 2, 'm.-', ... % Affichage de H03 en magenta. t, y3 + 3, 'g.-', ... % Affichage de H86 en vert. t, y4 + 4, 'y.-') % Affichage de H92 en jaune. text(2*pi, 2, ' H03') % Annotation du graphique. text(2*pi, 3, ' H86') % Annotation du graphique. text(2*pi, 4, ' H92') % Annotation du graphique. axis off % Cache les axes.

waitforbuttonpress % Pause utilisateur. close(theFigH) % Fermeture de la fenêtre. >> decomposition

theHar =

3 86 92 theMag =

(14)

Exemple de décomposition par DCT

S(t)

H03 H86 H92

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. [theName, thePath] = uigetfile('*.tiff'); % Sélection de l'image. if isequal(theName, thePath, 0), return, end; % Annulation.

theFullName = fullfile(thePath, theName); % Chemin complet.

theImage = double(imread(theFullName)); % Conversion uint8 -> double. [theNbR, theNbC] = size(theImage); % Taille de l'image.

theS = theNbR*theNbC; % Surface de l'image. theMag = abs(dct2(theImage)); % Spectre en amplitude. theSpc = sqrt(theMag); % Compression de l'échelle theMax = max(max(theSpc)); % de dynamique du signal. theSpc = 255*theSpc/theMax; % Etirement du contraste de theSpc = theSpc * sqrt(theS)/20 % manière ad hoc et avec theSpc(find(theSpc > 255)) = 255; % seuillage sur [0 255]. theFullName = fullfile(thePath, 'mag.tiff'); % Chemin complet.

(15)

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.

La figure 4 montre que l’énergie du signal (i.e. le carré de l’amplitude) se concentre principalement dans le coin supérieur gauche de l’image spectrale et décroît très rapidement en fonction de la fréquence. De plus comme les basses fréquences correspondent aux parties uniformes de l’image, on peut espérer pouvoir compresser l’image avec un filtre passe-bas (i.e. qui coupe les hautes fréquences) bidimensionnel simplifié tout en conservant un résultat visuellement acceptable. C’est l’objectif de l’application «ImgDCT» présentée en figure 5.

Figure 5: Compression d’image par filtrage fréquentiel simpl(ist)e. Avec une image de taille 256x256 et

(16)

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

(17)

Le champ «T a g» 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]

Tag: AxesGrayscale Tag: AxesSpectral

NextPlot : replacechildren NextPlot : replacechildren

Position: [123 347 256 256] Position: [441 347 256 256]

Tag: AxesCompressed Tag: AxesClipped

NextPlot : replacechildren NextPlot : replacechildren

Position: [123 23 256 256] Position: [441 23 256 256]

Tag: PushLoad Tag: PushStuff

FontSize : 10.0 FontSize : 10.0

Fontweight : bold Fontweight : bold

Position: [8 560 64 32] Position: [8 150 64 32]

String: 'LOAD' String: 'STUFF'

Tag: SliderRatio Tag: TextRatio

Max: 100.0 Position: [8 515 64 16]

Min: 0.0 String: [0.001 0.04]

Position: [30 210 18 300] SliderStep: [0.001 0.04] Value: 5.0

function PushLoad_Callback(hObject, eventdata, handles) if ImgLoad, ImgClip, ImgStuff, end

function SliderRatio_Callback(hObject, eventdata, handles) ImgClip

function PushStuff_Callback(hObject, eventdata, handles) ImgStuff

(18)

function outExit = ImgLoad

global g_NbR g_NbC % Taille de l’image.

global g_DCT g_Mag % Image spectrale et image spectrale rehaussée.

[theName, thePath] = uigetfile('*.tiff', '__ Open a grayscale TIFF image __'); if isequal(theName, thePath, 0)

outExit = 0; return; end;

outExit = 1;

theFullName = fullfile(thePath, theName); theImage = double(imread(theFullName)); [g_NbR, g_NbC] = size(theImage);

theGrayScale = theImage/255; % 0.0 <=> noir, 1.0 <=> blanc. axes(findobj('Tag','AxesGrayscale')); title('Grayscale Image');

image(cat(3, theGrayScale, theGrayScale, theGrayScale)); axis image; axis ij; 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;

axes(findobj('Tag','AxesSpectral')); title('Spectral Image'); image(g_Mag); colormap(jet(256)); axis image; axis ij;

function ImgClip

global g_NbR g_NbC % Taille de l’image.

global g_Mag % Image spectrale rehaussée. global g_MaxR g_MaxC % Taille du clip.

theValue = get( findobj('Tag','SliderRatio'), 'Value');

set(findobj('Tag','TextRatio'), 'String', sprintf('%2.1f %%', theValue)); theRatio = 10*sqrt(theValue);

g_MaxR = round(g_NbR * theRatio/100); g_MaxC = round(g_NbC * theRatio/100); theCMag = zeros(g_NbR, g_NbC);

theCMag(1:g_MaxR, 1:g_MaxC) = g_Mag(1:g_MaxR, 1:g_MaxC);

axes(findobj('Tag','AxesClipped')); title('Clipped Spectral Image'); image(theCMag); colormap(jet(256)); axis image; axis ij;

cla(findobj('Tag','AxesCompressed'));

function ImgStuff

global g_NbR g_NbC % Taille de l’image. global g_DCT % Image spectrale. global g_MaxR g_MaxC % Taille du clip. theCDCT = zeros(g_NbR, g_NbC);

theCDCT(1:g_MaxR, 1:g_MaxC) = g_DCT(1:g_MaxR, 1:g_MaxC); theIDCT = idct2(theCDCT);

theCGray(find(theCGray > 255)) = 255; % correction numérique. theCGray(find(theCGray < 0.0)) = 0.0; % correction numérique.

theCGrayScale = theIDCT/255; % 0.0 <=> noir, 1.0 <=> blanc. axes(findobj('Tag','AxesCompressed')); title('Compressed Image');

(19)

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.

Figure

Figure 1: Tracés de courbes 2D dans une figure MATLAB et édition manuelle du graphique.
Figure 2: Export au format EPS d’une figure MATLAB contenant quatre sous-graphes.
Figure 3: Décomposition harmonique par transformation en cosinus d’un signal discret de longueur 1024.
Figure 4: Transformée en cosinus d’une image en niveaux de gris (Source: NASA mission sts-97).
+2

Références

Documents relatifs

N' 15 Juillet-Décembre 2013 • La refondation de l'entreprise - outils et impacts Management &amp; Sciences Sociales 0... L'entreprise selon la théorie des

Sa thèse s’intègre dans le cadre du projet de recherche BISE2 (Business Information System for Energy and Environnement), et porte sur l’interprétation des événements dans

If the difference between the number of children that White and Visible Minorities females have were significant, then the discrimination portion of the wage

générer cette dernière est liée au pouvoir de marché de la société acquéreuse. Mais bien souvent, la création de valeur dans les F&amp;A n’est pas toujours au rendez-vous. De

L’analyse des messages publiés sur deux supports matériels de Twitter créés par la RTS a révélé comment des acteurs médiatiques et des acteurs non

We examine the impact of the abnormal part of recognized goodwill (proxy for PPA quality) on revisions of analyst expectations (i.e. revision of target prices, earnings

Our overview of the network of actors that participate in the construction of the notion of data journalism, according to the interviewees, reveals that there is a handful of

Dumontier et Elleuch (2002) observent sur le marché français à partir de 136 dates d’annonces de résultats et de publication d’états