• Aucun résultat trouvé

Scripts (programmes), mode batch

Dans le document Cours MATLAB et GNU Octave en pdf (Page 108-111)

Éditeur/débugger intégré à Octave GU

7.5 Scripts (programmes), mode batch

7.5.1 Principes de base relatifs aux scripts

Un "script" ou "programme" MATLAB/Octave n'est rien d'autre qu'une suite de commandes MATLAB/Octave valides (par exemple un "algorithme" exprimé en langage MATLAB/Octave) sauvegardées dans un M-file, c'est-à-dire un fichier avec l'extension .m.

Par opposition aux "fonctions" (voir chapitre suivant), les scripts sont invoqués par l'utilisateur sans passer d'arguments, car ils opèrent directement

dans le workspace principal. Un script peut donc lire et modifier des variables préalablement définies (que ce soit interactivement ou via un autre script),

ainsi que créer de nouvelles variables qui seront accessibles dans le workspace (et à d'autres scripts) une fois le script exécuté.

Il est important de noter qu'il n'est pas possible de définir de fonctions à l'intérieur d'un script (même si l'on ne souhaite utiliser celles-ci que par le script).

Il est possible (et vivement conseillé) de documenter le fonctionnement du script vis-à-vis du système d'aide en ligne help de MATLAB/Octave. Il suffit, pour cela, de définir, au tout début du script, des lignes de commentaire (lignes débutant par le caractère %). La commande help M-file affichera alors automatiquement le 1er bloc de lignes de commentaire contiguës du M-file. On veillera à ce que la toute première ligne de commentaire (appelée "H1-line") indique le nom du script (en majuscules) et précise brièvement ce que fait le script, étant donné que c'est cette ligne qui est affichée lorsque l'on fait une recherche de type lookfor mot-clé.

Pour exécuter un script, on peut utiliser l'une des méthodes suivantes, selon que l'on soit dans l'éditeur intégré, dans la console MATALAB/Octave ou depuis un autre script :

a) Run , Save File and Run ou F5 b) script enter

c) run('{chemin/}script{.m}') ou run {chemin/}script{.m} d) source('{chemin/}script.m') ou source {chemin/}script.m

a) Lancement de l'exécution depuis l'éditeur intégré MATLAB ou Octave GUI

b) Le script doit obligatoirement se trouver dans le répertoire courant ou dans le path de recherche MATLAB/Octave (voir chapitre

"Environnement"). Il ne faut pas spécifier l'extension .m du script

c) Cette forme permet d'exécuter un script situé en dehors du répertoire courant en indiquant le chemin d'accès (absolu ou relatif). On peut omettre

ou spécifier l'extension .m du script

d) Cette forme est propre à Octave. Dans ce cas l'extension .m doit obligatoirement être indiquée

En phase de debugging, on peut activer l'affichage des commandes exécutées par le script en passant la commande echo on avant de lancer le script, puis désactiver ce "traçage" avec echo off une fois le script terminé.

Exemple de script: Le petit programme ci-dessous réalise la somme et le produit de 2 nombres, vecteurs ou matrices (de même dimension) demandés interactivement. Notez bien la 1ère ligne de commentaire (H1-line) et les 2 lignes qui suivent fournissant le texte pour l'aide en-ligne. On exécute ce programme en frappant somprod (puis répondre aux questions interactives...), ou l'on obtient de l'aide sur ce script en frappant help somprod .

%SOMPROD Script réalisant la somme et le produit de 2 nombres, vecteurs ou matrices %

% Ce script est interactif, c'est-à-dire qu'il demande interactivement les 2 nombres, % vecteurs ou matrices dont il faut faire la somme et le produit (élément par élément) V1=input('Entrer 1er nombre (ou expression, vecteur ou matrice) : ') ;

V2=input('Entrer 2e nombre (ou expression, vecteur ou matrice) : ') ; if ~ isequal(size(V1),size(V2))

error('les 2 arguments n''ont pas la meme dimension') end

%{

1ère façon d'afficher les résultats (la plus propre au niveau affichage, mais ne convenant que si V1 et V2 sont des scalaires) :

fprintf('Somme = %6.1f Produit = %6.1f \n', V1+V2, V1.*V2) 2ème façon d'afficher les résultats :

Somme = V1+V2 Produit = V1.*V2 %}

% 3ème façon (basique) d'afficher les résultats disp('Somme =') , disp(V1+V2)

disp('Produit =') , disp(V1.*V2)

