Introduction à la programmation sous scilab
maria barbi, richard wilson
UPMC
11 septembre 2013
Vecteurs et matrices
Elements de programmation Fonctions
Graphisme
Statistique et probabilité Input Output
Charger une bibliothèque de fonctions
Un dernier exercice
Introduction à la programmation sous scilab
I
scilab : un logiciel comprenant à la fois un langage de programmation (fonctions, fonctions graphiques) et une interface utilisateur (aide en ligne, création d’images,...)
I
Les commandes scilab sont interprétées : il n’y a donc pas de compilation.
I
nombreux domaines du calcul scientifique, par exemple :
I
Algèbre linéaire
I
Interpolation, approximation ;
I
Solveur d’équation différentielles ;
I
Traitement du signal ;
I
Probabilité et statistiques.
I
Logiciel libre, donc gratuit, existant pour plusieurs plateformes (Windows, Mac, Linux).
I
Installation simple :
http://www.scilab.org/products/scilab/download.
Lancer scilab
I
Créer un répertoire où seront stockés vos fichiers et données.
I
Lancer scilab, soit en cliquant sur l’icone correspondante, soit en executant la commande scilab dans un terminal.
I
scilab est aussi une calculatrice ! Tapez : --> a=5+6
--> sqrt(12) --> 3^4 --> cos(a) --> (1+%i)^3
I
Pour rappeler la commande précédente (pour la modifier ou la corriger), appuyer sur la flèche «déplacement vers le haut».
I
L’aide en ligne est accessible à partir de l’option Help du menu ou en
tapant la commande help. on peut chercher un mot clé ou bien une
commande connue.
Variables spéciales et nombres complexes
I
Le nombre complexe √
−1 est prédefini et stocké dans la variable spéciale %i.
I
Une variable qui commence par le symbole % est prédefinie et ne peut pas être modifiée : voir aussi %pi.
I
Entrer une variable complexe : taper par exemple --> z1 = 1 + 2.5 * %i
--> z2 = 0.4 - %i
I
Les variables complexes peuvent être manipulées comme les variables réelles (taper par exemple z1+z2 ou z2/2).
I
fonctions prédéfinies utiles pour manipuler les complexes : --> real(z1) // partie réelle
---> imag(z1) // partie imaginaire --> modul = abs(z1) // module
--> theta = imag(log(z1)) // argument
--> modul*exp(%i*theta) // z
S’orienter dans l’arborescence
I
En ouvrant scilab, vous êtes situé dans un certain répertoire, appelons le, le «répertoire courant»
I
Pour connaître le nom du répertoire courant, taper : --> pwd
I
La commande --> ls
affiche le contenu du répertoire courant.
I
Pour changer de répertoire : --> cd ’nom_de_répertoire’
I
Les règles d’adressage sont celles d’Unix : un point (./) représente le répertoire courant, deux points (../) indiquent le répertoire racine.
Exercice : Créez un répertoire de travail sur votre compte et faites en
sorte de vous y déplacer dans scilab.
Méthode de travail
Il y a deux moyens d’exécuter des commandes scilab
1. Sasir les commandes l’une après l’autre à la suite du prompt -->.
2. Écrire une suite de commande dans un fichier, sauvegarder puis exécuter le fichier.
- Avantages :
I
pas besoin de ressaisir des commandes répétitives ;
I
conservation des programmes dans des fichiers, qui sont réutilisables et modifiables ;
I
mise au point de tâches longues et complexes ;
I
possibilité de créer ses propres fonctions.
- Un fichier contenant des commandes scilab s’appelle un script. On utilise d’habitude l’extension .sce.
- Il est exécuté (interprété) par scilab par la commande :
--> exec toto.sce
L’éditeur et un premier programme
Scilab possède un editeur de texte (Scipad ou SciNotes).
I
Ouvrez l’éditeur de texte : cliquez sur le bouton approprié, ou allez dans le menu Applications, ou encore tapez edit.
I
Créez un fichier essai1.sce que vous enregistrerez dans votre dossier contenant le texte suivant
a=4.1 // valeur de a (noter l’usage de //) b=3.5 // valeur de b
x=a/b; // valeur cherchee printf("voici le resultat :") disp(x)
Le « ;» à la fin de la commande rend celle-ci muette : le résultat n’est pas affiché. Regarder la page d’aide pour printf.
Exécuter le script avec le menu de l’éditeur, ou à partir de la fenêtre de
commande par : exec(’essai1.sce’).
Vecteur et matrices à la main
Vecteurs et matrices sont les objets qu’on utilise le plus souvent sous scilab. Un signal est toujours discretisé sous forme d’un vecteur.
I
Une matrice (un vecteur) peut être créé en spécifiant un par un leurs coefficients entre crochet :
--> v = [ 10 20 30 ] // vecteur ligne --> v = [ 10 20 30 ]’ // vecteur colonne
--> m = [ 0.1 0.2 0.3; 1 2 3; 10 20 30 ] // matrice
I
«’» = opérateur de transposition.
I
Les « ;» permettent de séparer les lignes dans une matrice.
I
Une fois créée, une variable est stockée en mémoire et donc réutilisable pour un calcul ultérieur. Taper v.
I
Chaque redéfinition de la variable efface de la mémoire la définition
précédente.
Vecteur et matrices de grande taille
I
Pour créer un vecteur de grande taille dont les coefficients suivent une progression arithmétique, on écrira :
--> v = 10:100;
--> v = [ 10:0.5:20 ];
--> v = linspace(1, 2, 10);
I
linespace(A, B, N), permettant de construire un vecteur d’N élements qui progressent linéairement entre une valeur initiale A et une valeur finale B.
I
logspace(a, b, N) permet de définir un vecteur contenant N valeurs entre 10^a et 10^b repartis selon une progression logaritmique.
I
zeros(N,M) crée une matrice nulle MxN.
I
ones(N,M) crée une matrice MxN contenant que des 1.
Taille des vecteur et matrices
Connaître les dimensions d’un vecteur ou d’une matrice :
I
size renvoie un vecteur de deux valeurs contenant le nombre de lignes et le nombre de colonnes de la matrice ou du vecteur fourni en argument :
--> m = zeros(2, 3);
--> size(m)
--> [nl nc] = size(m) --> nc
--> nl
I
length donne le nombre d’éléments d’une matrice, donc la longueur d’un vecteur
--> length(m)
--> v = zeros(1, 5);
--> length(v)
Recuperer un ou plusieurs éléments
Un élément d’une matrice est repéré par deux indices de position. L’accès à un élément permet de le lire ou d’en changer la valeur (affectation) :
--> v(1) --> m(2, 3) --> v(1) = 7
--> m(2, 3) = m(2, 3) + 1
Le symbole « :» permet de spécifier des des blocs d’indices :
I
L’écriture «i : j» signifie "tous les indices de i à j".
I
L’écriture « :» (sans indice) signifie "tous les indices".
--> v(1:3) // affiche v(1) v(2) v(3)
--> v(2:4) = 1 // affectation v(2)=v(3)=v(4)=1
--> b = m(1:2,2:3) // extraction du block 2x2
--> v = m(:,2) // extraction de la 2e colonne
Opérations élementaires entre vecteurs et matrices
I
Les opérateurs élémentaires +, -, *, / et ^ (puissance) de scilab sont des opérateurs matriciels.
--> A = [1 2 3 ; 4 5 6];
--> B = [7 8 ; 9 10 ; 11 12];
--> A*B
--> A+1 // NB : ajout d’un scalaire à une matrice
I
Attention aux dimensions ! --> A+B
!--error 8 Addition incohérente --> A+B’ // B’ est la transposée de B --> A^2
!--error 20 Une matrice carrée est attendue
Opérateurs «terme à terme» et fonctions élémentaires
I
Pour exécuter des opérations sur tous les éléments d’une matrice ou d’un vecteur, pris un par un : .* et .^.
Par exemple --> A.^2
retourne une matrice de même dimension que A dont les éléments sont ceux de A au carré.
I
Les fonctions élémentaires (cos, sin, log, exp, ...) appliquées à une matrice retournent la valeur de la fonction appliquée à chacun des termes de la matrice.
Par exemple
I
--> cos(A)
--> log(A)
Extraction d’une sous-matrice
I
Il est possible d’extraire une sous matrice d’une matrice quelconque en construisant les vecteurs formés par les indices de lignes et de colonnes à sélectionner.
I
Par exemple,
--> A = ones(1,5)’*linspace(1,5,5) --> B = A(1:2:5,1:3)
extrait de la matrice A les lignes 1,3 et 5 et les colonnes 1,2 et 3 ; --> A(:,[1,3,5]) = 1
construit une matrice 5 × 5 formée de 1 sur ses colonnes impaires ;
--> A = zeros(6,6); A(1:3,1:3) = 1; A(4:6,4:6) = 1
donne une matrice 6 × 6 formée de 2 blocs carrés de 3 × 3 ne
contenant que des 1.
Exercices
I
Construire la matrice de taille 9 × 9 dont tous les éléments sont nuls sauf les éléments du «centre» (i, j)={4, 5, 6}×{4, 5, 6} et les éléments du «bord », i={1, 9} ou j={1, 9}, qui tous valent 1.
I
Construire une matrice de taille m×n dont la composante (i, j) est égale à u(i)v(j) où u est un vecteur de taille m et v un vecteur de taille n que vous choisirez.
I
Construire sans effectuer de boucle la matrice 10 × 10 donnant les résultats de la table de multiplication de 1 à 10.
I
A partir des vecteurs u=[0,0.25,0.5,1] et v=(0:10)/10, construire
une matrice X de taille 4 × 10 dont la ligne i est formée de u(i) et
une matrice Y dont la colonne j est formée de v(j).
Programmer : boucles et tests
I
Programmer : définir et coder une suite d’algorithmes permettant de résoudre un problème.
I
Les structures de base sont :
"Si" Si condition alors faire ceci sinon faire cela
"Tant que" Tant que condition fare ceci
"Pour" Pour variable allant de borne inférieure à borne supérieure faire ceci
"Pour" Pour variable dans conteneur faire ceci (variante)
I
Dans scilab, comme dans la plupart des logiciels de programmation, les "mots clés" sont
if... (then)... elseif... else... end while... end for... end
Faire des tests dans scilab - 1
I
Pour effectuer un test : if, elseif, else, end. Par exemple, on écrira :
if condition 1 then instructions 1 elseif condition 2 then instructions 2; end
ou :
if valtest<0.5 instructions 1 else
instructions 2 end
ou encore, pour while : while condition 1 instructions 1 end
I
Rem : then peut être remplacé par un passage à la ligne ou virgule.
I
Dans tous ces cas, il faut utiliser une variable booléene, c’est-à-dire une variable qui ne peut que être égale qu’à vraie (T ou 1) ou fausse (F ou 0).
I
Exemple : taper 1 < 0.5 puis 1 > 0.5. Quelle est la réponse ?
Faire des tests dans scilab - 2
I
Comment écrire les conditions : Opérateurs logiques Instruction scilab
et &
ou |
non ∼
Relations Instruction scilab
= =
6= ∼= ou <>
< <
> >
≤ <=
≥ >=
I
Exemple (écrire tout sur une même ligne) :
if (a>=1 & b<>0), disp(a*b); elseif a<1, disp("a<1");
elseif b==0, disp("b=0"); end
tester avec plusieurs valeurs de a et b.
Boucles
I
La boucle for sert à répéter une opération sur un indice ou (c’est la même chose !) sur les composantes d’un vecteur («itération»).
I
Exemple : élever au carré les éléments d’un vecteur X : X = 1:0.5:10;
for i=1:length(X), X2(i) = X(i)*X(i);
end
I
Faisons la même chose avec une boucle while : X = 1:0.5:10;
i=1
while i<=length(X), X2(i) = X(i)*X(i);
i=i+1;
end
Exercice
On veut écrire de plusieurs manières un script qui calcule la somme des n premiers entiers :
1 + 2 + 3 + 4 + ... + n
1. Ecrire un script qui permet le calcul de la somme à l’aide d’une boucle for.
2. Même question avec une boucle while.
Fonctions sous scilab - 1
Un script peut contenir la définition d’une fonction réutilisable dans n’importe quel programme.
Un exemple pas par pas :
I
Créez un fichier titi.sce contenant les code : n=12;
c=1;
for i=1:n c=c*i;
end
I
Exécutez-le.
I
Tapez c et Enter/Entrée dans le terminal scilab pour afficher la valeur de la variable c.
I
Que calculent ces quelques lignes de programme ?
I
Est-ce important d’initialiser c à la valeur 1 ?
Fonctions sous scilab - 2
I
Modifiez votre script comme suit pour créer une fonction qu’on appellera toto, qui prend comme argument n et renvoie la valeur de c :
function c=toto(n)
c=1; // initialise c, variable locale for i=1:n
c=c*i;
end
endfunction
I
Enregistrer le fichier sous le nom toto.sci .
I
Dans la fenêtre scilab, executer le programme (une seule fois) : exec(’toto.sci’).
I
Taper maintenant toto(4) ou toto(5)... Et toto(-5) ?
Fonctions sous scilab - 3
I
Exercice : modifier la fonction toto.sce précédente, de sorte que si n est négatif ou n’est pas entier, la fonction renvoie zero plutôt que la valeur calculée de c. Tester la fonction obtenue.
I
Exercice : Programmer la fonction f (x ) = x
2en utilisant la méthode vue dans l’exercice précédent. Tester le résultat.
I
Exercice : Ecrire une fonction sommetheorique qui renvoie la formule mathématique n*(n+1)/2.
Cette formule coïncide-t-elle avec la somme des n premiers entiers
obtenue plus haut dans l’exercice sur la boucle for ?
Remarque : operateurs matriciels et itération
I
Nous avons vu que pour élever au carré les éléments d’un vecteur X, on peut écrire une boucle.
Cependant, on peut écrire aussi :
--> X2 = X.^2; // X2 : éléments de X au carré --> X2 = X.*X; // la même chose
I
Les opérateurs matriciels permettent d’éviter la plupart des boucles for, ce qui rend le programme beaucoup plus rapide ! Les boucles sont donc à éviter si possible.
I
De la même manière, il est donc possible de construire un vecteur suivant n’importe quelle fonction à partir du vecteur X : par exemple,
--> Y = (X.^2) .* cos(X);
où Y est la fonction x
2cos(x) appliquée au vecteur X.
Graphisme - 1 - La fonction plot
I
La fonction à utiliser pour la plupart des graphiques 2D est plot.
Dans son utilisation la plus simple (une fois définis X et Y) : --> plot(X, Y);
Ici x et y sont des vecteurs : il faut donc impérativement qu’ils aient même dimension.
I
Pour tracer en une seule fois plusieurs couples de variables : --> plot(x1, y1, x2,y2);
chacun des couples (xi, yi) devant avoir même dimension.
Exemple : (enregistrer dans un fichier)
x = 0:0.1:%pi; // vecteur des x
y = sin(x); // vecteur des y
z = x - x.^3/6 + x.^5/120; //DL
plot(x,y,x,z);
Graphisme - 2 - Styles
I
Code couleur (r ou red pour rouge, b pour bleu, yel... ) comme troisième argument entre guillements à plot : plot(x,y,’r’)
I
Symboles : il faut passer dans le troisième argument un symbole (’*’,
’+’, ou ’yel+’,...).
I
Style de ligne : ’-’, ’--’, ’-.-’ ou encore ’cyan*-’...
I
Titre et légendes : commande xtitle xtitle( "Titre du graphique" );
xtitle( "Titre", "Abs", "Ord" );
I
La fonction legend permet d’associer de légendes : legend("legend 1","legend 2");
Voir help plot pour plus de choix et de détails.
Graphisme - 2 - Styles
Exemple : à ajouter dans le plot précédent x = 0:0.1:%pi; // vecteur des x y = sin(x); // vecteur des y z = x - x.^3/6 + x.^5/120; //DL plot(x,y,’r’-,x,z,’b--’);
legend("sin x","DL(5) sin x");
xlab = "x";
ylab = "y";
titre = "DL à l ordre 5 de sin(x)"
xtitle(titre,xlab,ylab);
Graphisme - 3 - Plusieurs graphes
I
Par défaut, les graphes générés par des appels successifs à plot sont superposés.
I
Pour effacer le contenu de la fenêtre courante : --> clf;
I
La superposition automatique des graphes est désactivée par la commande : (Pour réactiver : "off".)
--> xset( "auto clear", "on" );
--> plot(X,X.^3)
I
Pour ouvrir une nouvelle fenêtre, la numéro n (à préciser) : xset(’window’,n)
I
Pour effacer le contenu de la fenêtre n :
--> clf(n);
Graphisme - 4 - Des alternatives
I
Il existe d’autres fonction permettant de faire des tracés 2D : notamment plot2d.
I
Les fonctions plot et plot2d diffèrent par la syntaxe des options permettant de varier l’aspect des courbes tracées.
I
plot2d plus directe par exemple pour les graphes en échelle log ou semilog :
x = -4:0.1:4;
y = exp(-x.^2);
plot2d(x,y,12,logflag=’nl’); //12 = une couleur xtitle("gaussienne en semilog");
I
Beaucoup d’autres fonctions de plot et fonctionnalités : des
possibilités à explorer !
Graphisme - 5 - en 3D
I
Pour des plots en 3D : plot3d
I
feval : Si f est une fonction et x et y sont des vecteurs, alors la fonction feval permet de bâtir une matrice z = f(x, y), comme dans cet exemple :
function [z]=selle(x,y) z=x^2-y^2
endfunction
x=[-1:0.1:1]’;y=x;
z=feval(x,y,selle);
I
On peut alors visualiser la fonction par plot3d(x,y,z)
Graphisme - 5 - plus chic
I
La gestion des propriétés d’un graphe passe par les variables handle, des pointeurs vers les objets du graphe : Figure, Axes, Polyline, etc., et leur propriétés.
I
Voir un handle : essayer get("current_figure").
I
Manipuler le handle : plus pratique de le stocker dans une variable : f = gcf() pour get("current_figure")
a = gca() pour get("current_axes") e = gce() pour get("current_entities") df = gdf() pour get("default_figure") da = gda() pour get("default_axes")
I
Un peu compliqué, mais une recherche sur le help ou internet permet
souvent de résoudre un problème donné.
Graphisme - 5 - plus chic...
I
Exemple : Dans notre exemple, on peut vouloir changer les couleurs et tourner le graphe :
plot3d(x,y,z)
f=gcf();//figure courante
f.color_map=hotcolormap(64); //entité color_map de f z=feval(x,y,z);
plot3d1(x,y,z,theta=-100,alpha=45)
Générateurs de nombre aléatoires
Il existe deux fonctions scilab permettant de générer des matrices de nombres aléatoires :
I
rand(n,m,’loi’) où n et m = nombre de lignes et colonnes,
’loi’ une chaîne de caractères décrivant la loi de probabilité choisie :
= ’uniform’ (par default) ou ’normal’ (gauss) --> X = rand(100, 1);
--> Y = rand(100, 10,’normal’);
I
grand(m, n, dist_type [,p1,...,pk]) : beaucoup plus générale lois : gaussienne, binomiale, χ
2, géometrique, etc etc
I
p1,...,pk sont les paramètres de la loi
--> Z = grand(1,1024,’bin’,10,0.3) // voir plot(Z)
I
Pour certaines distributions, il existe aussi des fonctions
correspondantes : cdfnor, cdfchi, cdfbin...
Histogramme, moyenne, écart type - 1
I
histplot calcule et affiche un histogramme des valeurs d’un vecteur.
I
Premier argument = nombre de classes à utiliser, ou vecteur donnant les bornes de ces classes :
--> Z = grand(1,1024,’bin’,10,0.3);
--> histplot(6, Z);
--> histplot([0:0.2:7], Z, style=5);
I
mean permet de calculer des moyennes de valeurs stockées dans des vecteurs et des matrices :
--> mx = mean(x) ;
I
variances : fonction variance : écart types : fonction stdev.
Histogramme, moyenne, écart type - 2
I
Pour les matrices, il est possible de procéder au calcul suivant les lignes ou les colonnes : exemples :
--> m = grand(50,200,’nor’,2,4);
--> mm = mean(m);
--> mmc = mean(m,’c’); // moyennes des lignes --> mmr = mean(m,’r’); // moyennes des colonnes --> mm1L = mean(m(1,:)); // moyenne 1e ligne
--> vmc = variance(m,’c’); // variances des lignes
--> std_m2c = stdev(m(:,2)); // écart type 2e colonne
--> std_m2c = sqrt(variance(m(:,2))); // idem
Déterminer une droite de régression
I
Si on dispose de n couples de points dont les abscisses et les
ordonnées sont stockées dans deux vecteurs colonnes x et y, on peut calculer les paramètres de la droite (a*x+b) par :
--> x = 0:0.05:%pi/2;
--> y = sin(x);
--> [a,b] = reglin(x, y);
I
pour afficher le résultat :
--> plot(x, y,’+’); // points
--> plot(x, a*x+b,’b’); // tracé de la droite
Exercice
I
Générer deux vecteurs aléatoires, normalement distribués, X et Y , de dimension (1000,1).
I
Tracer sur une même figure dans deux graphiques distincts ces deux vecteurs en fonction des indices des tableaux.
I
Calculer les moyennes de X , de Y .
I
Calculer les variances X et de Y .
I
Quel est le maximum de X ? de Y (commande max) ? Trouver les indices des tableaux X et Y correspondants aux maximas (commande find).
I
Soit S = X + Y et D = X − Y Tracer S et D sur une autre figure,
superposé sur un même graphique. Calculer la moyenne et la variance
de S et de D. Conclusion ?
Écrire un vecteur ou une matrice dans un fichier
I
Pour enregistrer un vecteur ou une matrice dans un fichier au format ASCII (fichier texte), utiliser la fonction write :
--> x = rand(10,5) ;
--> write(’data1’,x); // fichier ’data1’ créé
I
Attention : si le fichier existe déjà, on a un message d’erreur ! On peut spécifier l’état du fichier (new, old, unknown, scratch) :
u1=file(’open’,"./signal1.dat",’unknown’) write(u1,x)
file(’close’,u1);
I
On peut ainsi écrire plusieurs choses à la suite dans un même fichier : fid=file(’open’,"./signal1.dat",’unknown’)
write(fid,size(x));
write(fid,x)
file(’close’,fid);
Lire un vecteur ou une matrice dans un fichier
I
Pour lire le contenu du fichier, on utilise
read(nom_fichier, nombre_lignes,nombre_colonnes) ; le nombre de colonne peut être inconnu : -1.
u1=file(’open’,"./signal1.dat",’unknown’) signal1 = read(u1,-1,5);
file(’close’,u1);
Format
I
Lire et écrire un fichier contenant des caractères :
4ème argument = format du Fortran (peut être utile de le spécifier) : s = [’a’ ’a’ ’t’ ’t’ ’g’ ’c’ ’t’ ’a’ ’g’]
u1=file(’open’,"./signal2.dat",’unknown’) write(u1,s);
file(’close’,u1);
u1=file(’open’,"./signal2.dat",’unknown’) seq = read(u1,-1,1,"(a)")
file(’close’,u1);
s2=strcat(seq)
Ici, strcat permet d’avoir la concaténation des chaînes de
caractères : tester strcat(["a","b","c"]).
Sauver et charger un environnement
I
Pour enregistrer toutes les variables et fonctions qui ont été créés lors d’une session («l’environnement») :
save(’nom-de-fichier.sav’);
(ou menu Fichier → Charger l’environnement).
I
Pour charger l’environnement lors d’une autre session : save(’nom-de-fichier.sav’);
(ou menu Fichier → Charger l’environnement).
Charger une bibliothèque de fonctions
I
Une librairie est une collection de fonctions. Ces fonctions sont écrites dans un fichier *.sci. L’utilisateur peut définir ses propres librairies ou utiliser celles définies par d’autres utilisateurs.
I
La fonction exec permet de charger en mémoire des librairies. Par exemple, la commande
--> exec("ma\_librairie.sci")
charge les fonctions contenues dans le fichier ma_librairie.sci.
I