Prononcer
saïlab pour Sci-{entific} Lab...
Logiciel développé à l'INRIA (projet Méta), concurrent (clone?) gratuit de MATLAB
Outil de calcul numérique, pas de calcul formel, conçu pour aider à faire des simulations
Le type des objets n'est pas déclaré explicitement; Scilab attribue automatiquement un type aux variables en fonction de leur première affectation :
Exemples :Nombre
Booléen
Chaîne de caractères
Scilab transforme et arrondit les nombres en nombres décimaux et livre ses valeurs avec discrétion
-->f=(sqrt(5)-1)/2
f =
0.6180340
-->f-0.6180340
ans =
- 1.125E-08
-->f-.61803398874989
ans =
4.885E-15
-->f-.6180339887498948
ans =
1.110E-16
-->f-.6180339887498949
ans =
0.
-->f-.618033988749894885
ans =
0.
-->\%eps
\%eps =
4.441E-16
Scilab les assemble en tableaux de dimensions quelconques
-->b=3
b =
3.
-->b(2,1)=5
b =
! 3. !
! 5. !
-->b(2,2)=7
b =
! 3. 0. !
! 5. 7. !
On note que c'est toujours la même variable !
c=[1,2,3;4,5,6;..
7,8,9;10,11,12]
c =
! 1. 2. 3. !
! 4. 5. 6. !
! 7. 8. 9. !
! 10. 11. 12. !
La matrice identit\'e
-->c=eye(3,3)
c =
! 1. 0. 0. !
! 0. 1. 0. !
! 0. 0. 1. !
-->c=eye(2,3)
c =
! 1. 0. 0. !
! 0. 1. 0. !
-->c=eye(3)
c =
1.
-->c=eye(2,2,2)
!--error 42
incompatible RHS (right hand side)
De la place en g\'en\'eral
--> a=[1 2 3;4 5 6]
a =
! 1. 2. 3. !
! 4. 5. 6. !
--> matrix(a,1,6)
ans =
! 1. 4. 2. 5. 3. 6. !
--> matrix(a,3,2)
ans =
! 1. 5. !
! 4. 3. !
! 2. 6. !
Pour voir grand
-->z=zeros(100,100,10);
-->z=zeros(100,100,100);
!--error 17
stack size exceeded! (Use stacksize function
to increase it)
Memory used for variables : 6439
Intermediate memory needed: 1000007
Total memory available : 1000001
at line 11 of function zeros called by :
at line 15 of function zeros called by :
z=zeros(100,100,100);
Opérateurs de base : +, -, *, /, ^ sur les réels
(comme en Java)
Etendus aux tableaux, dans leur sens usuel des mathématiciens : A*B produit matriciel, produit scalaire, produit extérieur selon les dimensions de A et B
Variantes pour traiter élément par élément : A.*B
Opérateurs sur les matrices : A'
transposition, inv(A) inverse,
A\b système linéaire,
spec(A) spectre, etc.
Opérateurs de comparaison : == , < , > , <= , >= , <>
Opérateurs logiques : & , | , ~
Conditionnelle :
if condition then
instruction, instruction,... else
instruction, instruction,... end
Conditionnelle en cascade avec elseif
Branchement :La suite d'instructions correspondant à la valeur de var_test est sélectionnée et exécutée.
L'usage du end est nécessaire dans les fonctions.
Exemples :
-->if 3<0 then
-->x=3 else
-->x=5, y=7
x =
5.
y =
7.
-->num=17
num =
17.
-->select num, case 1, y="",
-->case 17, y="ouf", z=2
y =
ouf
z =
2.
Le tableau est fabriqué par un des constructeurs :
var = [1,2,3,5,7,11,13,17,19]
var = 1:.1:2 ([1,1.1,1.2,1.3,...,2])
var = rand(3,3)
La variable var est interne à la boucle : sa valeur est non définie dès la sortie de la boucle.
Dans le cas d'une itération matricielle, varprend successivement les valeurs des colonnes de la matrice.
Itération conditionnelle :
while condition,
instructions,
...
instructions,
end
Exemple (Syracuse) :
while x<>1,
if pmodulo(x,2)==0 then x=x/2
else x=floor((3*x+1)/2) end,
disp(x),
end
De l'usage du break dans les itérations : break fait sortir de la boucle qui le contient ;
while %t, {%t == vrai}function bonjour(x)
for i=1:1:x
disp("Bonjour")
end
endfunction
Arguments : non modifiables
Résultats : seul moyen de passer de nouvelles valeurs
Variables internes : inconnues de l'extérieur
la fonction grand permet de traiter encore plus de cas de lois (beta, binomial, chi, gamma, poisson, etc.)
Les affichages :Comment ça s'utilise?
1. Ouvrir une fenêtre xterm, se mettre dans le répertoire désiré (Probas), ouvrir une fenêtre emacs et une fenêtre scilab.2. Dans la fenêtre scilab lancer la commande
diary(td1.dia)
qui enregistrera le contenu de la session jusqu'à
diary(0)
3. Tester sous scilab le scénario de calcul,
le traduire en fonctions dans la fenêtre emacs
dans un fichier td1.sci;
revenir dans scilab pour lire ce fichier et définir les
fonctions qu'il contient
readf(td1.sci).
Ce résumé doit vous permettre de traduire vos modes de pensée algorithmique (acquis en Java dans le cours de Programmation) dans le langage de programmation Scilab sans pour autant en devenir un expert. Le style qui en résulte n'est souvent pas le meilleur possible, mais il a le mérite d'être sûr, clair et compréhensif. En l'absence d'outils de débogage commodes, mieux vaut déclarer soigneusement les tableaux avec leurs dimensions, ne pas utiliser les raccourcis Scilab qui risquent de vous perdre en cas de débordement ou de généralisation hasardeuse. En conséquence, il sera judicieux de considérer les tableaux comme des tableaux Java et non comme les objets matriciels ou vectoriels complexes de Scilab, sauf quand on on fait de l'algèbre linéaire. On fera juste une exception pour les tableaux mono-dimensionnels (assimilables à des vecteurs ligne ou colonne.
Tous les nombres manipulés sont
construits sur les réels; les entiers
ne le sont que par initialisation ou par « hasard »:
->3*(1+1.E-50)-3 = 0.
Les constantes numériques de base sont %e, %pi, %i, %eps ainsi que les constantes boolénnes %t, %f pour vrai et faux. Le calcul sur les nombres complexes se fait de façon usuelle, sous la forme 2+3*%i par exemple. La constante %eps définit la précision relative des calculs: deux nombres qui diffèrent de moins du quart de cette constante (!) sont indiscernables. Elle vaut 4.441E-16.
La structure de base est le tableau initialisé et
déclaré par exemple par
tableau=zeros(5,3) pour un tableau de zéros à 5 lignes et
3 colonnes,
tableau=eye(5,5) pour la matrice unité 5 x 5,
tableau=ones(5,1) pour un tableau de uns à 5 lignes et 1 colonne,
tableau=ones(1,5) pour un tableau de uns à 1 ligne et 5 colonnes.
Dans le cas des tableaux T de type (n,1) ou (1,n), on peut utiliser pour l'indexation le raccourci T(k) au lieu de T(k,1) ou T(1,k). Dans tous les autres cas une telle écriture produira des effets scabreux. C'est le seul raccourci que je conseille d'utiliser dans l'utilisation élémentgaire de Scilab.
On peut aussi déclarer des tableaux à trois dimensions et plus.
Scilab permet de manipuler les matrices ligne à ligne ou colonne par colonne. Je déconseille formellement d'utiliser ce genre de raccourci au moins au début.
Les chaînes de caractères (p. 32) se définissent comme il est d'usage entre apostrophes doubles: "vive l''info". Je recommande vivement d'utiliser les apostrophes doubles pour définir les chaînes de caractères et de réserver l'apostrophe au symbole ou à l'opérateur de transposition matricielle.
Une structure de liste, un peu fourre-tout, est disponible, mais qu'on ne devrait pas avoir à utiliser (p. 33-36).
On rencontre les mêmes que dans tous les autres langages de programmation.
Les expressions arithmétiques étendues aux matrices (p. 21-27):^ étant l'opérateur puissance
A\b résolution du
système linéaire Ax=b, spec(A) spectre, etc.
Les expressions booléennes:
- opérateurs de comparaison : == , < , > , <= , >= , <>
- opérateurs logiques : & , | , ~
Des fonctions mathématiques usuelles : p. 12
Des fonctions de génération aléatoire :
- rand pour la plus simple (p. 79)
- grand qui permet plus de paramétrages (p. 84).
Une variable est associée à chaque générateur qui sert à
avancer dans le calcul de la séquence pseudo-aléatoire; on
l'appelle semence (seed), on la découvre par l'opération semence=rand("seed") et on peut la modifier, par exemple pour
recommencer les simulations avec le même jeu de valeurs, au moyen de rand("seed",valeur). (p. 80)
Un mécanisme semblable, mais plus complexe existe pour la fonction grand. (p. 85)
Des exemples d'opérations sur les tableaux (p. 12-14):
produit
scalaire, produit
matriciel, produit extérieur, transposition, et
multiplication/division élément par élément
Des exemples de résolution de systèmes linéaires: p. 15-17.
Ce sont les mêmes qu'en Java. Seule la syntaxe change un peu.
Conditionnelles (p. 31):
if (<condition>)
<liste d'instructions>,
else <liste d'instructions>, end
où une liste d'instructions est une suite d'instructions séparés
par des virgules et se termine toujours par une virgule. Par
exemple:
if (x>5), y=4,z=5, else z=2,y=2, end
ou encore mieux, plus lisible et plus sûr:
if (x>5),
y=4,z=5,
else
z=2,y=2,
end
Plus généralement on peut mettre en cascade les conditionnelles
avec des elseif comme par exemple:
if (<condition>)
<liste d'instructions>,
elseif (<condition>),
<liste d'instructions>,
...
elseif (<condition>),
<liste d'instructions>,
else <liste d'instructions>,
end
Attention! Je déconseille l'usage du then car il est source
d'ennuis lors de l'exécution s'il est mal placé sur la ligne (les then ne doivent jamais se trouver en
début de ligne, il faut les mettre sur la même ligne que la
condition).
Je conseille de plus de mettre la condition entre
parenthèses pour plus de clarté.
Aiguillages sur une variable entière (p. 31):
select var_test,
case expr1 <liste d'instructions>,
case expr2 <liste d'instructions>,
...
else <liste d'instructions>,
end
Comme d'habitude on exécute la suite d'instructions qui correspond à la premi`ere expression rencontrée dont la valeur est celle de la variable de test; par défaut on exécute celle du else.
Itération bornée (p. 29):
for var=tableau
<liste d'instructions>,
end
La variable var, qui doit être une variable scalaire pour ne pas compliquer les choses, prend toutes les valeurs stockées dans l'expression tableau, successivement selon l'ordre induit par les colonnes du tableau. Le tableau le plus couramment utilisé est de type vecteur: (debut:pas:fin) qui en extension donne la suite d, d+p, d+2p,..., f, où d, p, f sont les valeurs respectives des expressions debut, pas et fin. On peut omettre pas lorsqu'il vaut 1.
Attention! La variable de boucle n'est active que pendant
l'exécution de la boucle; elle est ignorée en dehors. Si on veut
récupérer sa valeur, il faut le faire explicitement au moyen d'une
autre variable.
Si par hasard la variable de boucle était de type tableau,
l'exécution se ferait en mode vectoriel: à éviter absolument
pour commencer!
Itération conditionnelle (p. 30):
while condition,
<liste d'instructions>,
end
Cette instruction est, en tous points, semblable à celle de Java. La seule erreur serait d'oublier les virgules nécessaires après la condition et avant le end.
L'instruction break permet de sortir d'une quelconque de ces primitives.
Elles sont difficiles à définir à la console; il faut les définir sous Emacs ou Nedit puis les importer dans la fenêtre Scilab par getf. Le résultat, s'il y en a un, est indiqué sous la forme d'une liste (au sens de 2.2).
Forme générale de déclaration :
function [y1,y2,...,yk] = nomfonction(x1,x2,...,xl)
.....
corps de la fonction
.....
y1=..., instructions, ..., yk=...,
endfunction
Exemple :
function [y1,y2]=f(x1,x2)
y1=x1-x2
y2=x1+x2
endfunction
Il est impératif de donner une valeur aux diverses variables qui
vont former le résultat. Cependant, il importe aussi de respecter
un format de sortie qui est celui d'une liste hétérogène (voir
2.2). Avec le format complexe
function [y1,y2,...,yk] = nomfonction(x1,x2,...,xl)
il est impératif de donner au résultat, dans l'appel de la
fonction, le format attendu: [z1,z2,...,zk] = nomfonction(x1,x2,...,xl),
comme le montrent les exemples suivants. (Voir aussi les p. 93-94 pour
d'autres commentaires.)
-->function [y]= titi(x) -->y=[x,x,x] -->endfunction -->titi(3) ans = ! 3. 3. 3. ! -->function y=tata(x) -->y=[x,x,x] -->endfunction -->tata(3) ans = ! 3. 3. 3. ! -->titi(3)==tata(3) ans = ! T T T ! // pour s'amuser, on fait du boole'en -->function [y1,y2]=tutu(z) -->y1=z+2 -->y2=z-2 -->endfunction -->tutu(3) ans = 5. -->[x1,x2]=tutu(3) x2 = 1. x1 = 5.
Pour le passage des arguments, c'est un avatar des conventions de Java, et on les trouvera dans les résumés du cours ainsi qu'aux p. 40-41.
Enfin la fonction error(message) permet de sortir proprement d'une fonction en imprimant un message (p. 43).
Attention! L'usage de listes complexes et hétérogènes en sortie conduit à des erreurs d'exécution.
Pour déboguer une fonction ou un ensemble de fonctions, il faut
placer dans le corps du texte des instructions supplémentaires qui
permettront d'ob server les valeurs des variables importantes. En
cours d'exécution on verra apparaître ces valeurs sur la
console Scilab:
disp(liste_variable) imprime sur la fenêtre de travail
les valeurs des variables de la liste
qui s'imprime en sens inverse (de droite à gauche). En aucun cas
cette instruction ne permet-elle d'affecter un résultat à une fonction.
Très importantes sont les fonctions d'affichage graphique qui permettent
représenter des graphes fonctionnels et des histogrammes. Fondamentalement,
elles sont de deux types:
- les fonctions plot2d(vx,vy,options) et leurs variantes (p. 58-62)
qui prennent les deux tableaux
vx et vy,qui doivent être de même dimension, et
qui construisent alors le graphe de la fonction vy en fonction de
vx, tout en suivant les directives de couleurs, de pointillés, etc.
indiquées dans les options.
- la fonction histplot(vx,vy,options) qui procède semblablement
mais répartit les éléments de vy selon le découpage
imposé par vx. (cf. p. 83).
Ne pas oublier que les graphiques se superposent dans une même fenêtre et qu'on peut la nettoyer au moyen de la fonction xbasc(). D'autres fonctions de gestion des fenêtres graphiques sont explicitées p. 57.
Pour terminer cette section, voici quelques explications complémentaires concoctés par Michel Delasnerie.
La fonction 'plot2d2( x, y)' trace une fonction 'en escalier',
les vecteurs 'x' et 'y' doivent être de même type (ligne
ou colonne) et de même dimension :
le graphe est horizontal de 'x(1)' à 'x(2)' d'altitude 'y(1)'
et ainsi de suite...
mais d'après le célèbre théorème "piquets/intervalles"
la dernière valeur de 'y' - à savoir 'y($)' - n'est
représentée que comme une verticale d'abscisse 'x($)'
de 'y($-1)' à 'y($)' et non par un trait horizontal,
la dernière marche manque !
Pour la tracer il faut rajouter
- à droite de 'x' un piquet de plus de valeur appropriée ;
- à droite de 'y' une valeur fictive ( 0 ou 'y($)').
(remplacer 'a droite' par 'en bas', dans le cas de colonnes)
Exemple :
-->x = 1:4
x =
! 1. 2. 3. 4. !
-->[x,5]
ans =
! 1. 2. 3. 4. 5. !
--> y = x;
-->y($)
ans =
4.
-->[y, y($)]
ans =
! 1. 2. 3. 4. 4. !
-->xbasc(); plot2d2( x, y, 1, "011", " ", ..
[0,0,6,5], [0,6,0,5])
--> // Il manque la dernie`re marche (que le saut)
-->xbasc(); plot2d2( [x,5], [y,y($)], 1, "011", ..
" ", [0,0,6,5], [0,6,0,5])
--> // Maintenant elle y est (en entier) !
Les arguments optionnels ont été délibérément choisis pour que le cadre déborde largement [de +1] tout autour du graphe.
La fonction 'hisplot( x, data)' a comme arguments principaux deux vecteurs (eventuellement de types distincts) - 'x' est une suite de piquets encadrant des intervalles ; - 'data' des données, aléatoires ou non, en quantité, en général, beaucoup plus grande que la taille de 'x'. 'hisplot' commence par calculer l'histogramme des 'data' en fonction des intervalles déterminés par 'x' comme à la page 18 du polycopié 'Aléatoire' de Francis Comets, puis en trace le graphe 'en rectangle'.
Ces deux fonctions ne font pas le même travail, 'histplot' en fait plus : pour que 'plot2d2' fasse la même chose l'argument 'y' doit être calculé avec la formule des histogrammes (les fréquences normalisées par les longueurs d'intervalle) à partir de données ou de tirages aléatoires.
Pour charger un fichier de définitions de fonctions on utilise la
primitive getf ("nom_de_fichier"); si l'une des fonctions a été modifiée un avertissement le signale:
->getf("poisson.new.sci")
Warning :redefining function: loipoisson2
Pour sauver un ensemble de valeurs, ou en acquérir depuis un
fichier, on utilisera les fonctions save et load qui
permettent de sauver dans un fichier des variables, ou de les charger
depuis une sauvegarde: voir p. 18:
- save("fichier", liste de variables)
- load("fichier", liste de noms de variables).
On peut aussi utiliser des mécanismes plus sophistiqués,
inspirés de Fortran comme les fonctions
write et read, dont la
syntaxe type est la suivante:
write(unit,variable,format)
write(unit,nombres,format).
Dans ces expressions:
- unit est un nom de fichier
(éventuellement %io(1) pour la fenêtre Scilab en lecture et
%io(2) pour la fenêtre Scilab en écriture);
- variable est une expression Scilab dont la valeur sera
écrite dans le fichier;
- nombres est une suite d'entiers ou de variables entières)
qui indique le nombre de lignes et/ou d'objets à lire dans le fichier;
- format indique comment les valeurs sont codées dans le
fichier (ce paramètre est facultatif).
On trouvera des exemples commentés en section 3.5.7 (p. 48-51).
Les commandes suivantes ont aussi leur intérêt:
- who : pour lister les variables actives (p. 19, p. 41)
- timer() : pour estimer un temps de calcul (p. 52)
- stacksize(taille) : pour changer la hauteur de pile (p.19)
- clear v : pour supprimer la variable v de
l'environnement.
La barre de menus dans la fenêtre d'exécution Scilab comprend
plusieurs touches utiles:
1. File :
- « file operations » permet de charger des fichiers,
- « kill » ferme la fenêtre,
- « quit » élimine le calcul courant suspendu;
2. Control :
- « stop » suspend le calcul (on augmente la pile d'exécution),
- « resume » le reprend,
- « abort » tue le calcul suspendu et replace au niveau inférieur,
- « restart » remet Scilab dans son environnement initial (et on
perd tout);
3. Graphic Window : aide à la gestion des fenêtres;
4. Help : l'aide en ligne.
error 8 : addition incohérente
error 10 : multiplication incohérente
error 21 : index invalide
error 42 : incompatible RHS (membre droit d'instruction)
error 58 : incorrect number of arguments in function call
error 241 : File exo1.sci does not exist or read access denied
Vous vous êtes trompé de fichier ou vous êtes sans doute dans un mauvais
répertoire. Changez de fichier, ou bien fermez Scilab, changez de
répertoire, relancer Scilab et recommencez.