return % Sortie du script (instruction ici pas vraiment nécessaire, % vu qu'on a atteint la fin du script !)

7.5.2 Exécuter un script en mode batch

Pour autant qu'il ne soit pas interactif, on peut exécuter un script depuis un shell (dans fenêtre de commande du système d'exploitation) ou en mode batch (p.ex. environnement GRID), c'est-à-dire sans devoir démarrer l'interface-utilisateur MATLAB/Octave, de la façon décrite ici.

Avec MATLAB :

En premier lieu, il est important que le script.m s'achève sur une instruction quit, sinon la fenêtre MATLAB (minimisée dans la barre de tâches sous Windows) ne se refermera pas

Passer la commande (sous Windows depuis une fenêtre "invite de commande", sous Linux depuis une fenêtre shell) : matlab -nodesktop -nosplash -nodisplay -r script { -logfile fichier_resultat } où :

sous Windows, il faudra faire précéder la commande matlab du path (chemin d'accès à l'exécutable MATLAB, p.ex. C:\Program Files (x86)\MATLAB85\bin\ sous Windows 7)

à la place de -logfile fichier_resultat on peut aussi utiliser > fichier_resultat le fichier de sortie fichier_resultat sera créé (en mode écrasement s'il préexiste)

Sachez finalement qu'il est possible d'utiliser interactivement MATLAB en mode commande dans une fenêtre terminal (shell) et sans interface graphique (intéressant si vous utilisez MATLAB à distance sur un serveur Linux) ; il faut pour cela démarrer MATLAB avec la commande : matlab -nodesktop - nosplash

Avec Octave :

Contrairement à MATLAB, il n'est ici pas nécessaire que le script.m s'achève par une instruction quit Vous avez ensuite les possibilités suivantes :

Depuis une fenêtre de commande (fenêtre "invite de commande" sous Windows, shell sous Linux), frapper : octave --silent --no-window-system script.m { > fichier_resultat }

En outre, sous Linux ou macOS, vous pouvez aussi procéder ainsi :

- faire débuter le script par la ligne: #!/usr/bin/octave --silent --no-window-system - puis mettre le script en mode execute avec la commande: chmod u+x script.m

- puis lancer le script avec: ./script.m { > fichier_resultat } Notez que, dans ces commandes :

9/14/2018

MATLAB et Octave - 7. Programmation : interaction, structures de contrôle, scripts, fonctions, entrées-sorties, debu…

https://enacit1.epfl.ch/cours_matlab/mfiles.shtml#editeur_debugger

9/22

avec > fichier_resultat, les résultats du script sont redirigés dans le fichier_resultat spécifié et non pas affichés dans la fenêtre de commande

--silent (ou -q) : n'affiche pas les messages de démarrage de Octave

--no-window-system (ou -W) : désactive le système de fenêtrage (i.e. X11 sous Linux) ; les graphiques apparaissent alors dans la fenêtre de commande (simulés par des caractères), mais il reste possible d'utiliser la commande saveas pour les sauvegarder sous forme de fichiers- image

en ajoutant encore l'option --norc (ou -f) ou --no-init-file), on désactiverait l'exécution des prologues (utilisateurs .octaverc, et système)

vous pourriez donc aussi faire débuter votre script par la ligne #!/usr/bin/octave -qWf Ex: le script ci-dessous produit un fichier de données "job_results.log" et un graphique "job_graph.png" :

% Exemple de script MATLAB/Octave produisant des données et un graphique % que l'on peut lancer en batch avec :

% matlab -nosplash -nodisplay -nodesktop -r job_matlab > job_results.log

% octave --silent --no-window-system --norc job_matlab.m > job_results.log data = randn(100,3)

fig = figure;

plotmatrix(data, 'g+');

saveas(fig, 'job_graph.png', 'png') quit

A l'intérieur de votre script, vous pouvez récupérer sur un vecteur cellulaire avec la fonction argv() les différents arguments passés à la commande octave

En outre avec Octave, si vous ne désirez exécuter en "batch" que quelques commandes sans faire de script, vous pouvez procéder ainsi : Depuis une fenêtre de commande ou un shell, frapper: octave -qf --eval "commandes..." { > fichier_resultat.txt }

Ex: la commande octave -qf --eval "disp('Hello !'), arguments=argv(), a=12; douze_au_carre=12^2, disp('Bye...')" affiche : Hello ! arguments = { [1,1] = -qf [2,1] = --eval

[3,1] = disp('Hello'), arguments=argv(), a=12; douze_au_carre=12^2, disp('Bye...') }

douze_au_carre = 144 Bye...

7.5.3 Tester si un script s'exécute sous MATLAB ou sous Octave

Étant donné les différences qui peuvent exister entre MATLAB et Octave (p.ex. fonctions implémentées différemment ou non disponibles...), si l'on souhaite réaliser des scripts portables (i.e. qui tournent à la fois sous MATLAB et Octave, ce qui est conseillé !) on peut implémenter du code conditionnel relatif à chacun de ces environnements en réalisant, par exemple, un test via une fonction built-in appropriée.

Ex: on test ici l'existence de la fonction built-in OCTAVE_VERSION (n'existant que sous Octave) : if exist('OCTAVE_VERSION') % Octave

% ici instruction(s) pour Octave else % MATLAB

% ici instruction(s) équivalente(s) pour MATLAB end

7.6 Fonctions

7.6.1 Principes de base relatifs aux fonctions

Également programmées sous la forme de M-files, les "fonctions" MATLAB/Octave se distinguent des "scripts" par la manière de les appeler : [variable(s) de sortie ...] = nom_fonction(paramètre(s) d'entree ...)

On invoque donc une fonction en l'appelant par son nom_fonction et en lui passant, entre parenthèses, les paramètres d'entrée requis (valeurs, noms de variables, expressions) ;

s'il n'y a pas de paramètre à passer, on peut omettre les parenthèses, par exemple : beep() ou beep

Si la fonction retourne des valeurs de sortie, on l'invoque en l'affectant à une(des) variable(s) entre crochets ; s'il n'y a qu'une valeur de sortie, les crochets peuvent être omis

Le mécanisme de passage des paramètres à la fonction se fait "par valeur" (c'est-à-dire copie) et non pas "par référence". La fonction ne peut donc pas modifier les variables d'entrée au niveau du script/fonction appelant ou du workspace principal.

Les variables créées à l'intérieur de la fonction sont dites "locales", c'est-à-dire qu'elles sont par défaut inaccessibles en dehors de la fonction (que ce soit dans le workspace principal ou dans d'autres fonctions ou scripts). Chaque fonction dispose donc de son propre workspace local.

Si l'on tient cependant à ce que certaines variables de la fonction soient visibles et accessibles à l'extérieur de celle-ci, on peut les rendre "globales" en les définissant comme telles dans la fonction, avant qu'elles ne soient utilisées, par une déclaration global variable(s) (voir plus bas). Il faudra aussi faire une telle déclaration dans le workspace principal (et avant d'utiliser la fonction !) si l'on veut pouvoir accéder à ces variables dans le workspace principal ou ultérieurement dans d'autres scripts !

Il est en outre possible de déclarer certaines variables comme "statiques" avec la déclaration persistent (voir aussi plus bas) au cas où l'on désire, à chaque appel à la fonction, retrouver certaines variables internes dans l'état où elles ont été laissées lors de l'appel précédent. Attention, cela ne devrait pas être utilisé pour les fonctions qui doivent être récursive !

Contrairement aux scripts dans lesquels on n'a pas le droit de définir de fonctions internes, il est possible, dans un M-file de fonction, de définir

plusieurs fonctions à la suite les unes des autres. Cependant seule la première fonction du M-file, appelée fonction principale (main function), sera

accessible de l'extérieur. Les autres, appelées fonctions locales (ou subfunctions), ne pourront être appelées que par la fonction principale ou les autres fonctions locales du M-file.

Il est finalement possible de définir des fonctions à l'intérieur du corps d'une fonction. Ces fonctions imbriquées (nested function) ne pourront cependant être invoquées que depuis la fonction dans laquelle elles sont définies.

Le code de toute fonction débute par une ligne de déclaration de fonction qui définit son nom_fonction et ses arguments args_entree et args_sortie (séparés par des virgules), selon la syntaxe :

function [argument(s)_de_sortie, ...] = nom_fonction(argument(s)_d_entree, ...) les crochets ne sont pas obligatoires s'il n'y a qu'un arg_sortie

s'il n'y a pas de paramètre de sortie, on peut omettre []= s'il n'y a pas de paramètre d'entrée, on peut omettre ()

Octave affiche un warning si le nom de la fonction principale (tel que défini dans la 1ère déclaration de fonction) est différent du nom du M-file. Sous MATLAB, le fait que les 2 noms soient identiques n'est pas obligatoire mais fait partie des règles de bonne pratique.

Se succèdent donc, dans le code d'une fonction (et dans cet ordre) :

1. déclaration de la fonction principale (ligne function... décrite ci-dessus)

2. lignes de commentaires (commençant par le caractère %) décrivant la fonction pour le système d'aide en-ligne, à savoir :

• la "H1-line" précisant le nom de la fonction et indiquant des mots-clé (ligne qui sera retournée par la commande lookfor mot-clé) • les lignes du texte d'aide (qui seront affichées par la commande help nom_fonction)

Dans le document Cours MATLAB et GNU Octave en pdf (Page 108-111)