Vous êtes sur la page 1sur 87

Scilab: une introduction Version 1.

0
J.Ph. Chancelier1 31 ao ut 2004

Cermics, Ecole Nationale des Ponts et Chauss ees, 6 et 8 avenue Blaise Pascal, 77455, Marne la Vall ee, Cedex 2
1

Table des mati` eres


I Une introduction ` a Scilab 5
7 7 9 10 12 15 16 19 22 24 25 26 27 28 30 33 35 40 45 45 50 53 55

1 Une introduction ` a Scilab 1.1 Pr esentation du langage Scilab . . . . . . 1.2 Quelques id ees g en erales . . . . . . . . . 1.3 Les objets . . . . . . . . . . . . . . . . . 1.4 Objets vectoriels et matriciels . . . . . . 1.4.1 Extraction, insertion et d el etion . 1.4.2 Scalaires et matrices de scalaires . 1.4.3 Cha nes de caract` eres . . . . . . . 1.4.4 Bool eens et matrices de Bool eens 1.4.5 Matrices creuses . . . . . . . . . . 1.4.6 Les listes . . . . . . . . . . . . . . 1.5 Programmer avec Scilab . . . . . . . . . . 1.5.1 Branchement et aiguillages . . . . 1.5.2 It erations . . . . . . . . . . . . . . 1.5.3 Fonctions Scilab . . . . . . . . . . 1.5.4 Contr oler lex ecution des fonctions 1.6 Fonctions dentr ees sorties . . . . . . . . . 1.7 Graphiques avec Scilab . . . . . . . . . . . 1.8 Interfa cage . . . . . . . . . . . . . . . . . 1.8.1 Ecriture dune interface . . . . . . 1.8.2 Chargement et utilisation . . . . . 1.8.3 intersci . . . . . . . . . . . . . . . 1.8.4 Utilisation de la commande link .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . .

II

Examples illustratifs

59
61 62 63 63 64 65

2 Programmer : Arbres et matrices de ramication 2.0.5 Matrices de ramications . . . . . . . . . . . . . . . 2.0.6 Tirage al eatoire des ordres des ar etes lles . . . . . . 2.0.7 Construction dun arbre . . . . . . . . . . . . . . . . 2.0.8 Utilisation des graphes Scilab pour visualiser larbre 2.1 Repr esentation graphique directe . . . . . . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

Table des mati` eres 71 71 72 73 79 79 80 81 82

3 Programmer : Arbres et DOL-syst` emes 3.0.1 DOL-syst` emes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.0.2 Interpr etation des cha nes . . . . . . . . . . . . . . . . . . . . . . . . . 3.0.3 Dessiner un arbre . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 Programmer : Musique serielle 4.1 Musique s erielle . . . . . . . . . . . . . 4.1.1 G en erer les 48 phrases possibles 4.1.2 Le codage des notes en pmx . . 4.2 Utilisation du syst` eme de Lorenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Premi` ere partie

Une introduction ` a Scilab

Chapitre 1

Une introduction ` a Scilab


1.1 Pr esentation du langage Scilab

Scilab est un langage interpr et e, ` a typage dynamique, extensible et gratuit. Il a dabord et e d evelopp e sous le nom de Basile (Inria projet Meta2) puis sous le nom de Scilab par le Scilab Group (Chercheurs du projet Inria Metalau et de lEnpc Cermics). Son d eveloppement actuel est coordonn e par un Consortium et un nombre non n egligeable de contributions proviennent de contributeurs ext erieurs. Scilab est un langage portable. Il est port e sur les di erentes variantes dUNiX, mais aussi sur Windows et MacOS X. On peut consid erer que Scilab est un langage de script puisque il peut servir ` a une illustration algorithmique en quelques lignes. Mais cest aussi un langage de programmation et la librairie Scilab contient presque 100000 lignes de code de fonctions ecrites en Scilab. La syntaxe de Scilab est simple, les donn ees propres au calculs scientique (Matrices) y sont dun maniement ais e. Cela conduit a des programmes compacts et lisibles souvent beaucoup courts que des programmes C, C++ ou Java equivalents. Scilab est avant tout d edi e au calcul scientique. Il permet dacc eder de fa con ais ee ` a de nombreuses librairies num eriques : calcul matriciel, int egration num erique, optimisation, equations di erentielles, . . . . Scilab est extensible. On peut facilement rajouter de nouvelles fonctionnalit es a Scilab avec des librairies ext erieures existantes. De nombreuses contributions qui utilisent cette possibilit e sont disponibles sur le site ociel de Scilab :
http://www-rocq.inria.fr/scilab/

Un site Scilab ` a lEnpc contient de nombreux travaux pratiques illustrant les cours de math ematiques propos ee a lEnpc :
http://cermics.enpc.fr/scilab/

La fen etre principale de Scilab (dans la version Unix Gtk) se pr esente comme sur la gure 1.3. La visualisation des r esultats num eriques peut se faire gr ace ` a une biblioth` eque graphique utilisable interactivement (Voir Figure 1.1). Enn, les aides de toutes les fonctions sont accessibles en ligne et elles comportent g en eralement un exemple de code Scilab illustrant leur utilisation. Les deux commandes les plus importantes de Scilab sont sans doute help et apropos, elles permettent de naviguer dans laide. De nombreuses demonstrations sont aussi disponibles en lignes (Menu demos).

Chapitre 1. Une introduction a ` Scilab

Fig. 1.1 Une fen etre graphique

Fig. 1.2 Une fen etre de laide en ligne

1.2. Quelques id ees g en erales

Fig. 1.3 La fen etre principale

1.2

Quelques id ees g en erales

Le langage Scilab est un langage qui a et e initialement con cu pour privil egier les op erations matricielles en ciblant des applications scientiques. Les objets ne sont jamais d eclar es ou allou es explicitement, ils ont un type dynamique (renvoy e par la fonction typeof) et leur taille peux changer dynamiquement au gr e des op erateurs qui leurs sont appliqu es :

-->a= rand(2,3); -->typeof(a) plexes (en double pr ecision) ans = constant -->a= [a, zeros(2,1)] a = ! ! 0.2113249 0.7560439 0.0002211 0.3303271

a est (apr` es ex ecution de =) une matrice 2x3 scalaire type de a ? constant d esigne les matrices de r eels ou de com-

la taille de a augmente

0.6653811 0.6283918

0. ! 0. ! nouveau type de a par r eaectation.

-->a= scilab; typeof(a) ans = string -->exists(a) ans = 1. -->clear(a); exists(a) ans = 0.

a est-elle d enie ?

destruction explicite de a

10

Chapitre 1. Une introduction a ` Scilab

La m emoire disponible ` a un moment donn e par lutilisateur peut- etre contr ol ee (cest-` adire demand ee ou chang ee) au moyen de la commande stacksize. Elle est bien s ur limit ee par la m emoire dynamique que lon peut demander (m emoire allou ee par malloc sur le tas). Les commandes who et whos permettent dobtenir les noms et les tailles des variables pr esentes dans lenvironnement dex ecution.
-->stacksize() mum de variables ans = ! 1000000. 5336. ! m emoire disponible en nombre de doubles (8 octets) et nombre maxi-

-->A=rand(1000,1000); noter quune expression termin ee par ; est evalu ee mais le r esultat nest pas ach e !--error 17 rand: stack size exceeded (Use stacksize function to increase it)

-->stacksize(6000000); -->A=rand(1000,1000);

modication de la taille m emoire disponible On peut maintenant g en erer A

L evaluation des expressions Scilab se fait au moyen dun interpr` ete appel e scilab. Cest linterpr` ete qui g` ere le contexte dex ecution des expressions Scilab. Dans le contexte dex ecution de Scilab, un utilisateur dispose par d efaut dun grand nombre de fonctions. Ces fonctions peuvent etre des fonctions ecrites en Scilab ; nous verrons en eet que Scilab est un langage de programmation. Mais elle peuvent aussi avoir et e ecrites en C, Fortran, . . . et rendues accessibles au niveau de linterpr` ete Scilab. Ce sont ces nombreuses fonctions facilement utilisables qui font la richesse et la puissance du langage. Notons aussi quun utilisateur peut enrichir lenvironnement de base et cela de fa con dynamique avec de nouvelles fonctions Scilab qui peuvent utiliser du code de librairies externes C, Fortran, . . . . On peut donc d evelopper des bo tes ` a outils pour enrichir lenvironnement dex ecution de Scilab et ladapter ` a des besoins sp eciques.

1.3

Les objets

Comme il a d ej` a et e dit, Scilab a et e con cu au d epart pour le calcul scientique et lobjet de base est la matrice de nombres ottants en double pr ecision, un scalaire etant un cas particulier de matrice de taille 1x1. Par d efaut les nombres utilis es par Scilab sont donc des matrices de double.
-->a=1:0.6:3 a = ! 1. 1.6 2.2 2.8 ! b est le vecteur 1x2 contenant deux valeurs pr ed enies (e, ) a est maintenant une matrice scalaire (de double)

-->b=[%e,%pi]

1.3. Les objets


b ! = 2.7182818 3.1415927 !

11

-->b(a) ans = ! 2.7182818 2.7182818 3.1415927

a peut en fait etre utilis e comme indice entier

3.1415927 !

Au cours du temps Scilab sest enrichi de nouveaux types en privil egiant laspect matriciel : matrices de cha nes de caract` eres, matrices de bool eens, matrices creuses (de scalaires ou de bool eens), matrices dentiers (int8, int16, int32), matrice de fractions rationnelles et du type list (plus quelques variantes) permettant de construire en fait des structures :
-->a=["A","B";"C","D"] a = !A ! !C B D ! ! ! Une matrice de scalaires Une matrice de cha nes de caract` eres

-->b=rand(2,2) b = ! ! 0.2113249 0.7560439 0.0002211 ! 0.3303271 !

-->b= b>= 0.5 b = ! F F ! ! T F ! -->l=list(a,b) l = l(1) !A ! !C B D ! ! ! l(2) ! F F ! ! T F ! -->a= spec(rand(3,3)) a = ! 1.8925237 !

Une matrice de bool eens

Une liste dobjets

Un vecteur de nombres complexes

12
! ! 0.1887123 + 0.0535764i ! 0.1887123 - 0.0535764i !

Chapitre 1. Une introduction a ` Scilab

Il est possible de d enir de nouveaux types dobjets en Scilab, au sens o` u il est possible de d enir des objets dont le type dynamique (valeur retourn ee par typeof) est d eni par lutilisateur. Les op erateurs de Scilab (par exemple lop erateur +) peuvent etre surcharg es pour tenir compte de ces nouveaux type dynamiques.
-->function [y]=eleve(nom,promo) Une fonction Scilab --> [y]=tlist([Eleve,nom,promo],nom,promo) tlist est utilis e pour construire une structure en sp eciant son type dynamique et les noms de ses champs. -->endfunction -->el=eleve(Lapeyre,64); Un objet de type Eleve -->typeof(el) ans = Eleve -->function %Eleve_p(el) Surcharge de la fonction dimpression (indiqu e par le suxe _p) --> mprintf(Nom: %s, promo: %d\n,el.nom,el.promo); -->endfunction -->el test de la fonction dimpression el = Nom: Lapeyre, promo: 64 -->el.nom ans = Lapeyre acc` es ` a un champ

1.4

Objets vectoriels et matriciels

Comme nous lavons d ej` a soulign e, une des caract eristique de Scilab est de privil egier les op erations matricielles quel que soit le type des el ements des matrices. Nous passons en revue dans cette section les op erateurs g en eraux de construction dobjets matriciels communs ` a tous les types de matrices. Le type matrice dans Scilab d esigne en fait des tableaux ` a au plus deux indices qui sont de fa cons interne cod es comme des tableaux unidimensionnels. On peut donc toujours acc eder aux el ements dune matrice avec un ou deux indices, le stockage des el ements etant fait colonne par colonne. Les vecteurs et scalaires sont en Scilab trait es comme des cas particuliers de matrices. Pour construire des tableaux multidimensionnels en Scilab on dispose du type hypermat. Ce type est impl ement e en Scilab (du moins jusque dans la version 2.7) et les op erateurs associ es sont en fait beaucoup moins performants que les op erateurs sur les matrices usuelles. Les op erateurs el ementaires de construction qui sont surcharg es pour tous les types de matrices sont lop erateur de concat enation en ligne ; et lop erateur de concat enation en

1.4. Objets vectoriels et matriciels

13

colonne ,. Ces deux op erateurs ne sont consid er es comme des op erateurs de concat enation que, dans un contexte matriciel, (i.e entre les symboles [ et ]). Tout leurs arguments doivent avoir le m eme type. On notera que dans un contexte matriciel le symbole blanc est synonyme de , et le retour ` a la ligne synonyme de ; et que cela peut etre source de confusion :

-->A=[1,2,3 +5] A = ! 1. 2. 3. 5. !

Attention ici A=[1,2,3,+5] avec un + unaire

-->A=[1,2,3 *5] A = ! 1. 2. 15. !

Attention ici A=[1,2,3*5] avec un * binaire

-->A=[A,0; 1,2,3,4] A = ! ! 1. 1. 2. 2. 15. 3. 0. ! 4. !

Le tableau 1.1 d ecrit des fonctions de construction de matrices utilis ees fr equemment.
diag eye grand linspace ou : logspace matrix ones rand zeros .*.

matrice (m,n) ` a diagonale x ee (ou extraction de diagonales) matrice (m,n) avec des uns sur la diagonale principale matrice (m,n) scalaire al eatoire vecteur ` a valeurs r eguli` erement espac ees vecteur ` a valeurs logarithmiquement espac ees changement de dimensions (m,n) ` a produit m*n x e matrice (m,n) de uns matrice (m,n) scalaires al eatoires (lois uniforme ou Gaussienne) matrice (m,n) de z eros op erateur de Kronecker

Tab. 1.1 Quelques fonctions de construction de matrices Et nous en donnons une illustration rapide :
-->A= [eye(2,2), 3*ones(2,3); linspace(3,9,5); zeros(1,5)] A = ! ! ! ! 1. 0. 3. 0. 0. 1. 4.5 0. 3. 3. 6. 0. 3. 3. 7.5 0. 3. 3. 9. 0. ! ! ! !

14
-->d=diag(A) d = ! ! ! ! 1. 1. 6. 0. ! ! ! !

Chapitre 1. Une introduction a ` Scilab


extraction de la diagonale principale

-->B=diag(d) B = ! ! ! ! 1. 0. 0. 0. 0. 1. 0. 0. 0. 0. 6. 0. 0. 0. 0. 0. ! ! ! !

construction dune matrice diagonale

-->C=matrix(d,2,2) C = ! ! 1. 1. 6. ! 0. !

changement des dimensions

-->D=[1,2,3].*.ones(2,2) D = ! ! 1. 1. 1. 1. 2. 2. 2. 2. 3. 3. 3. ! 3. !

produit de Kronecker

La plupart des fonctions Scilab acceptent des arguments de type matriciel et il faut se reporter ` a la documentation de chaque op erateur pour en comprendre la s emantique :

-->A=rand(2,2) A = ! ! 0.2113249 0.7560439 0.0002211 ! 0.3303271 !

matrice al eatoire avec loi uniforme par d efaut

-->B=exp(A) B = ! ! 1.2353136 2.1298336 1.0002212 ! 1.3914232 !

exponentiation termes ` a termes B(i,j)=exp(A(i,j))

-->B=expm(A) B = ! ! 1.2354211 0.9918216 0.0002901 ! 1.391535 !

exponentiation matricielle

1.4. Objets vectoriels et matriciels

15

1.4.1

Extraction, insertion et d el etion

Pour d esigner des el ements dune matrice, on utilise la notation A(B) ou A(B,C) ; o` u B et C sont des matrices dindices ou des matrices de bool eens. Quand une expression A(B) ou A(B,C) est un membre gauche dune aectation, alors il sagit dune op eration daectation si le membre de droite de laectation s evalue ` a une matrice non vide. On donne alors une valeur ` a la sous matrice d esign ee par le membre gauche en utilisant la valeur du membre droit. Il faut bien s ur que les deux sous matrices aient des tailles compatibles (i.e il faut quelles aient la m eme taille ou bien que le membre droit soit scalaire). Il peut aussi sagir dune op eration de d el etion si le membre droit s evalue ` a une matrice vide. On elimine alors les el ements d esign es par le membre gauche. Les op erations daectation et de d el etion changent bien s ur dynamiquement les dimensions de la matrice concern ee.
-->clear A; -->A(2,4) = 1 A = ! ! 0. 0. 0. 0. 0. 0. 0. ! 1. ! aectation qui change une sous matrice de A

-->A([1,2],[1,2])=int(5*rand(2,2)) A = ! ! 1. 3. 0. 1. 0. 0. 0. ! 1. !

-->A([1,2],[1,3])=[] A = ! ! 0. 1. 0. ! 1. !

d el etion dune sous matrice

-->A(:,1)= 8 A = ! ! 8. 8. 0. ! 1. !

aectation : d esigne lensemble des indices possibles, ici toutes les lignes de A

-->A(:,$)=[] A = ! ! 8. ! 8. !

d el etion $ d esigne le dernier indice

-->A(:,$+1)=[4;5] A = ! ! 8. 8. 4. ! 5. !

rajout dune colonne par aectation

16

Chapitre 1. Une introduction a ` Scilab

Quand une expression A(B) ou A(B,C) appara t dans une expression Scilab (hors membre gauche dune aectation), elle d esigne alors une sous matrice de la matrice A et son evaluation conduit ` a la cr eation dune nouvelle matrice.

-->A = int(10*rand(3,7)) A = ! ! ! 2. 7. 0. 3. 6. 6. 8. 6. 8. 0. 5. 6. 7. 1. 5. 2. 2. 2. 8. ! 6. ! 3. !

int calcule la partie enti` ere

-->B=A([1,3],$-1:$) trice (lignes un et trois; avant derni` ere et derni` ere colonnes) B = ! ! 2. 2. 8. ! 3. !

extraction dune sous ma-

Une expression A(B) ou A(B,C) d esigne une sous matrice de la matrice A. Quand B et C sont des matrices scalaires elles d esignent les indices ` a utiliser pour d esigner la sous matrice. Quand B et C sont des matrices de bool eens, alors les indices ` a consid erer sont les indices pour lesquels B et C prennent la valeur T. On peut utiliser la fonction find pour obtenir explicitement les indices correspondants.

-->A = int(10*rand(2,4)) A = ! ! 2. 7. 0. 3. 6. 6. 8. ! 6. !

int calcule la partie enti` ere

-->A( A>= 5) = [] d el etion : les indices sont donn es par une matrice de bool eens A>=5. Noter que A devient une matrice colonne. A = ! ! ! 2. ! 0. ! 3. ! indices des el ements de A qui sont >=2

-->I=find(A>=2) I = ! 1. 3. !

1.4.2

Scalaires et matrices de scalaires

Les matrices de scalaires d esignent dans Scilab les matrices dont les el ements sont des nombres ottants en double pr ecision (double) ou bien des nombres complexes en double

1.4. Objets vectoriels et matriciels

17

pr ecision (deux double). Leur type est d esign e par constant (valeur retourn ee par typeof). La norme adopt ee sur les calculs en double pr ecision peut etre contr ol ee par la fonction ieee :
-->ieee() ans = 0. -->1/0 !--error 27 division by zero... -->ieee(2) -->1/0 ans = Inf Dans le mode par d efaut 1/0 provoque une erreur Scilab le mode de calcul par d efaut

le mode par d efaut est maintenant le mode ieee 1/0 est maintenant evalu ea +

Les calculs se font avec une certaine pr ecision qui d epend de la machine sur laquelle Scilab est utilis e. La variable Scilab pr ed enie %eps, donne cette pr ecision machine. Cest le plus grand nombre en double pr ecision tel que 1+(%eps)/2 ==1.
-->x = [1.32,2,2.34e-3,%inf,%pi,%s,%nan,1+%eps] x = ! 1.32 2 0.00234 Inf 3.1415927 s Nan quelques scalaires Scilab

Cest bien s ur pour le type constant que lon trouve un tr` es grand nombre dop erateurs et de fonctions matricielles pr ed enis. Nous donnons ici les principaux op erateurs Scilab et les r` egles de pr ec edence qui les r egissent. Il sont tous d enis par d efaut pour les matrices de scalaires (m eme les op erateurs logiques) et sont surcharg es ou surchargeables pour les autres types de donn ees. Les op erateurs sont class es en ligne par ordre de pr ec edence croissante. Au sein dun m eme ligne, les op erateurs ont m eme pr ec edence avec associativit e` a gauche sauf pour les op erateurs puissance ou lassociativit e est a droite. Les op erateurs commen cant par le symbole . d esignent en g en eral des op erateurs agissant termes ` a termes. Par exemple C=A.*B calcule la multiplication termes ` a termes des deux matrices A et B ` a savoir C(i,j)=A(i,j)*B(i,j).
-->A=(1:9) * ones(1,9) A = ! ! ! ! 1. 2. 3. 4. 1. 2. 3. 4. 1. 2. 3. 4. 1. 2. 3. 4. 1. 2. 3. 4. 1. 2. 3. 4. 1. 2. 3. 4. transposition et produit matriciel usuel *

1. 2. 3. 4.

1. 2. 3. 4.

! ! ! !

18
| & ~ ==, >=, <=, >, < ,<>, ~= +,+,.*, ./, .\, .*., ./., .\., *, /, /., \. ^,** , .^ , .** , .

Chapitre 1. Une introduction a ` Scilab ou logique et logique non logique op erateurs de comparaison addition et soustraction binaire addition et soustraction unaires multiplications et divisions puissances transpositions

Tab. 1.2 Pr ec edences des op erateurs

! ! ! ! !

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

5. 6. 7. 8. 9.

! ! ! ! !

-->A.* A ans = ! ! ! ! ! ! ! ! ! 1. 2. 3. 4. 5. 6. 7. 8. 9. 2. 4. 6. 8. 10. 12. 14. 16. 18. 3. 6. 9. 12. 15. 18. 21. 24. 27. 4. 8. 12. 16. 20. 24. 28. 32. 36.

r evisons nos tables de multiplications : produit termes ` a termes

5. 10. 15. 20. 25. 30. 35. 40. 45.

6. 12. 18. 24. 30. 36. 42. 48. 54.

7. 14. 21. 28. 35. 42. 49. 56. 63.

8. 16. 24. 32. 40. 48. 56. 64. 72.

9. 18. 27. 36. 45. 54. 63. 72. 81.

! ! ! ! ! ! ! ! !

-->t=(1:4);m=size(t,r);n=4; -->A=(t*ones(1,n+1)).^( ones(m,1)*[0:n]) sances termes ` a termes pour construire une matrice de Vandermonde A = ! ! ! ! 1. 1. 1. 1. 1. 2. 3. 4. 1. 4. 9. 16. 1. 8. 27. 64. 1. 16. 81. 256. ! ! ! !

j 1 A(i, j ) = t i

puis-

-->A=eye(2,2).*.[1,2;3,4] A = ! ! ! ! 1. 3. 0. 0. 2. 4. 0. 0. 0. 0. 1. 3. 0. 0. 2. 4. ! ! ! !

produit de Kronecker

-->A=[1,2;3,4];b=[5;6]; x = A \ b ; norm(A*x -b) ans =

\ r esolution du syst` eme lin eaires Ax=b

1.4. Objets vectoriels et matriciels

19

0. -->A1=[A,zeros(A)]; x = A1 \ b d etermin e : on obtient une solution particuli` ere x = ! - 4. ! ! 4.5 ! ! 0. ! ! 0. ! -->A1=[A;A]; x = A1\ [b;7;8] x = ! - 5. ! ! 5.5 ! Syst` eme sur-d etermin e : solution au sens des moindres carr es Syst` eme sous-

1.4.3

Cha nes de caract` eres

Les cha nes de caract` eres Scilab sont d elimit ees par les caract` eres apostrophe ou guillemets anglo-saxons " (qui sont equivalents). Pour ins erer une apostrophe ou des guillemets, il faut les faire pr ec eder dun d elimiteur (` a nouveau ou " ). Les op erations de base sur les cha nes de caract` eres sont la concat enation, not ee par lop erateur + et la fonction length qui renvoie le nombre de caract` eres contenus dans une cha ne. On peut bien sur cr eer des matrices de cha nes de caract` eres et les deux op erateurs pr ec edemment d ecrits deviennent alors vectoriels et les op erateurs usuels de construction de matrices par concat enation de colonnes ou de lignes sont utilisables :
-->S="une cha^ ne avec <<">> " S = une cha^ ne avec <<>> -->S=une cha^ ne beaucoup plus longue... --> avec un mot en ""guillemets"" " S = ... pour continuer sur la ligne suivante

une cha^ ne beaucoup plus longue avec un mot en "guillemets" -->S=[Une,de;matrice,cha^ nes] S = !Une ! !matrice de cha^ nes ! ! ! longueur de chaque cha ne de la matrice S une matrice de cha nes

-->length(S) ans =

20
! ! 3. 7. 2. ! 7. !

Chapitre 1. Une introduction a ` Scilab

ascii execstr grep part msscanf msprintf strindex string stripblanks strsubst tokens strcat length

conversion entre cha ne et codes Ascii fait ex ecuter par linterpr` ete une cha ne de caract` ere recherche de sous-cha nes dans une matrice de cha nes extraction de sous-cha nes lecture format ee (C) dans un cha ne construction dun vecteur ou dune cha ne par ecriture format ee position doccurrences de sous cha nes dans une cha ne conversion vers une cha ne de caract` ere enl` eve les caract` eres blancs initiaux et naux substitution de sous-cha nes d ecoupe une cha ne concat` ene les el ements dune matrice longueur des cha nes dune matrice de cha ne Tab. 1.3 Quelques fonctions sur les cha nes de caract` eres

Dans le tableau 1.3, sont r epertories plusieurs fonctions utiles li ees ` a lutilisation des cha nes de caract` eres. Nous les illustrons maintenant au moyen dun exemple. On cherche ici ` a transformer une matrice scalaire en une cha ne de caract` ere permettant dobtenir une A A repr esentation en L TEX de cette matrice. Conna tre le langage L TEX na ici aucune importance, il sagit, partant de la matrice A=testmatrix(magi,3), de construire la cha ne de caract` ere :
\[ A= \begin{array}{ccc} 8 & 1 & 6 \\ 3 & 5 & 7 \\ 4 & 9 & 2 \\ \end{array} \]

-->A=testmatrix(magi,3) A = ! ! ! 8. 3. 4. 1. 5. 9. 6. ! 7. ! 2. !

un carr e magique 3x3

-->[ma,na]=size(A); -->B=string(A) B = !8 ! !3 ! !4 1 5 9 6 7 2 ! ! ! ! !

taille de la matrice de cha nes transformation dune matrice scalaire en matrice de cha nes

-->delim=\\; -->B=[B,delim(ones(ma,1))];

rajout dune colonne

1.4. Objets vectoriels et matriciels

21

--> noter que delim(ones(ma,1)) construit un vecteur (ma,1) ou la cha ne delim est r ep et ee sur chaque ligne. -->B=strcat(B, & ) transposition et concatenation avec utilisation dun s eparateur B = 8 & 1 & 6 & \\ & 3 & 5 & 7 & \\ & 4 & 9 & 2 & \\ -->B=strsubst(B,& \\ &,\\) B = 8 & 1 & 6 \\ 3 & 5 & 7 \\ 4 & 9 & 2 & \\ -->B=strsubst(B,& \\,) B = 8 & 1 & 6 \\ 3 & 5 & 7 \\ 4 & 9 & 2 -->delim="c";delim=strcat(delim(ones(na,1))) delim = ccc -->text=[\[ A= \begin{array}{+delim+}; --> B; --> \end{array} \] ]; -->mputl(text,matrix.tex) construction dun motif r ep et e na fois B est maintenant une cha ne de carat` eres substitutions

concatenation matricielle ecriture dans le chier matrix.tex

-->B=string(A); une variante pour construire B -->fmt=%d; fmt = strcat(fmt(ones(1,na)), &) + \n; construction dun format -->B= msprintf(fmt,A) construction dun vecteur de cha ne par ecriture format ee B = 8 &1 &6\n3 &5 &7\n4 &9 &2\n -->B=string(A); -->B=strcat(B, & ,c); une autre variante pour construire B concat enation des colonnes de B avec s eparateur

-->text= [\[ A= \begin{array}{+delim+}; --> B + \\ ; B est un vecteur colonne, on concat` ene chaque ligne avec \\ --> \end{array} \] ] concat enation matricielle en ligne + text = !\[ A= \begin{array}{ccc} ! !8 & 1 & 6 \\ ! !3 & 5 & 7 \\ ! !4 & 9 & 2 \\ ! !\end{array} \] ! ! ! ! ! ! ! ! !

22

Chapitre 1. Une introduction a ` Scilab

Les cha nes de caract` eres peuvent aussi etre utilis ees pour construire des expressions du langage Scilab que lon peut alors faire evaluer par linterpr` ete au moyen de la commande
execstr

-->i=3; -->text = [function [y]=plus+string(i)+(x); -->y = x + + string(i); -->endfunction] text = !function [y]=plus3(x) ! !y = x +3 ! !endfunction -->execstr(text); -->plus3(4) ans = 7. ! ! ! ! !

construction dun vecteur de cha ne

evaluation par Scilab de la cha ne construite on dispose maintenant de la fonction plus3

1.4.4

Bool eens et matrices de Bool eens

Un Bool een peut prendre deux valeurs vrai T et faux F. On dispose des deux variables bool eennes %t et %f qui s evaluent respectivement ` a T et F et qui peuvent etre utilis ee pour construire des matrices de bool een. L evaluation des op erateurs de comparaisons ( == , > , >= , <= et ~=) produit des r esultats de type matrices de bool eens. On dispose des op erateurs matriciels termes ` a termes & (et) , | (ou) et ~ (not) et des fonctions logiques and, or et not qui prennent en argument une matrice de Bool eens. Les matrices Bool eennes sont utilis ees dans Scilab avec les expressions conditionnelles et elles servent aussi bien souvent ` a s electionner des el ements dans une matrice. Nous avons d ej` a illustr e cette utilisation dans une sections pr ec edente.

-->x=-10:0.1:10; -->y=( (x>=0).* exp(-x) )+ ((x <0).* exp(x)); tique de bool een vers scalaires. -->y=bool2s([%t,%f]) y = ! 1. 0. !

conversion automa conversion explicite.

1.4. Objets vectoriels et matriciels

23

Nous donnons ici un exemple dutilisation de matrices bool eennes. On cherche ` a tester la 1 v eracit e dune expression logique :

-->expr= (x1 & x2 | x3) == ( (x1 & x2 ) | x3); gique est vraie

on cherche ` a v erier si lexpression lo-

-->n=size(strindex(expr,x),*) combien de fois la cha ne x appara t dans expr. Noter que * indique que lon veut le produit des dimensions dune matrice. n = 6. -->nv=0; -->for i=1:n --> if grep(expr,x+string(i))<>[] then --> nv=nv+1; --> end -->end -->nv nv = 3. -->for i=1:nv --> expr=strsubst(expr,x+string(i),x(:,+string(i)+)); -->end; -->expr expr = dans expr on a substitu e xi par la cha ne x(:,i) pour i=1:nv

est-ce que x1,x2,... apparaissent dans expr ?

nombre de variables xi dans expr

(x(:,1) & x(:,2) | x(:,3)) == ( (x(:,1) & x(:,2) ) | x(:,3)) -->n=nv ; -->T=[1;0] T = ! ! 1. ! 0. ! n contient le nombre des xi pr esents dans expr

-->x=ones(2^n,n); --> tiens et si on utilisait le myst erieux .*. ! -->for i=1:n --> x(:,i) = ones(2^(i-1),1).*.(T.*.ones(2^(n-i),1)); -->end -->x = (x > 0) table donnant toutes les valeurs bool eennes possibles pour n variables x = ! T T T !
tester si une expression logique contenant des variables bool eennes vue comme une fonction Bool eenne de ces variables est la fonction constante qui vaut toujours vrai
1

24
! ! ! ! ! ! ! T T T F F F F T F F T T F F F T F T F T F ! ! ! ! ! ! !

Chapitre 1. Une introduction a ` Scilab

-->execstr(rep=(+expr+)); toutes les valeurs bool eennes possibles pour expr (on construit une expression et on la fait evaluer par linterpr` ete Scilab) -->and(rep) ans = T expr est-elle vraie ?

1.4.5

Matrices creuses

Les repr esentations dites creuses des matrices consistent ` a ne coder que leurs el ements non nuls. En Scilab, le stockage dune matrice creuses de taille (m,n) est eectu e de la fa con suivante. Un tableau de taille m contient des pointeurs vers des descripteurs de lignes. Chaque descripteur de ligne est cod e au moyen de deux tableaux, le premier contient les indices des colonnes qui contiennent des el ements non nuls et le deuxi` eme tableau contient les valeurs associ ees. Certains probl` emes qui, d ecrits sous forme pleine, ne pourraient etre stock es en m emoire par Scilab se trouvent accessibles sous forme creuse. Ceci se fait bien evidemment avec une perte decacit e en terme de temps de calcul. La fonction de base pour construire des matrices creuses est la fonction sparse. Seules les matrices de scalaire et les matrices de bool eens disposent de la possibilit e dune repr esentation creuse dans Scilab.
-->A=sprand(100,100,0.1); une matrice creuse (100,100) contenant 10% de valeurs non nulles -->whos(-type,sparse) occupation m emoire Name Type Size Bytes A -->B=full(A); -->whos(-name,B); Name B -->timer();inv(B);timer() ans = 0.01 -->timer();inv(A);timer() ans = 0.26 temps de calcul de linverse sparse 100 by 100 13360

occupation m emoire pour la m eme matrice en repr esentation pleine Type Size Bytes constant 100 by 100 80016 temps de calcul de linverse

1.4. Objets vectoriels et matriciels

25

1.4.6

Les listes

Les listes Scilab sont construites par les op erateurs list, tlist et mlist. Ces trois op erateurs construisent en fait des structures au sens o` u ils permettent dagr eger sous un seul nom de variable un ensemble de donn ees de type di erents. On notera que ce sont des types r ecursifs. Si on utilise le constructeur list, lacc` es aux donn ees se fait par un indice. Tout se passe comme si on avait un tableau de donn ees. Si on utilise le constructeur tlist, lobjet construit a un nouveau type dynamique et lacc` es au donn ees peut se faire par linterm ediaire de noms. Notons aussi que les champs sont dynamiques et quon peut rajouter dynamiquement de nouveaux champs. Une tlist etant aussi une liste, lacc` es aux el ements de la liste par un indice reste possible. Le constructeur mlist est tr` es voisin du constructeur tlist. La seule di erence est que lacc` es aux el ements de la liste par un indice nest plus eective (cette op eration restant toutefois possible en utilisant les fonctions getfield et setfield). En revanche on peut surcharger les op erateurs dextraction et dinsertion pour donner un sens aux acc` es faits avec un ou plusieurs indices. Les tableaux ` a plusieurs indices (hypermat) sont impl ement es dans Scilab au moyen dune mlist. Voici maintenant, illustr ees sur un exemple, les op erations usuelles sur les listes :
-->L=list() L = () -->L(2) = testmatrix(magi,3); -->L(0) = 34; -->L($) = X L = L(1) 34. L(2) Undefined L(3) X -->L($+1) = Y L = L(1) 34. rajoute un el ement ` a la n aectation L(i)=val. Noter que L(1) nexiste pas. rajout dun el ement au d ebut de la liste remplace le dernier el ement Une liste vide

26

Chapitre 1. Une introduction a ` Scilab

L(2) Undefined L(3) X L(4) Y -->[a,b]=L([1,3]) b = X a extraction, on peut extraire plusieurs el ements ` a la fois

= 34.

-->L(2)=null(); d el etion du deuxi` eme el ement de la list -->function w=f(x,y,z); w=arg1:+string(x)+ arg2:+ string(y)+ arg3:+ string(z);endfunction -->f(L(:)) transformation de la liste en une s equence darguments ans = arg1:34 arg2:X arg3:Y -->f(45,L(2:3)) ans = arg1:45 arg2:X arg3:Y

1.5

Programmer avec Scilab

Scilab est aussi un langage de programmation qui permet d ecrire des scripts (suite dinstructions Scilab dans un chier) et des fonctions (parfois aussi appel ees macros). Un chier contenant une suite dinstructions Scilab et des d enitions de fonction est ex ecut e par Scilab au moyen de la fonction exec. On notera que cette fonction admet un argument optionnel qui permet de contr oler le niveau dachage ` a l ecran lors de lex ecution du script. Lusage est de nommer les scripts scilab par des noms de chier termin es par le suxe .sce. Il est aussi possible au lancement de Scilab dindiquer un script ` a ex ecuter au moyen de loption scilab -f <nom-de-script>. Si le script se termine par linstruction quit, ceci permet de lancer des ex ecutions de Scilab en mode batch. Si un chier ne contient que des fonctions Scilab, alors lusage est de le nommer par un nom de chier au suxe .sci. Ce chier peut alors etre ex ecut e dans Scilab (ce qui a pour eet de charger les fonctions dans lenvironnement courant) par linstruction exec ou par linstruction getf.

1.5. Programmer avec Scilab

27

On notera aussi que, lors du lancement de Scilab, si un chier de nom .scilab est pr esent dans le r epertoire de base de lutilisateur (variable denvironnement HOME) alors ce chier de script est ex ecut e. Nous passons maintenant en revue la syntaxe des it erateurs, des branchements et des fonctions en Scilab

1.5.1

Branchement et aiguillages

Ces instructions permettent de conditionner lex ecution dinstructions ` a la valeur dune condition. La forme la plus simple est la suivante :
if <condition> then <instructions> end

Les instructions contenues dans le bloc <instructions> ne seront ex ecut ees que si l evaluation de la condition <condition> est T. L evaluation de la condition <condition> peut- etre une matrice de bool eens ou une matrice de scalaire, la condition nest alors vraie que si tous les el ements de la matrice de bool eens sont vrais ou tous les el ements de la matrice scalaire sont non nuls. A=log(rand(3,3)) if imag(A)==0 then disp(A est une matrice r eelle) ; end Dans la forme ` a deux branches,
if <condition> then <instructions> else <instructions> end

la premi` ere branche est ex ecut ee quand la valeur de la condition est vraie et la deuxi` eme quand la valeur de la condition est fausse.
A = - 1.1076719 - 0.4073953 - 0.4645914 - 0.1628187 ! - 0.3772698 ! - 0.1298622 !

! - 1.5543587 ! - 0.2796559 ! - 8.4167389

-->if imag(A)==0 then --> disp(A est une matrice r e elle); A est une matrice r e elle -->else --> disp(A est une matrice complexe); -->end

Enn on peut utiliser une forme multibranches ou les else succ essifs sont alors introduits par elseif. On peut parfois remplacer des instructions conditionnelles successives par une instruction daiguillage (select), par exemple quand on veut ex ecuter des instructions en fonction de la valeur dun nombre ou dune cha ne de caract` eres. ),
select case case ... else end <expr> , <expr1> then <instructions> <expr2> then <instructions> <instructions>

28

Chapitre 1. Une introduction a ` Scilab

La valeur de <expr> est successivement compar ee ` a la valeur de chacune des expressions <expr1>, <expr2>, . . . . D` es quil y a egalit e le bloc dinstructions suivant le case est ex ecute. Si aucun cas d egalit e nest d etect e alors cest le bloc else qui sera (sil est pr esent) ex ecut e.

1.5.2

It erations

Il y a deux structures de contr ole it eratives dans Scilab, la boucle for et la structure while. Avant de recourir aux it erateurs, il faudra essayer pour des raisons decacit e en terme de temps de calcul de voir si les it erateurs ne peuvent pas etre remplac es par des instructions vectorielles ou matricielles. La syntaxe de la boucle for est la suivante :
for <nom>=<expr> <instructions> end

Le bloc dinstructions va etre ex ecut e de fa con it erative et ` a chaque it eration la variable


nom prendra une nouvelle valeur. Si le r esultat de l evaluation de linstruction <expr> est une matrice alors le nombre dit erations sera x e au nombre de colonnes de cette matrice et <nom>

prendra comme valeur les colonnes successives de cette matrice. Si le r esultat de l evaluation de linstruction <expr> est une liste alors cest la longueur de la liste qui donne le nombre dit erations et <nom> prendra comme valeur les valeurs des el ements successifs de la liste. Le bloc <instructions> peut contenir lexpression break. Si au cours des it erations linstruction break est evalu ee alors lex ecution de la structure dit eration se termine et lex ecution des instructions reprends ` a la n du bloc it eratif. La variable <nom> garde la valeur quelle avait lors de lex ecution du break. En labsence dinstruction break la variable <nom> na plus de valeur ` a la n de lex ecution du bloc it eratif.
-->n=89; -->for i=2:(n-1) --> if pmodulo(n,i)==0 then break;end -->end -->if exists(i) then --> mprintf(%d divise %d \n,i,n) -->else --> mprintf(%d est premier\n,n) 89 est premier -->end -->n=16778; -->timer(); -->res=[] res = [] -->for i=2:(n-1) --> if pmodulo(n,i)==0 then

it eration sur les entiers de 2 ` a n-1

est-ce quun break a eu lieu ? si oui i est un diviseur de n si non n est premier

on veut tous les diviseurs de n

1.5. Programmer avec Scilab


--> res=[res,i]; --> end -->end -->timer() ans = 0.85 -->res res = ! 2. 8389. !

29
` a chaque it eration la taille du vecteur res cro t

temps CPU ecoul e depuis lappel pr ec edent ` a timer

les diviseurs de n

-->v=2:(n-1); -->timer(); -->I=find(pmodulo(n,v)==0) I = ! 1. 8388. !

calculs vectoriels pour aller plus vite m eme calcul mais vectoriel

-->res = v(I) res = ! 2. 8389. ! comparer au r esultat obtenu plus haut !

-->timer() ans = 0.

La syntaxe de lit erateur while est la suivante


while <condition> <instructions> end

Les instructions contenues dans le bloc <instructions> sont ex ecut ees tant que la condition <condition> est vraie. L evaluation de la condition <condition> peut etre une matrice de bool eens ou une matrice de scalaire ; la condition nest alors vraie que si tous les el ements de la matrice de bool eens sont vrais ou tous les el ements de la matrice scalaire sont non nuls.
-->while %t it eration innie, il faut un verb pour quitter le while --> val=evstr(x_dialog(Entrez un nombre positif,1.0)); une fen etre de dialogue --> if val==[] then break;end --> if size(val,*) & val >= 0.0 then r eponse correcte: on quitte le while --> break; --> else --> x_message(Votre nombre nest pas positif -->+string(val)) message en cas de r eponse incorrecte --> end -->end

30

Chapitre 1. Une introduction a ` Scilab

1.5.3

Fonctions Scilab

D enir de nouvelles fonctions dans Scilab se fait au moyen de la construction syntaxique suivante :
function [<nom1>,<nom2>,...]=<nom-de-fonction>(<arg1>,<arg2>,...) <instructions> endfunction

Dans la d enition de la fonction on pr ecise bien s ur le nom de la fonction, la liste de ses arguments dentr ee et la liste des arguments de sortie. On notera quune fonction peut renvoyer plusieurs valeurs. Lappel dune fonction se fait de la fa con suivante :
<nom-de-fonction>(<expr1>,<expr2>,...)

ou encore :
[<v1>,<v2>,...<vp>]=<nom-de-fonction>(<expr1>,<expr2>,...)

Dans le premier cas la valeur retourn e par la fonction est la premi` ere valeur de retour et dans le deuxi` eme cas ce sont les p premi` eres valeurs de retour qui sont aect ees aux variables <v1>, <v2>,. . . ,<vp>. Lors de lappel de la fonction les expressions fournie en arguments sont dabord evalu ees et leur valeurs sont pass ees a lenvironnement dex ecution de la fonction sous les noms <arg1>, <arg2>,. . . . Les arguments des fonctions sont donc pass es par valeurs quel que soit leur type. Notons toutefois que, si un argument est un nom de variable, la variable ne sera pas copi ee si dans le corps de la fonction la variable correspondante nest jamais modi ee. Lex ecution dune fonction se termine normalement quand tout le bloc <instructions> a et e ex ecut e, mais elle peut aussi se terminer si lex ecution du corps de la fonction conduit ` a une instruction return. Le retour de la fonction ` a lieu alors imm ediatement apr` es linstruction return. Les variables de retour <nom1>,<nom2>,... ont alors la valeur courante quelles avaient dans lenvironnement dex ecution de la fonction.
-->function y=f(x); y=2*x;endfunction fonction simple sur une seule ligne. Noter le ; quil faut alors ajouter avant la premi` ere instruction -->x=90; -->f() x nest pas fourni mais il existe dans lenvironement courant, lappel ne provoque pas derreur. Mais cest maladroit ! ans = 180. -->f(5,7) !--error 58 incorrect number of arguments in function call... arguments are : x -->[a,b]=f(5) !--error 59 incorrect # of outputs in the function arguments are : erreur: trop darguments fournis

erreur: trop darguments demand es en retour

1.5. Programmer avec Scilab


y

31

-->function y=f(x); z=x; endfunction Warning :redefining function: f

nouvelle d enition de f

-->y=89; -->z=67; -->w=f(x) y nest pas calcul e dans le corps de la fonction f mais il a une valeur dans lenvironement dappel, cest cette valeur qui est renvoy ee w = 89. -->z z = 67. -->function y=f(); y=x; endfunction Warning :redefining function: f -->x=5; -->y=f() x nest pas d enie localement: cest la valeur de x dans lenvironement appellant qui est utilis ee y = 5. -->function y=f(); x= 2*x; y=x; Warning :redefining function: f -->y=f() y = 10. -->x=[56,67]; -->function y=f(); x(1)= 5; y=x Warning :redefining function: f -->y=f() y = 5. -->// parler de varargin et varargout -->// parler des arguments nomm es -->function w=f(x,y,z); z=[x,y,z];endfunction Warning :redefining function: f endfunction z na pas et e modi e par lex ecution de f

une valeur locale de x est cr ee

endfunction

une valeur locale de x est cr ee et donc x==5

32
-->f(6,z=78,y=8);

Chapitre 1. Une introduction a ` Scilab


on peut changer lordre dans lequel on donne les arguments

Comme on la vu une fonction admettant n variables en entr ee et retournant p valeurs en sortie peut etre appel ee avec moins darguments dentr ee et le nombre de valeurs de retour demand ees peut etre inf erieur ` a p. Il est possible de contr oler les valeurs utilis ees dans un appel de fonction au moyen de la fonction argn. . En eet une ligne dinstruction [lhs,rhs]=argn() permet dobtenir dans les variables lhs (resp. rhs) le nombre de valeurs de retour (resp. dentr ee) utilis ees. Cela permet de g erer des arguments optionnels comme illustr e sur lexemple suivant. On notera sur cet exemple que lon peut utiliser la fonction error pour produire une erreur Scilab.

-->function [u,v]=f(x,y) --> [lhs,rhs]=argn(0) --> if rhs <= 0 then error(at least on argument must be given);end --> if rhs <= 1 then y=2;end --> if lhs == 2 then --> u=x; v=y; --> else --> u=x+y; --> end -->endfunction -->[u,v]=f(4) v = 2. = 4. -->function [varargout]=f() --> varargout=list(1,2,3) -->endfunction Warning :redefining function: f

Normalement le nombre dargument dentr ees doit etre inf erieur ou egal au nombre dargument dentr ee de la fonction appel ee. Il y a une exception ` a cela. Si le dernier argument dune fonction comportant n arguments dentr ees ` a pour nom varargin alors la fonction peut etre appel ee avec plus de n arguments. Les arguments fournis ` a partir du n-i` eme sont stock es dans une liste Scilab de nom varargin.

-->function [l]=f(x,varargin); l = varargin; endfunction -->f(0,1,2) varagin devient la liste (1,2) ans =

1.5. Programmer avec Scilab

33

ans(1) 1. ans(2) 2.

Une fonction Scilab peut utiliser les variables courantes de lenvironnement dappel mais en lecture seulement. Il est possible de modier une variable de lenvironnement dappel que pour un ensemble particulier de variables dites globales. Les variables globales doivent etre d eclar ees dans lenvironnement initial au moyen de la fonction global, et pour etre utilis ee en ecriture elle doivent aussi etre d eclar ees dans les fonctions qui peuvent changer leurs valeurs
-->global a; -->isglobal(a) ans = T -->function f(); global(a); a=int(10*rand(1,4)); endfunction -->f() -->a Lappel de f a chang ea a = ! --> 2. 7. 0. 3. ! a est maintenant une variable globales, par d efaut elle prend la valeur [] On le v erie . . .

1.5.4

Contr oler lex ecution des fonctions

Il est toujours dicile de programmer sans fautes et programmer en Scilab n echappe pas ` a cette fatalit e. Plusieurs fonctions (ou fonctionalit es) permettent daider ` a la d etection des fautes et ` a leur correction. On peut interrompre lex ecution de code Scilab au moyen de la commande pause (du menu principal) ou de linterruption Ctrl-C. Le prompt est alors di erent pour signaler ` a lutilisateur que linterruption ` a eu lieu et ` a quel niveau dinterruption il se trouve. De m eme que lex ecution dune fonction Scilab se fait dans un environnement local ` a la fonction, une pause ` a pour eet dinterrompre une ex ecution en cours et de relancer lex ecution de linterpr` ete dans un nouvel environnement local. Il faut consid erer que les environnements dex ecution sempilent. Lenvironnement courant est au sommet de la pile. Dans lenvironnement au sommet de la pile on a acc` es (en lecture) aux variables des environnement pr ec edents. linterruption Ctrl-C arr ete lex ecution en cours ` a un endroit non d etermin e ` a lavance, sachant que lon peut alors contr oler ou lon se trouve par la commande whereami (ou where). Il est cependant parfois pr ef erable dins erer explicitement la commande pause dans une fonction pour etre sur de la position du point darr et rajout e.
-->a=34;

34

Chapitre 1. Une introduction a ` Scilab

-->function y=f(x) ; pause; a = %pi; pause; y=g(x); endfunction -->function y=g(x) ; b = %e ; y=sin(x);pause; endfunction -->f(5) a a = 34. b= 56; resume a a = 3.1415927 exists(b) ans = 0. resume exists(b,local) ans = 0. resume ans = - 0.9589243 -->a=g(4); arr et a la pause dans la fonction g [y]=resume([1:4]); sortie de lenvironement de la pause avec envoit dune variable dans lenvireonement de la fonction g -->a a = ! 1. 2. la valeur retourn ee par g est la valuer de y retourn ee par la commande resume on continue on quitte la pause et on sarr ete ` a la suivante dans g b dans lenvironement local de la fonction g le b de lenvironement local de la pause pr ec edente nexiste plus cr eation dune variable dans lenvironement local de la pause on quitte la pause et on sarr ete ` a la suivante toujours dans f la valeur de a dans lenvironement local de f

pause dans f on peut visualiser les variables de lenvironement au dessous

3.

4. !

Plut ot que de modier le code dune fonction en y ins erant des pause ce qui n ecessite le rechargement de la fonction dans lenvironnement courant de Scilab. On peut utiliser la fonction setbpt pour xer un point darr et ` a une ligne donn ee dune fonction. On continue lex ecution interrompue au moyen de la commande resume. On peut aussi interrompre une ex ecution au moyen des commandes abort (resp. quit). On revient alors au niveau 0 le

1.6. Fonctions dentr ees sorties

35

bas de la pile dex ecution (resp au niveau en dessous du sommet de la pile dex ecution, le sommet etant retir e de la pile). On peut aussi ex ecuter pas ` a pas le contenu dune fonction au moyen de la commande exec. Dans ce cas il ny a pas denvironnement local dex ecution et il faut donc d enir les argument de la fonction avant lappel de exec
-->getf(stepf.sci,n); charger f1 avec getf et loption n -->x=int(10*rand(1,4)); argument de f1 step-by-step mode: enter carriage return to proceed y=sin(x).*x y = ! 1.8185949 y = y+2, y = ! 3.8185949 return! 4.5989062 0. 0.4233600 !

6.5989062

2.

2.42336 !

Noter que par d efaut on ne voit pas le source Scilab des instructions si le chargement de la fonction avec getf na pas et e fait avec loption n.

1.6

Fonctions dentr ees sorties

Nous avons d ej` a vu lors des sessions pr ec edentes que si une instruction se termine par une virgule ou un retour ` a la ligne alors le r esultat de son evaluation est ach e dans la fen etre Scilab. Lachage naura par contre pas lieu si linstruction est termin ee par un point virgule ou si linstruction fait partie du corps dune fonction. Pour acher explicitement la valeur dune variable ou dune expression on peut utiliser les fonctions disp ou print. Le premier argument de la fonction print permet de contr oler o` u se fera lachage. On peut indiquer un nom ou un descripteur de chier (voir la commande file) ou bien utiliser %io(2) qui permet lachage dans la fen etre Scilab :
le r esultat de laectation est ach e

-->a=%pi a = 3.1415927 -->function y=f(x) ; a = %pi, y = x+a, endfunction -->f(2), ans = 5.1415927

lachage de a ne se fait plus

-->function y=g(x) ; a = %pi, print(%io(2),a), y = x+a, endfunction -->g(2); On force lachage de a a =

36

Chapitre 1. Une introduction a ` Scilab

3.1415927

Il est possible de contr oler le format utilis e pour lachage des nombres par les fonctions disp et print au moyen de la fonction format. On notera aussi quil est possible de sauver les variables de lenvironnement courant au moyen de la commande save. On recharge alors les variables dans lenvironnement courant avec la commande load. Les commandes save et load utilisent un format binaire machine ind ependant. Les sauvegardes se font donc sans pertes de pr ecisions et sont portables. Pour contr oler plus nement le formatage des entr ees sorties plusieurs fonctions sont disponibles dans Scilab. Les fonctions write et read sont bas ees sur des formatages Fortran. Les descripteurs de chiers accept es par ses deux fonctions sont obtenus au moyen de la commande file. Les sorties et entr ees dans la fen etre Scilab etant obtenus par les descripteurs %io(2) et %io(1). Nous ne nous etendrons pas plus sur ces fonctions et nous allons plut ot d ecrire ici les fonctions Scilab qui emulent les fonction dentr ees sorties que lon utilise en C. Ces fonctions permettent l ecriture et la lecture format ee ou binaire sur des chiers, sur les sorties et entr ees standard de la fen etre Scilab et sur des cha nes de caract` eres.
mprintf mfprintf msprintf mscanf mfscanf msscanf fprintfMat fscanfMat mgetl mgetl mputl mopen mclose

Ecriture sur la sortie standard Ecriture dans un chier Ecriture dans une matrice de cha nes de caract` eres Lecture sur lentr ee standard Lecture dans un chier Lecture dans une matrice de cha nes de caract` eres Ecriture format ee dune matrice dans un chier Lecture format ee dune matrice dans un chier lecture des lignes dun chier dans une matrice de cha nes lecture des lignes dun chier dans une matrice de cha nes Ecriture des lignes dune matrice de cha nes dans un chier ouverture dun chier fermeture dun chier Tab. 1.4 Quelques fonctions dentr ees sorties

La fonction mopen interface la fonction C,fopen et sa syntaxe est la suivante :


[fd,err]=mopen(filename , mode, swap ) filename est une cha ne d ecrivant un nom de chier. Largument mode est une cha ne dau plus trois caract` eres (dont la valeur par d efaut est rb) qui permet de pr eciser si le chier doit etre ouvert en lecture (r), en ecriture (w), en compl etion (a) ou en lecture/ ecriture (r+). Lajout du caract` ere b pr ecise que le chier est un chier binaire.

Les fonctions d ecriture et de lecture format ees sont proches des fonctions de noms voisins pr esentes dans la librairie C. La sp ecication des formats par exemple suit la sp ecication des formats des fonctions C. Laspect vectoriel qui est une caract eristique de Scilab est int egr e aux fonctions de lecture ecriture. Pour l ecriture, les formats sont utilis es sur les lignes des

1.6. Fonctions dentr ees sorties

37

arguments vectoriels donn es et pour la lecture on peut pr eciser le nombre de fois o` u il faut utiliser le format (voire lutiliser jusqu` a atteindre une n de chier). Lexemple suivant illustre cela :
-->mprintf(%d,1:4) rant les lignes de chaque arguments 1 -->mprintf(%d %d,1:2,3:4) 1 2 -->mprintf(%f %f,1) 1.000000 des arguments manquants provoquent une erreur le format sapplique aux arguments en explo-

les arguments en trop sont ignor es

!--error 998 Error: printf: not enough arguments

-->mprintf(%d ,int(10*rand(3,1))) 3 6 6 -->mprintf(%d\ n,int(10*rand(3,1))) 0

les formats sont r eutilis es sur chaque lignes

\ n ache un retour ` a la ligne

-->S=msprintf(%d\ n,int(20*rand(5,1)));S; trice S ans = !4 17 13 6 18 !

on construit une nouvelle ligne dans la ma-

-->A= rand(4,3); -->fprintfMat(test,A); trice dans un chier texte -->norm(B-A) ans = 8.159D-07 -->fd=mopen(test,r);

B=fscanfMat(test);

lecture ecriture dune ma on teste le r esultat de la lecture

ouverture du chier en lecture

38
-->L=mfscanf(-1,fd,"%f%f%f") L = ! ! ! ! 0.214601 0.3126420 0.3616360 0.292227 0.5664250 0.482647 0.3321720 0.5935090

Chapitre 1. Une introduction a ` Scilab


utilisation dun m eme format sur toutes les lignes du chier

0.5015340 0.4368590 0.2693120 0.6325740

! ! ! !

-->norm(L-A) ans = 7.989D-07 -->mclose(fd);

noter evidement que la pr ecision est controll ee par le format choisi

Nous donnons maintenant un autre exemple de lecture format ee avec des donn ees de type cha ne de caract` eres et nombres m elang ees. On cherche ` a lire au moyen de la fonction mfscanf le chier mfscanf.dat dont le contenu est :
// un exemple avec lecture d un fichier avec separateur de type [ ]*,[ ]* // ------------------------------------------------------------------------Agen , 47000 , 56 Aigues Juntes , 09000 , 78 Aiguilhe , 43000 , 78 Ainac , 04000 , 56 Ajaccio , 20000 , 23 Ajoux , 07000 , 34 Albi , 81000 , 23 Alencon , 61000 , 12

-->fd=mopen(mfscanf.dat,r); -->mgetl(fd,2); je saute les deux premi` eres lignes -->[n,a,b,c]=mfscanf(-1,fd,%[^,],%*[, ]%d%*[, ]%d\ n); lecture -->n n = 3. -->stripblanks(a) ans = !Agen Aigues Juntes Aiguilhe Ainac Ajaccio Ajoux matrice de cha ne (transpos ee) nombre darguments retourn es

Albi

Alencon

-->[b,c] ans = ! ! ! ! ! 47000. 9000. 43000. 4000. 20000. 56. 78. 78. 56. 23. ! ! ! ! !

donn ees num eriques

1.6. Fonctions dentr ees sorties


! ! ! 7000. 81000. 61000. 34. ! 23. ! 12. !

39

-->mclose(fd);

Pour permettre une ecriture binaire qui soit machine ind ependante les fonctions Scilab que nous verrons dans la suite ecrivent les nombres dans les chiers au format little endian. Ce mode par d efaut peut- etre supprim e au moyen du param` etre swap en lui donnant la valeur 0. Dans ce dernier cas les lectures ecritures se font avec le mode natif de la machine utilis ee. La fonction mopen retourne un descripteur de chier fd et eventuellement un indicateur derreur. La fonction mclose permet de fermer un chier qui a et e pr ec edemment ouvert par une commande mopen et de lib erer ainsi le descripteur du chier ouvert (Le nombre de chiers que lon eut ouvrir simultan ement est limit e). On notera quil est possible de fermer tous les chiers ouverts avec linstruction mclose(file()). Les fonctions d ecrites dans la table 1.5 permettent la lecture ecriture de donn ees binaires. Les fonctions mget et mput utilisent le mode de lecture (petit ou grand endian) qui est pr ecis e lors de louverture dun chier avec mopen. Mais il est toujours possible de forcer une lecture en petit ou grand endian en utilisant un param` etre ad equat.
mget mput mgetstr mputstr mtell mseek meof

Lecture de donn ees binaires Ecriture de donn ees binaires Lecture dune cha ne de caract` eres Ecriture dune cha ne de caract` eres retourne la position courante dans un chier d eplace la position courante dans un chier test de n de chier

Tab. 1.5 Quelques fonctions dentr ees sorties binaires On pourra se reporter aux fonctions Scilab contenues dans le r epertoire SCI/macros/sound o` u des fonctions de lecture ecriture de chier de sons constituent dexcellent exemples dutilisation des fonctions de la table 1.5. Nous donnons simplement ici un exemple sommaire de lecture ecriture dune matrice dans un format binaire.
-->x=testmatrix(magic,4); -->fd=mopen(save.dat,wb); ment utile que sous windows) -->mput(length(x),i,fd) -->mputstr(x,fd) ans = 0. -->mput(size(x,r),i,fd) -->mput(size(x,c),i,fd) Ecriture du nombre de lignes (un entier) Ecriture du nombre de colonnes (un entier)

Ouverture dun chier (le b nest vrai Ecriture dun entier. La longueur de la cha ne x Ecriture de la cha ne x

40
-->mput(x,d,fd) -->mclose(fd) ans = 0. -->clear x; -->fd=mopen(save.dat,rb); -->l=mget(1,i,fd) l = 1. -->name=mgetstr(l,fd) name = x -->m=mget(1,i,fd) m = 4. -->n=mget(1,i,fd) n = 4.

Chapitre 1. Une introduction a ` Scilab


Ecriture dun tableau de doubles Fermeture du chier

Ouverture dun chier en lecture lecture dun entier

lecture dune cha ne de caract` ere dont on conna t la longueur l

lecture des entiers m et n

-->data=mget(m*n,d,fd); lecture de m*n double dans un vecteur -->code= msprintf(%s=matrix(data,%d,%d);,name,m,n); -->execstr(code); cr eation de x dans lenvironement courant ` a partir des donn ees lues -->mclose(fd) fermeture du chier ans = 0. -->x x = ! ! ! ! 16. 5. 9. 4. 2. 11. 7. 14. 3. 10. 6. 15. 13. 8. 12. 1. ! ! ! ! test

1.7

Graphiques avec Scilab

Les primitives graphique Scilab sont nombreuses et il est hors de propos ici de les d ecrire compl` etement et de fa con exhaustives. Nous donnerons un aper cu et des r` egles dutilisation g en erales et il faudra se reporter aux manuel en ligne pour une utilisation pr ecise de chaque

1.7. Graphiques avec Scilab

41

fonction. Nous commen cons par un long script Scilab qui fait un petit tour dhorizon de fonctions graphiques. Lex ecution de ce script produit la Figure 1.4.
-->xbasc();t=linspace(-20*%pi,20*%pi,2000); xbasc eace la fen etre graphique courante et remet ` a z ero la liste des ordes graphiques enregistr es -->param3d1(sin(t),t.*cos(t)/maxi(t),t/100,35,45,X@Y@Z,[2,4]); courbe dans R 3 -->xs2ps(0,fig1); vers un fichier Postscript -->xbasc();x=linspace(-%pi,%pi,40); y=linspace(-%pi,%pi,40); -->plot3d(x,y,sinh(x)*cos(y)) ; -->xs2ps(0,fig2);

surface dans

R3

-->xbasc() -->function [xdot]=derpol(t,x); xdot=[x(2);-x(1)+(1 - x(1)**2)*x(2)];endfunction -->xf= linspace(-1,1,10);yf= linspace(-1,1,10); -->fchamp(derpol,0,xf,yf); champ de vecteurs dans R 2 -->xs2ps(0,fig3); -->xbasc(); v=rand(1,2000,n); -->histplot([-6:0.4:6],v,[1],015, ,[-4,0,4,0.5],[2,2,2,1]); -->function [y]=f2(x); y=exp(-x.*x/2)/sqrt(2*%pi); endfunction; -->x=-6:0.1:6;x=x;plot2d(x,f2(x),1,"000"); une courbe dans -->xs2ps(0,fig4); -->xbasc();polarplot();xs2ps(0,fig5); une courbe dans

un histogramme R 2 qui se superpose

R 2 en coordonn ees polaires

-->xbasc(); -->function [x,y,z]=f3(alp,tet) --> r=log(1+abs(alp)) --> x=cos(alp).*cos(tet); --> y=cos(alp).*sin(tet); --> z=sinh(alp); -->endfunction -->x=linspace(-%pi/2,%pi/2,40);y=linspace(0,2*%pi,20); -->[x1,y1,z1]=eval3dp(f3,x,y); construction de facettes -->plot3d1(x1,y1,z1); surface dans R3 donn ee par une matrice de facettes -->xs2ps(0,fig6); -->xbasc(); -->x=linspace(-%pi,%pi,40); y=linspace(-%pi,%pi,40); -->contour(x,y,sinh(x)*cos(y),10); -->xs2ps(0,fig7);

lignes de niveaux

-->xbasc();plot2d([],[],rect=[0,0,1,1],strf="012"); pour fixer une echelle -->xset(clipgrf); pour fixer une zone de clipping -->n=20; -->rects=[0.8*rand(1,n);0.8*rand(1,n);0.2*ones(1,n);0.2*ones(1,n)]; -->xrects(rects,rand(1,n)*20); une famille de rectangles -->xs2ps(0,fig8); -->xbasc()

42

Chapitre 1. Une introduction a ` Scilab

1.0 Z 11.5 0.8 0.6 0.4 0.2 0.0 0.00 1 0.63 1 0 0 Y 1 1 X 11.5 3.1 0.0 Y 3.1 3.1 0.0 X 0.6 3.1 0.8 1.0 1.0 0.2 0.4 0

Z 0.63

0.8

0.6

0.4

0.2

0.2

0.4

0.6

0.8

1.0

90 0.5 0.5 120 0.4 0.3 150 0.2 0.1 30 Z 2.30 60

180

0.00

210

330

2.30 1

1.0

0 0.0 4 0 4 240 270 300 Y 1 1.0

0.0 X

3.14 9.4 2.51 1.88 1.26 0.63 0.00 0.63 1.26 1.88 3.1 2.51 9.4 3.14 3.14 7.3 5.2 1.0 1.0 3.1 5.2 7.3 9.4 1.88 1.26 0.63 0.00 0.63 1.26 1.88 2.51 3.14 9.47.3 5.2 3.1 1.0 1.0 3.1 5.2 7.3 9.4 7.3 5.2 3.1 1.0 1.0 9.4 7.3 5.2 3.1

2.51

Fig. 1.4 Petit panorama

1.7. Graphiques avec Scilab

43

-->xsetech(frect=[-2*cos(%pi/6),0,2*cos(%pi/6),3]) pour fixer une echelle -->theta=[-%pi/6,%pi/2,%pi*7/6,-%pi/6]; -->T=[cos(theta);sin(theta)]; -->Ts=(1/(1+2*sin(%pi/6)))*rotate(T,%pi); -->x=[T(1,:);Ts(1,:)]; y=[T(2,:);Ts(2,:)]; -->x=[x+cos(%pi/6),x-cos(%pi/6),x];y=[y+sin(%pi/6),y+sin(%pi/6),y+1+2*sin(%pi/6)]; -->xset(thickness,8); epaisseur courante du trait -->xpolys(x,y); une famille de polygones -->xs2ps(0,fig9); -->unix(SCI+/bin/Blatexprs panorama fig[1-9]) ans = 0. appel dune commande unix

Nous commen cons par d ecrire quelques id ees g en erales sur la fa con dont le graphique est impl ement e dans Scilab. La sortie graphique courante peut etre une fen etre graphique, un chier au format Postscript, un chier au format xg suivant le driver graphique qui est s electionn e ( on obtient le driver courant avec la commande driver() et on s electionne un driver au moyen de la m eme commande avec un argument, par exemple driver(Pos) ou avec la commande xinit ou bien encore de fa con totalement transparente en utilisant des menus de Scilab). Quand on utilise comme driver une fen etre graphique Scilab a, par d efaut, la particularit e denregistrer toutes les commandes graphiques dans lordre ou elles ont et e ex ecut ees. Quand on grandit une fen etre graphique ou quand on eectue un zoom, Scilab peut donc rejouer les commandes enregistr ees et et produire un nouveau graphique adapt e au changement de taille. De la m eme fa con on peut rejouer les commandes graphiques apr` es avoir chang e de driver pour par exemple obtenir un graphique Postcript. Cest ce qui est fait dans le script pr ec edent au moyen de la commande xs2ps. Le driver courant associ e ` a une fen etre graphique et qui enregistre les commandes graphiques est le driver Rec. On peut rejouer les commandes graphiques au moyen de la commande xtape ou de la commande xbasr. La commande xbasc permet deacer la fen etre courante et deacer en m eme temps les commandes graphiques enregistr ees. d etruire une fen etre graphique xdel ` a bien s ur le m eme eet. Il peut parfois etre utile de supprimer lenregistrement des commandes graphiques, il sut pour cela de changer le driver et dutiliser le driver X (ou W) ` a la place de Rec. Par d efaut aussi les graphiques apparaissent dans une fen etre graphique au fur et a mesure de leur ex ecution. Il est possible de changer ce mode par d efaut et de contr oler le moment ou la fen etre graphique est rafra chie en changeant le mode pixmap de la fen etre courante. Le mode pixmap de la fen etre courante est un param` etre de la fen etre et il y en a beaucoup dautres. Ils d enissent le contexte graphique dune fen etre. On peut avoir ` a un moment donn e plusieurs fen etre graphique mais on ne peut changer le contexte graphique que de la fen etre courante. On obtient le num ero de la fen etre courante au moyen de xget(window) et on change la fen etre graphique courante par xset(window,n). On obtient les param` etres du contexte graphique de la fen etre courante au moyen de la fonction xget et on les change au moyen de la fonction xset.

44

Chapitre 1. Une introduction a ` Scilab

Mais revenons au mode pixmap. Quand ce mode est s electionn e xset(pixmap,1) le graphique nest plus eectu e directement sur la fen etre graphique mais sur une zone m emoire. La fen etre graphique nest rafra chie que quand la commande xset(wshow) est appel ee. On peut eacer la zone m emoire utilis ee pour le graphique par wset(wwpc). On peut ainsi construire des animations graphiques :
-->xsetech(frect=[0,0,10,10]) -->xrect(0,10,10,10) -->n=100; -->xset(pixmap,1) -->driver(X11); -->for k=-n:n, --> a=ones(n,n); --> a= 3*tril(a,k)+ 2*a; --> a= a + a; --> k1= 3*(k+100)/200; --> Matplot1(a,[k1,2,k1+7,9]) --> xset(wshow) --> xset(wwpc) -->end -->xset(pixmap,0)

Un dernier point g en eral est le calcul des echelles graphiques. Les fonctions permettant de dessiner des objets graphiques simples ( par exemple des rectangles xrects, des polylignes xpoly,. . . ) utilisent une echelle graphique courante et il est imp eratif pour leur utilisation correcte davoir dabord x e une echelle courante. Cela se fait soit en appelant une fonction de haut niveau, par exemple la fonction plot2d, soit au moyen de la fonction xsetech. Les fonctions de haut niveau par d efaut xent une echelle courante de fa con a ce quelle soit compatible avec les graphiques pr ec edents. On peut contr oler plus pr ecis ement les echelles au moyens de param` etres optionnels.
-->xbasc();t=linspace(0,2*%pi); -->plot2d(t,sin(t)) -->plot2d(t,sinh(t/%pi)) lechelle courante sadapte pour contenir les deux courbes (Figure 1.5 gauche) -->[a,b,c,d]=xgetech(); -->b lechelle courante: [xmin,ymin,xmax,ymax] b = ! 0. - 1. 7. 4. !

-->xbasc(); -->plot2d(t,sin(t)) -->plot2d(t,sinh(t/%pi),strf="000") -->[a,b,c,d]=xgetech(); -->b b = ! 0. - 1. 7. 1. !

sans changer lechelle courante (Figure 1.5 droite) lechelle courante: [xmin,ymin,xmax,ymax]

1.8. Interfa cage

45

4.0 3.5 3.0 2.5 2.0 1.5 1.0 0.5 0.0 0.5 1.0 0.0 0.7 1.4 2.1 2.8 3.5 4.2 4.9 5.6 6.3 7.0

Fig. 1.5 Utilisation des echelles

1.8
1.8.1

Interfa cage
Ecriture dune interface

Supposons quon dispose dune librairie de fonctions externes ecrites en C. La librairie contient par exemple la fonction geom qui eectue m*n tirages al eatoires selon une loi g eom etrique de param` etre p et stocke les r esultats dans un tableau dentiers y de taille m x n. Savoir ce que fait exactement geom nest pas vraiment utile pour nous ici. Disons simplement que, etant donn es les entiers m et n et le param` etre p, cette fonction retourne le tableau y. Voil` a le code C de la proc edure geom (qui est fort simple), la seule chose importante ici etant sa liste dappel :
#include <stdlib.h> int geom(int m,int n,double p,int y[]) { int i; if ( p >= 1.0 ) { cerro("p doit-etre < 1 "); return 1; } for (i = 0 ; i < m*n ; i++) { double z = drand48(); y[i] = 1; while ( z < 1.0-p ) { z = drand48(); y[i] ++; } } return 0; }

On souhaite donc rajouter dans Scilab une fonction (une primitive) de m eme nom geom dont la syntaxe dappel est y=geom(m,n,p). La fonction geom est suppos ee eectuer m*n tirages de loi g eom etrique et renvoyer le r esultat sous la forme dune matrice Scilab de taille m x n. Pour ce faire, il faut ecrire une interface, cest-` a-dire un programme (disons ` a nouveau en C) qui va etre charg e de faire les conversions et le passage des donn ees entre linterpr` ete

46
champ,champ1,fchamp contour,fcontour,contour2d, contourf, fcontour2d errbar eval3d,eval3dp,genfac3d fec geom3d grayplot,fgrayplot graypolarplot hist3d histplot isoview legends Matplot,Matplot1 param3d,param3d1 paramfplot2d plot plot2d,fplot2d ,plot2dxx plot3d,plot3d1,fplot3d, fplot3d1,plot3d2,plot3d3 polarplot Sfgrayplot, Sgrayplot subplot

Chapitre 1. Une introduction a ` Scilab champs de vecteurs dans le plan courbes de niveau rajoute des barres derreurs ` a une courbe 2D utilitaires pour construire des facettes pour un graphique 3D dessin 2D dune fonction d enie sur une triangulation calcul de coordonn ees courbes de niveau courbes de niveau sur courbe polaire histogramme 3D histogramme 2D change les echelles graphiques pour obtenir une repr esentation isom etrique rajoute des l egendes sur un graphique 2D dessin 2D des valeurs dune matrice Courbes param etrique en 3D animation de courbes 2D param etr ees courbes 2D Courbes 2D dessin 3D dune surface Courbes en coordonn ees polaires courbes de niveau subdivise une fen etre graphique en sous fen etre Tab. 1.6 Fonctions graphiques

Scilab et la fonction C geom. Nous appellerons intgeom linterface pour la fonction geom (il faut ecrire une interface pour chaque fonction que lon veut interfacer). Il existe dans Scilab diverses fa cons d ecrire une interface. Nous allons utiliser ici la m ethode qui nous semble la plus simple. De nombreux exemples d ecriture dinterfaces sont fournis dans le r epertoire SCI/examples. Le r epertoire SCI/examples/interface-tutorial-so/ donne aussi un exemple tr` es simple dinterface, destin ee aux utilisateurs d ebutants, proche de celle d ecrite ici. Pour ecrire cette interface particuli` ere, on a utilis e des fonctions de la librairie dinterfa cage (CheckRhs, CheckLhs, GetRhsVar et CreateVar), des variables de la librairie dinterfa cage (LhsVar) et des fonctions internes Scilab (cerro, aussi utilis ee dans geom). Pour utiliser les fonctions et les variables pr ec edentes, il faut rajouter le chier den-t ete stack-c.h dans le chier intgeom.c. Linterface de la fonction geom s ecrit alors de la fa con suivante :
#include "stack-c.h" extern int geom(int m, int n, double p, int y[]); int intgeom(char *fname) {

1.8. Interfa cage


xarc,xarcs xarrows xaxis xclea xclip xfarc,xfarcs xfpoly,xfpolys xfrect xgrid xnumb xpoly,xpolys xrect xrects xrpoly xsegs xstring,xstringb xstringl xtitle

47 dessine une (ou plusieurs) ellipse ou une partie dellipse dessine un ensemble de ` eches dessine un axe gradu e eace une zone rectangulaire xe une zone de clip peint une (ou plusieurs) ellipses peint le contenu dune (ou plusieurs) polyligne peint le contenu dun rectangle rajoute une grille sur un graphique rajoute des nombres sur un graphique dessine une (ou plusieurs) polyligne dessine un rectangle dessine ou peint un ensemble de rectangles dessine un polygone r egulier dessine un ensemble de segments non connect es dessine une cha ne de caract` eres coordonn ees dun rectangle entourant le dessin dune cha ne de caract` eres rajoute un titre Tab. 1.7 Primitives Graphiques

int l1, m1, n1, l2, m2, n2, m3, n3, l3; int minlhs=1, maxlhs=1, minrhs=3, maxrhs=3; int m,n,y; double p; /* 1 - V erification du nombre darguments dentr ee et de sortie */ CheckRhs(minrhs,maxrhs) ; CheckLhs(minlhs,maxlhs) ; /* 2 - V erification du GetRhsVar(1, "i", &m1, GetRhsVar(2, "i", &m2, GetRhsVar(3, "d", &m3, type &n1, &n2, &n3, des arguments et retour des pointeurs */ &l1); &l2); &l3);

if ( m1*n1 != 1 || m2*n2 != 1 || m3*n3 != 1) { cerro("Erreur: les arguments de geom doivent etre scalaires"); return 0; } /* 3 - Extraction des valeurs */ m = *istk(l1); n = *istk(l2) ; p = *stk(l3); /* 4 - Cr eation de la variable de retour */ CreateVar(4,"i",&m,&n,&y); if ( geom(m,n,p,istk(y)) == 1 ) return 0; /* 5 - Sp ecification de la variable de retour */ LhsVar(1) = 4; return 0;

48
driver graycolormap, hotcolormap xbasc xbasimp xbasr xchange xclear xclick xdel xend xget xgetech xgetmouse xgraduate,graduate xinfo xinit xlfont xload xname xpause xs2fig,xs2gif,xs2ppm,xs2ps xsave xselect xset xsetech xtape xtitle winsid

Chapitre 1. Une introduction a ` Scilab choix dun driver graphique tables de couleurs eace la fen etre graphique courante et les ordres graphiques enregistr es imprime la fen etre courante redessine le contenu dune fen etre graphique changement de coordonn ees eace la fen etre courante attente dun click souris d etruit une fen etre graphique termine une session graphique donne des valeurs du contexte graphique donne l echelle de la fen etre courante position et ev` enement souris utilitaire pour la graduation des axes rajoute une information dans la zone message dune fen etre graphique initialise un driver graphique charge des fonts recharge un graphique sauv e par xsave change le nom de la fen etre graphique courante pause convertit le graphique courant au format Xfig, gif, ppm ou Postscript sauve un graphique dans un format rechargeable avec xload s electionne une fen etre et la met au premier plan xe des valeurs du contexte graphique xe l echelle courante gestion de lenregistrement des ordres graphiques rajoute un titre retourne la liste des fen etre graphiques

Tab. 1.8 Primitives li ees aux fen etres graphiques


}

A premi` ere vue, cette fonction peut para tre un peu compliqu ee. En fait on ne va pas taper tout ce code, mais plut ot partir dun exemple tout fait quon va adapter ` a notre cas. Puisque tous les programmes dinterface sont b atis sur le m eme moule, les modications ` a faire sont tr` es faciles ` a r ealiser avec quelques retouches ` a l editeur. Linterface pr ec edente pourrait par exemple etre utilis ee presque telle quelle pour nimporte quelle fonction C qui aurait une liste dappel semblable ` a celle de geom. Comment cette interface marche-t-elle ? Quand sous linterpr` ete Scilab, on tape la commande y=geom(m,n,p), les arguments sont evalu es et leurs valeurs sont stock ees dans un tableau (que lon appellera pile dappel) dans lordre o` u ils apparaissent dans la liste dappel. Dautre part le nombre darguments de retour attendus (ici y) est connu. La fonction dinterfa cage intgeom doit tout dabord contr oler que le nombre darguments transmis et attendus au retour sont corrects. Cela est fait en utilisant CheckLhs et CheckRhs ; si le nombre darguments ne correspond pas aux bornes sp eci ees ces fonctions g en` erent une erreur et provoquent la sortie de linterface.

1.8. Interfa cage

49

Dans linterface, chaque variable Scilab est rep er ee par un num ero, dabord les variables dentr ee puis les variables de sortie. Ici par exemple, la fonction Scilab etant y=geom(m,n,p), les variables dentr ee m,n,p ont les num eros 1,2,3 et la variable de sortie y a le num ero 4. Ensuite, il faut v erier que chaque el ement pr esent dans la liste dappel a le bon type (est-ce une matrice, une cha ne de caract` eres, une fonction ?) et la bonne taille. Enn il faut r ecup erer un pointeur vers les donn ees pour pouvoir les transmettre ` a la fonction interfac ee ; cest ce qui est fait dans la deuxi` eme partie de la proc edure intgeom. La commande suivante :
GetRhsVar(2, "i", &m2, &n2, &l2);

a pour eet de v erier que le deuxi` eme argument de la liste dappel est bien de type num erique ("i") et de renvoyer dans m2 et n2 les dimensions de la matrice et dans l2 une adresse pour acc eder aux donn ees (une conversion des donn ees en entiers est faite). Si le type ne convient pas une erreur est g en er ee. Le deuxi` eme argument etant de type entier on obtient un pointeur dentiers avec istk(l2). Le deuxi` eme argument de geom qui doit etre un entier est donc nalement r ecup er e dans linterface par n= *istk(l2). On notera quil est prudent de v erier que m2*n2 vaut bien 1 car une utilisation de n = *istk(l2) dans un appel y=geom(10,[],2.5) donnerait nimporte quoi. Le troisi` eme argument est de type double ("d") et on y acc` ede par p=*stk(l3). De mani` ere g en erale, disposant des dimensions des arguments, on doit eectuer des v erications et en cas derreur on peut utiliser la fonction cerro pour acher un message puis faire un return (Scilab prend alors le relais). On notera dailleurs que dans la fonction geom, on a aussi utilis e la fonction cerro pour imprimer un message derreur. Avant dappeler la fonction geom, il faut cr eer la variable num ero 4, soit y, et r eserver de la place pour la stocker. La variable y doit etre une matrice dentiers de taille mn et la fonction geom veut un pointeur dentiers. La commande : CreateVar(4,"i",&m,&n,&y) de la quatri` eme partie de intgeom se charge de cr eer dans la pile dappel un nouvel objet Scilab avec le num ero 4 (une matrice mn) et ` a nouveau on obtient une adresse pour acc eder aux donn ees y (les donn ees sont enti` eres et sont donc accessibles via istk(y)) La syntaxe dappel de CreateVar est la m eme que celle de GetRhsVar sauf que les 4 premiers arguments sont des entr ees et le dernier une sortie calcul ee par CreateVar. Apr` es lappel de geom, il ne reste plus qu` a renvoyer ` a Scilab le r esultat ce que r ealise la cinqui` eme partie de la proc edure intgeom. Le nombre de variables attendues par Scilab a d ej` a et e contr ol e au d ebut de linterface (CheckRhs) et il ne reste plus qu` a indiquer par linterm ediaire de LhsVar(i)=j les positions des variables que lon veut renvoyer : linstruction LhsVar(1)=4 signie la premi` ere variable de sortie est la variable num ero 4. Cest Scilab qui contr ole alors tout seul d eventuelles conversions de donn ees ` a eectuer. Il nest bien s ur pas question de d ecrire ici toutes les fonctions de la biblioth` eque dinterfa cage. Le lecteur int eress e pourra se reporter au r epertoire
SCI/examples/interface-tour-so

pour une description au travers dexemples de toutes les possibilit es de la librairie. La connaissance des 4 fonctions d ecrites ici, (CheckLhs, CheckRhs, GetRhsVar, CreateVar) permet dinterfacer la plupart des fonctions C.

50

Chapitre 1. Une introduction a ` Scilab

Dans le r epertoire SCI/examples/interface-tour-so on montre en particulier comment interfacer une fonction C qui a elle-m eme une fonction comme param` etre dentr ee, ou comment on peut appeler linterpr` ete Scilab ` a lint erieur dune interface. Cest evidemment un peu plus compliqu e, mais des exemples simples sont donn es pour r ealiser ce type dinterface. Les utilisateurs familiers des mexfiles Matlab pourront se reporter au r epertoire
SCI/examples/mex-examples

pour constater que leurs chiers mex (librairie dinterfa cage de Matlab) marchent quasiment tels quels dans Scilab.

1.8.2

Chargement et utilisation

Il nous reste une deuxi` eme etape importante : comment charger et utiliser le code pr ec edent dans Scilab. Nous allons suivre ici la m ethode qui est utilis ee dans le r epertoire SCI/examples/interface-tour-so. Pour que lexemple soit plus r ealiste nous allons interfacer deux fonctions, la fonction geom que nous avons vu pr ec edemment et la fonction syst` eme srand48 qui permet dinitialiser le g en erateur al eatoire drand48. La fonction syst` eme srand48 ne renvoie pas de valeur et admet pour argument un entier, voila son interface :
int intsrand48(char *fname) { int l1, m1, n1; CheckRhs(1,1); CheckLhs(0,1); GetRhsVar(1, "d", &m1, &n1, &l1); if ( m1*n1 != 1 ) { cerro("Erreur: srand48 attend un argument scalaire"); return 0; } srand48((long int) *stk(l1)); LhsVar(1) = 0; /* pas de valeur renvoy ee */ return 0; }

Nous avons donc deux fonctions ` a interfacer et on supposera que les codes C correspondants sont ecrits dans un unique chier intgeom.c (contient intgeom, geom et intsrand48) . On notera quil ny a en fait aucune contrainte sur la r epartition des fonctions dans les chiers. Il faut maintenant charger ces codes dans Scilab pour d enir deux nouvelles primitives geom et srand48. Pour cela, il faut compiler le code, le charger dynamiquement (en chargeant une librairie partag ee .so sous Unix ou .dll sous Windows ) et indiquer les nom Scilab (geom et srand48) que lon veut donner aux fonctions dont les codes sont interfac es par intgeom et intsrand48. Tout cela va pouvoir seectuer depuis Scilab dune fa con ind ependante du syst` eme h ote (Unix, Windows), des compilateurs disponibles, etc, de la fa con suivante. Au moyen dun editeur de texte on va constituer un chier de nom builder.sce. Ce nom est canonique et un utilisateur qui rencontre un chier de nom builder.sce sait quil faut ex ecuter un tel chier pour congurer une contribution, un interface, etc . . . .

1.8. Interfa cage


// This is the builder.sce // must be run from this directory ilib_name = libealea // interface library name

51

// objects files files = [intgeom.o];

libs

= []

// other libs needed for linking

// table of (scilab_name,interface-name) // for fortran coded interface use C2F(name) table =[geom, intgeom; srand48,intsrand48]; // do not modify below // ---------------------------------------------ilib_build(ilib_name,table,files,libs)

Une base de d epart pour construire le chier builder.sce est le chier dexemple SCI/examples/interface-tutorial-so/builder.sce que lon peut facilement adapter ` a un nouvel interfa cage. Dans ce chier on trouve les informations suivantes : ilib_name contient une cha ne de caract` eres, cest le nom que lon veut donner la librairie (un ensemble dinterfaces) que lon est en train de construire. files est un vecteur de cha nes de caract` eres donnant la liste des chiers objets qui constituent la librairie. Ici on trouve juste le chier intgeom.o. Noter que les chiers objets sont not es avec un suxe .o et cela m eme si lon se trouve sous Windows. Un m eme chier builder.sce doit pouvoir sex ecuter sans changements sous Windows ou sous Unix. libs est un de cha nes de caract` eres donnant une liste de librairies n ecessaires ` a la cr eation de la librairie partag ee. table est une matrice de cha nes de caract` eres ou on donne la correspondance entre un nom de fonction Scilab et un nom dinterface. On trouve par exemple sur la premi` ere ligne geom, intgeom; qui indique que la fonction Scilab geom est interfac ee au moyen de linterface intgeom Il sut alors de faire ex ecuter ce chier par Scilab (il est imp eratif pour se faire que le r epertoire courant de Scilab soit le r epertoire ou se trouve le chier builder.sce) pour cr eer

52

Chapitre 1. Une introduction a ` Scilab

une librairie partag ee et cr eer un chier loader.sce qui permettra de charger la librairie dans Scilab.
-->exec builder.sce -->ilib_name = libalea; // interface library name -->files = [intgeom.o] // objects files -->libs = [] // other libs needed for linking -->table = [ geom, intgeom; // table of (scilab_name,interface-name) --> srand48,intsrand48]; -->// do not modify below -->// ----------------------------------------------->ilib_build(ilib_name,table,files,libs); generate a gateway file generate a loader file generate a Makefile: Makelib running the makefile

Apr` es lex ecution de ce chier, de nouveaux chiers sont cr ees dans le r epertoire courant. Le plus important dentre eux est le chier loader.sce. Il permet le chargement dans Scilab de la nouvelle librairie au moyen de la fonction addinter. En pratique on ex ecute donc une fois builder.sce pour compiler la librairie puis ` a chaque nouvelle session Scilab on ex ecute loader.sce pour charger la librairie (noter que le chargement peut etre eectu e de nimporte o` u, il nest pas n ecessaire de se trouver dans le r epertoire de loader.sce pour lex ecuter).
// appel du loader qui est dans un r epertoire distant -->exec SCI/contrib/geom/loader.sce -->// generated by builder.sce: Please do not edit this file -->// ------------------------------------------------------->libalea_path=get_file_path(loader.sce); -->functions=[ geom; --> srand48; -->]; -->addinter(libalea_path+/libalea.so,libalea,functions); Loading shared executable addinter-linux-so//libalea.so shared archive loaded Linking libalea (in fact libalea_) Interface 0 libalea

Citons pour information les autres chiers g en er es. On trouve un chier libalea.c appel e gateway. Il contient une proc edure appel ee proc edure de gestion des interfaces. Elle sert daiguillage pour g erer la table de correspondance table. On trouve egalement un chier Makelib qui est un chier Makefile qui d epend du syst` eme h ote et de lenvironnement de compilation (Unix, Windows/Visual C++, Windows/Absoft). Il permet la cr eation de la librairie partag ee. Il ne reste plus qu` a tester cette nouvelle primitive geom avec le petit script qui suit. On compare graphiquement (Figure 1.6) lhistogramme empirique obtenu par simulation et celui donn ee par la th eorie
-->n=10000; pr=0.2 ; -->y=geom(1,n,pr); // appel de la nouvelle primitive

1.8. Interfa cage


-->N=20; i=0:N; // tests des r esultats -->z=[]; for i1=i, z=[z,size(find(y==i1),"*")];end -->plot2d3("onn",i,z/n,[1,3],"161","Simulation"); -->zt=0;for i1=1:N; zt=[zt,pr*(1-pr)^(i1-1)];end -->plot2d1("onn",i,zt,[-2,6],"100","Theorie");

53

Fig. 1.6 Histogramme des donn ees

1.8.3

intersci

Il existe dans Scilab un utilitaire appel e intersci qui permet de g en erer un chier dinterface ` a partir dun chier de description de la fonction ` a interfacer. intersci ne permet pas toute la souplesse dune interface ecrite ` a la main en C mais peut etre utilis e pour certaines interfaces simples ou comme base de d epart. Dans une version r ecente intersci g en` ere du code compatible avec celui que nous avons d ecrit dans les paragraphes pr ec edent. La documentation compl` ete de intersci se trouve dans le r epertoire doc de Scilab et de nombreux exemples sont d ecrits dans le r epertoire SCI/examples/intersci-examples-so. Nous nous limitons ici ` a un exemple simple, interfacer la fonction ext1c :
#include "machine.h" int F2C(ext1c)(n, a, b, c) int *n; double *a, *b, *c;

54
{ int k; for (k = 0; k < *n; ++k) c[k] = a[k] + b[k]; return(0); }

Chapitre 1. Une introduction a ` Scilab

On notera que cette fonction na que des arguments de type pointeurs et que le nom de la fonction est encapsul e dans un appel de macros C2F(ext1c) (cest une limitation de intersci qui doit interfacer ` a la fois des fonctions C et Fortran). Pour interfacer cette fonction il faut ecrire un chier de description disons ex01fi.desc (le suxe .desc est impos e) :
ext1c a b a vector m b vector m c vector m ext1c m a b c m integer a double b double c double out sequence c ***********************

Le texte ecrit dans le chier indique que lon va cr eer une fonction Scilab [c]=ext1c(a,b) o` u a,b et c sont trois vecteurs de m eme taille. La premi` ere ligne d ecrit les arguments dentr ee et la derni` ere les arguments de sortie. La fonction ext1c pour sex ecuter doit appeler la fonction C ou Fortran C2F(ext1c) avec quatre arguments : un pointeur dentier qui contiendra la taille des vecteurs et trois pointeurs de double qui permettrons dacc eder aux valeurs contenues dans les vecteurs Scilab a,b et c. La place n ecessaire pour stocker c est r eserv ee dans linterface avant lappel de la fonction C C2F(ext1c). En ex ecutant intersci au moyen de la commande :
bin/intersci-n ex01fi

on va g en erer linterface ex01fi.c et un chier de type builder (comme au paragraphe 1.8.2)


ex01fi_builder.sce. #include "stack-c.h" /****************************************** * SCILAB function : ext1c, fin = 1 ******************************************/ int intsext1c(fname) char *fname; { int m1,n1,l1,mn1,m2,n2,l2,mn2,un=1,mn3,l3; CheckRhs(2,2); CheckLhs(1,1); /* checking variable a */

1.8. Interfa cage


GetRhsVar(1,"d",&m1,&n1,&l1); CheckVector(1,m1,n1); mn1=m1*n1; /* checking variable b */ GetRhsVar(2,"d",&m2,&n2,&l2); CheckVector(2,m2,n2); mn2=m2*n2; /* cross variable size checking */ CheckDimProp(1,2,m1*n1 != m2*n2); CreateVar(3,"d",(un=1,&un),(mn3=n1,&mn3),&l3); C2F(ext1c)(&mn1,stk(l1),stk(l2),stk(l3)); LhsVar(1)= 3; return 0; }

55

On se reportera au r epertoire
SCI/examples/intersci-examples-so

o` u le m eme exemple est repris de fa con plus compl` ete. Lensemble des op erations ` a eectuer etant r ecapitul ees dans le chier ex01.sce :
// appel de intersci-n au moyen dun Makefile G_make(ex01fi.c,ex01fi.c); // execution du builder cr\ee par intersci-n files = [ex01fi.o , ex01c.o]; libs = [] ; exec(ex01fi_builder.sce); // execution du loader exec loader.sce // test de la fonction a=[1,2,3];b=[4,5,6]; c=ext1c(a,b); if norm(c-(a+b)) > %eps then pause,end

1.8.4

Utilisation de la commande link

Pour terminer, il convient de parler dun cas (encore) plus simple o` u on peut charger des fonctions dynamiquement dans Scilab sans avoir ` a ecrire une interface. On utilise pour cela les fonctions Scilab link et call. Une contrainte est impos ee, on doit modier la fonction C pour que sa liste dappel ne contienne que des pointeurs.
#include <stdlib.h> int geom1(int *m, int *n, double *p, int y[]) { int i; if ( *p >= 1.0 ) { cerro("p doit-etre < 1 "); return 1; } for (i = 0 ; i < (*m) * (*n) ; i++) {

56

Chapitre 1. Une introduction a ` Scilab


double z = drand48(); y[i] = 1; while ( z < 1.0 - *p ) { z = drand48(); y[i] ++; }

} return 0; }

Comme pr ec edemment il faut cr eer une librairie partag ee et la charger cette fois dans Scilab avec la commande link. Il existe donc deux fa cons de charger une librairie partag ee dans Scilab mais qui correspondent ` a deux usages di erents : (addinter rajoute des primitives Scilab et n ecessite l ecriture dinterfaces alors que scifunlink ne fait que rajouter des fonctions dans la table des fonctions accessibles par les primitives non lin eaires ode, optim,. . . et la primitive call.
-->names=[geom1] // les points dentr ees ` a rajouter // ici un seul. -->files = geom1.o // les fichiers objets. -->flag = c -->ilib_for_link(names,files,[],"c"); generate a loader file generate a Makefile: Makelib running the makefile

Dans ce qui pr ec` ede flag=c permet de pr eciser que la fonction geom1 est ecrite en C. Cette pr ecision est n ecessaire car sur certains syst` emes le compilateur Fortran ajoute un blanc soulign e (underscore) au d ebut ou a ` la n des noms des points dentr ee ce que ne fait pas le C. On charge alors dynamiquement cette fonction dans Scilab en ex ecutant le chier loader.sce.
-->exec loader.sce // chargement de la librairie -->link(geom1_path+/libgeom1.so,[geom1],c); Loading shared executable ./libgeom1.so shared archive loaded Linking geom1 (in fact geom1) Link done

On peut alors appeler la fonction C geom1 depuis Scilab et obtenir sa sortie comme une variable Scilab. On doit envoyer ` a geom1 les param` etres dentr ee m,n et p et r ecup erer la matrice de sortie y. Cest la commande call qui permet de faire cet appel. La syntaxe est un peu longue car on doit fournir les valeurs des variables dentr ee, mais aussi leur type C et leur position dans la liste dappel de geom1. Cest en eet la fonction call qui doit faire le travail de conversion que nous avions pr ec edemment cod e dans un interface. Cela donne par exemple :
-->m=3;n=4;p=0.3; -->y=call("geom1",m,1,"i",n,2,"i",p,3,"d","out",[m,n],4,"i");

Dans cette instruction, on indique en premier argument le nom de la fonction C appel ee (cest aussi le point dentr ee pass e ` a link). Les arguments suivants, jusqu` a la cha ne out,

1.8. Interfa cage

57

donnent linformation relative aux variables dentr ee. Les arguments situ es apr` es la cha ne out donnent, pour leur part, linformation relative aux variables de sortie. ` chaque variable est associ A e un triplet de param` etres. On interpr` ete par exemple les trois param` etres m,1,"i" comme : passer la valeur m comme premier argument de geom de type int. En sortie, on aura : y (premier argument ` a gauche du signe egal) est une matrice de dimension [m,n], quatri` eme param` etre de geom, de type int. Evidemment, on peut encapsuler linstruction call(...) dans une fonction Scilab y=geom(m,n,p) et en proter pour faire des tests (par exemple de dimensions) sur les arguments pass es ` a notre fonction C. Une autre utilisation de la commande link se fait dans le contexte suivant : certaines primitives Scilab comme par exemple les fonctions ode, fsolve ou optim admettent des arguments de type fonction que lon appellera fonctions externes. Par exemple pour chercher les z eros de la fonction cos(x) x2 1, on peut construire une fonction Scilab :
function y=f(x) y=cos(x)*x^2-1

et utiliser ensuite cette fonction f comme argument de la fonction fsolve :


-->y0=10; y=fsolve(y0,f) y = 11.003833 -->f(y) ans = 3.819D-14

On peut parfois avoir envie, pour des raisons decacit e, de coder ce genre de fonctions dans un langage compil e (C, C++ ou Fortran). Dans ce cas, il ne faut pas vraiment ecrire une interface, car la fonction fsolve a d ej` a et e pr evue pour fonctionner avec des fonctions f externes. fsolve nous impose par contre une contrainte sur la liste dappel de la fonction f quelle peut reconna tre (voir le help de fsolve). Lexemple pr ec edent pourrait etre cod e en C sous la forme :
#include <math.h> void f(int *n,double *x,double *fval,int *iflag) { *fval = cos(*x)*(*x)*(*x) - 1; }

On proc` ede comme pr ec edemment pour compiler et charger la fonction C f dans Scilab :
-->ilib_for_link(f,f.o,[],c); generate a loader file generate a Makefile: Makelib running the makefile -->exec loader.sce

et on indique ` a fsolve que le probl` eme ` a r esoudre concerne la fonction f ecrite en C en lui passant en argument la cha ne "f" :

58

Chapitre 1. Une introduction a ` Scilab

-->y0=10; y=fsolve(y0,"f") y = 11.003833

Cela est valable pour la plupart des primitives Scilab admettant des argument fonctionnels.

Deuxi` eme partie

Examples illustratifs

Chapitre 2

Programmer : Arbres et matrices de ramication


Le but de ce T.P de programmation Scilab est la synth` ese dimages darbres par les matrices de ramication [3] [1]. Les arbres que lon va g en erer seront des arbres binaires : chaque ar ete m` ere donne naissance ` a exactement deux ar etes lles (ou aucune pour les ar etes qui conduisent aux feuilles de larbre). Un exemple darbre binaire est donn e dans la gure 2.1
1 1 1 2 1 2 3 3 2 2 1 1 1

Fig. 2.1 Un exemple darbre et les ordres des ar etes Sur cet arbre binaire on peut d enir lordre dune ar ete ou dun arbre (cest lordre de lar ete issue de la racine de larbre) qui se calcule r ecursivement de la fa con suivante : soit t un arbre, si larbre est r eduit ` a une ar ete son ordre od(t) = 1 sinon on consid` ere les deux sous arbres de larbre t, soient R(t) et L(t) et on a alors la formule : od(t) =
def

max(od(R(t)), od(L(t))) od(L(t)) + 1

si od(R(t)) = od(L(t)) si od(R(t)) = od(L(t))

(2.1)

On voit ainsi que partant des ar etes dordre 1 (celles qui on un noeud feuille) on peut, en

62

Chapitre 2. Programmer : Arbres et matrices de ramication

utilisant la formule pr ec edente, calculer lordre de toute les ar etes de larbre (un exemple est donn e sur la gure (2.1). On appelle biordre dun noeud le couple (i, j ) (avec i < j )) des ordres des ar etes lles issues du noeud consid er e. Si lordre dune ar ete est k alors les biordres possibles sont (1, k ), (2, k ), . . . , (k 1, k ) et (k 1, k 1) Il y a donc k biordres possible pour une ar ete dordre k . Pour g en erer al eatoirement une structure darbre, on part de la racine de larbre dordre x e N . Puis r ecursivement on g en` ere par tirages al eatoires des biordres successifs pour construire les ar etes lles. Pour tirer un biordre au hasard, an de g en erer les descendants dune ar ete dordre k , il faut se donner une loi discr` ete sur {1, . . . , k }not ee Pk . Pour g en erer un arbre dordre od(t) = N , il faut donc se donner N 1 lois de probabilit e discr` etes (Pk )k=2,N . La loi Pk etant une loi discr` ete sur{1, . . . , k }. Pour simplier on rajoute la loi P1 qui ne sera pas utilis ee puisquune feuille na pas de descendants. Cela revient ` a se donner une matrice triangulaire inf erieure (dite matrice de ramication) P de taille N N v eriant 0 pij 1 et N eme ligne de la matrice P . j =1 pij = 1. La loi Pk se lit sur la k -i`

2.0.5

Matrices de ramications

On commence par ecrire une fonction qui etant donn e un ordre N et un param` etre de choix renvoie une matrice de ramication. Pour commencer la fonction doit renvoyer deux types de matrice, soit une matrice identit e N N, soit une matrice N N de la forme : 1 1 1 1 1 2 2 avec def = (2.2) 2 1 2 3 3 ...
-->function [N,mat]=matrice_ramification(N,val) --> select val Selection du type de matrice ` a construire --> case 1 then mat=eye(N,N); Matrice Identit e --> case 2 then --> mat= (1/2).^[1:N-1]; Puissance termes ` a termes pour construire 1 & . . . &N 1 --> mat=ones(N-1,1)*mat ; Copier N fois la m eme ligne --> mat=tril(mat); Extraire la partie triangulaire inf erieure --> d=diag(diag(mat),1);d($,:)=[]; La diagonale principale --> mat = [mat,zeros(N-1,1)]+d; --> mat = [eye(1,N);mat]; Rajout de la premi` ere ligne --> end -->endfunction -->[N,mat]=matrice_ramification(3,2); mat mat = ! 1. 0. 0. !

63
! ! 0.5 0.5 0.5 0.25 0. ! 0.25 !

2.0.6

Tirage al eatoire des ordres des ar etes lles

On ecrit maintenant une fonction calcul_ordre qui etant donn e un ordre k utilise un matrice de ramication mat pour faire un tirage al eatoire des ordres des deux ar etes lles issues de lar ete dordre k. On utilise la k-i` eme ligne de la matrice de ramication pour eectuer un tirage dans {1, . . . , k}. Si la valeur k est tir ee les deux ar etes lles on pour ordre k-1 sinon la valeur tir ee donne lordre de lune des ar etes lles et lautre ` a alors pour ordre la valeur k. Le choix dattribution entre lle gauche et droite se fait alors avec une loi uniforme.

-->function [ordreg,ordred]=calcul_ordre(k) --> o1=k; --> o2=grand(1,markov,mat(k,1:k),1) --> if o2==k then --> o1=k-1; o2= k-1; --> end --> ale= grand(1,uin,1,2) ; --> if ale==1, --> ordreg=o1; ordred=o2; --> else --> ordreg=o2; ordred=o1; --> end -->endfunction

loi sur 1,. . . ,k en utilisant mat les deux ar etes lles sont dordre k-1 1 ou 2 avec loi uniforme Attribution des ordres gauche et droit

2.0.7

Construction dun arbre

On utilise ici les listes Scilab pour coder un arbre binaire de la fa con suivante : Une feuille sera cod ee par la liste T=list(1) (1 est lordre dune feuille) Un arbre t dordre k sera cod e par T=list(k,Tg,Td) o` u Tg et Td codent respectivement les sous arbres gauches et droits de larbre t. On ecrit maintenant une fonction r ecursive Scilab qui construit une liste codant un arbre al eatoire obtenu ` a partir dune matrice de ramication mat

-->function [L]=construire(k) --> if k==1 then --> L=list(1); Liste associ ee ` a une feuille --> else --> [ordreg,ordred]=calcul_ordre(k); Tirage des ordres des ar etes lles --> L=list(k,construire(ordreg),construire(ordred)); On suit la d enition --> end -->endfunction -->N=2; [N,mat]=matrice_ramification(N,1); -->L=construire(N) L = Matrice identit e 2x2 Un exemple

64
L(1) 2. L(2) L(2)(1) 1. L(3) L(3)(1) 1.

Chapitre 2. Programmer : Arbres et matrices de ramication

2.0.8

Utilisation des graphes Scilab pour visualiser larbre

Le codage pr ec edent des arbres nest pas tr` es parlant, la sortie ecran de Scilab devenant rapidement inadapt e pour visualiser un arbre, m eme de petite taille. Avant dutiliser directement le graphique Scilab, nous allons construire un graphe Scilab ` a partir de notre arbre et directement utiliser les fonctions de repr esentation de graphes de Scilab pour la visualisation. Pour ce faire il faut pouvoir attribuer des positions dans le plan aux noeuds de notre arbre. Nous allons utiliser un algorithme du a D.Knuth dont lid ee est la suivante. Au cours de lalgorithme de construction de larbre on va conserver pour chaque noeud sa profondeur et on va attribuer a chaque noeud un num ero. Les num eros attribu es aux noeuds correspondent ` a une num erotation obtenue en faisant un parcourt en profondeur dabord de larbre. On change donc le codage pr ec edent en rajoutant la profondeur et une num erotation dans les listes en rempla cant le scalaire ordre par une matrice [ordre,numero,profondeur]. On modie la fonction construire en cons equence. Elle admet maintenant trois arguments, lordre et la profondeur du noeud courant et le premier num ero attribuable ` a un noeud de larbre ` a g en erer. En retour la fonction construire renvoie un arbre sous forme de liste Scilab et le denier num ero attribu e` a un noeud dans la construction de larbre. La nouvelle version de construire prends maintenant la forme suivante :
-->function [L,nmax]=construire(k,numero,prof) --> if k==1 then --> L=list([1,numero,prof]); Une feuille --> nmax=numero; Le dernier num ero utilis e dans le cas feuille --> return; --> end --> [ordreg,ordred]=calcul_ordre(k); --> [Lg,nmg]=construire(ordreg,numero,prof+1) Le sousarbre gauche utilise numero comme premier num ero ` a attribuer --> [Ld,nmd]=construire(ordred,nmg+2,prof+1); Le sous arbre droit utilise le dernier num ero attribu e a larbre gauche plus 2 comme premier num ero --> L=list([k,nmg+1,prof],Lg,Ld); On rajoute la racine dordre k et de num ero nmg+1 --> nmax=nmd; -->endfunction

2.1. Repr esentation graphique directe

65

Il sut maintenant dattribuer aux noeuds de larbre une abscisse proportionnelle aux num eros des noeuds et une ordonn ee proportionnelle ` a la profondeur des noeuds pour obtenir une repr esentation visuelle de larbre. Nous commen cons par construire deux matrices : Une dont le nombre de colonnes est le nombre dar etes de larbre et chaque colonne contient le num ero du noeud p` ere et le num ero du noeud ls de lar ete. Une autre dont le nombre de colonnes est le nombre de noeuds de larbre et chaque colonne contient lordre, le num ero et la profondeur du noeud correspondant On construit ces deux matrices simultan ement ` a laide dune fonction r ecursive utilisant L le r esultat de la fonction construire :
-->function [M,pos]=construire_matrice(L,M,pos) --> if size(L)== 3 then Ce nest pas une feuille ! --> M=[M,[L(1)(2);L(2)(1)(2)],[L(1)(2);L(3)(1)(2)]]; Deux ar etes ` a rajouter --> [M,pos]=construire_matrice(L(2),M,pos); Passer au sous arbre gauche --> [M,pos]=construire_matrice(L(3),M,pos); Passer au sous arbre droit --> end --> pos=[pos,L(1)] Rajouter les informations du noeud courant -->endfunction

On notera que les matrices M et pos sont ` a la fois donn ee en entr ee et en sortie de la fonction construire_matrice. Les arguments des fonctions etant pass es par valeur, on ne peut pas les modier. Par contre on peut en modier une copie et renvoyer cette copie dans les arguments de sortie de la fonction. Il ne reste plus qu` a tester le code. On note que si lon choisit une matrice Identit e NN pour matrice de ramication, on obtient un arbre r egulier de hauteur N et lordre des ar ete diminue strictement ` a chaque division. On trouvera sur la Figure 2.2 un arbre obtenue en utilisant la matrice identit e avec N = 4 (` a gauche) et un exemple avec la matrice 2.2 ` a nouveau avec N = 4 (` a droite).
-->N=4;val=1; -->[N,mat]=matrice_ramification(N,val); -->[L,nmax]=construire(N,1,1); -->[g,rect]= construire_graphe(L,nmax); -->rep=[2 1 1 2 1 2 2 2 2 2 2 2 2]; -->plot_graph(g,rep,rect);

Voir Figure 2.2

2.1

Repr esentation graphique directe

On cherche maintenant ` a obtenir une repr esentation graphique des arbres g en er es en utilisant les primitives graphiques de Scilab. Pour obtenir une repr esentation graphique, on va construire des segments qui repr esentent les ar etes de larbre et dessiner ` a l ecran lensemble des segments ` a laide de la fonction xsegs. On dispose de plusieurs degr es de libert e:

66

Chapitre 2. Programmer : Arbres et matrices de ramication

1 2

1 2 3

1 2

1 2 3

1 1 2 1 1 2 2 3 4 4 1 1 2 1 1 3 1 2 3 1 2 1 2 1 1 1 2 1

Fig. 2.2 Repr esentation de larbre On peut faire d ependre la couleur et l epaisseur du trait utilis e de lordre du segment ` a tracer. A chaque ramication, les angles de rotation 1 et 2 des branches lles par rapport ` a la direction de la branche m` ere peuvent d ependre aussi de lordre de la branche m` ere. Quand une branche m` ere et une branche lle ont m eme ordre, on peut imaginer quil sagit dune branche principale de larbre et donc diminuer langle de rotation entre m` ere et lle dans ce cas la. Nous allons ` a nouveau construire larbre par une fonction r ecursive. Au cours de la r ecursion nous voulons construire une matrice qui codera lensemble des segments et leurs ordres. Pour des arbres de grande taille proc eder comme dans la fonction construire_matrice sera tr` es p enalisant ` a cause des recopies et r eallocation des matrices pass ees ` a la fois en argument dentr ee et de sortie. Nous allons donc plut ot ici utiliser une variable globale ou plut ot une fonction empiler(x) qui re coit en argument un vecteur ligne et qui le stocke dans une matrice globale. Si la variable globale sappelle M empiler doit en th eorie juste eectuer lop eration M=[M;x]. Cette op eration qui va etre r ep et ee un grand nombre de fois nest pas vraiment ecace car elle saccompagne dune copie de M. Pour en augmenter la rapidit e M sera allou ee par blocs. On utilisera une tlist pour coder la pile avec les champs suivants : val est une matrice pxq o` u q est la taille des vecteurs ` a stocker dans la pile. pos est lindice de la ligne courante que lon peut utiliser pour stocker un vecteur dans la pile. libres est le nombre de lignes encore libres dans la pile. inc est le nombre de lignes ` a rajouter dans val quand la pile est pleine. Cest donc la taille dallocation des blocs. On ecrit maintenant la fonction empiler et la fonction valeurs qui donne la matrice contenant toutes les valeurs empil ees.
-->function []=empiler(x) met de la pile, la taille de x doit etre xe --> global %pile; --> n=length(x);buf_size=1000; --> if typeof(%pile)==constant then Rajoute un vecteur ligne au som-

buf_size nous donne la taille des blcos Creation de la pile

2.1. Repr esentation graphique directe

67

--> %pile=tlist([pile,val,pos,libres,inc],0*ones(buf_size,n),1,buf_size,buf_size); --> end --> if %pile.libres > 1 then --> %pile.val(%pile.pos ,:)=x; On stocke x --> %pile.pos = %pile.pos + 1; On incr emente la position libre --> %pile.libres = %pile.libres - 1; On d ecr emente le nombre de positions libre --> else --> %pile.val=[%pile.val;0*ones(%pile.inc,n)]; On rajoute un block dans la pile --> %pile.libres = %pile.libres + %pile.inc; On mets ` a jours le nombre de positions libres --> empiler(x); On stocke x --> end -->endfunction -->function m=valeurs() --> global %pile; --> m=%pile.val(1:%pile.pos-1,:); -->endfunction On extrait de la pile la matrice des valeurs stock ees La derni` ere valeur stock ee est sur la ligne pos-1

La fonction calculer construit un arbre et stocke au fur et ` a mesure les segments qui le compose dans la pile.
-->function []=calculer(cp,cd,k) calcul les ar etes lle du segment cd cp dordre k --> empiler([cd(1),cp(1),cd(2),cp(2),k]); On empile les informations sur le segment --> if k==1,return;end Arr et sur une feuille --> [ordreg,ordred]=calcul_ordre(k); Calcul des ordres des deux branches lles --> l1=l(ordreg),l2=l(ordred); Les longueurs des branches lles --> delta1=del(ordreg)*%pi/180,delta2=del(ordred)*%pi/180; les angles de rotation --> if ordreg==k then --> delta1=delta1/5; la branche principale tourne moins --> end --> if ordred==k then --> delta2=delta2/5; la branche principale tourne moins --> end --> [cp1,cp2]=newp(cp,cd) calcul des deux nouveaux noeuds --> calculer(cp1,cp,ordreg); calcul du nouveau segment qui suit cp cd1 --> calculer(cp2,cp,ordred); calcul du nouveau segment qui suit cp cd2 -->endfunction -->function [cp1,cp2]=newp(cp,cd) Rotations pour trouver les coordonn ees des deux noeud ls --> dir=cp-cd;dir = dir/norm(dir,2) --> diro=[dir(2),-dir(1)] --> cp1= cp + l1*cos(delta1)*dir + l1*sin(delta1)*diro --> cp2= cp + l2*cos(delta2)*dir - l2*sin(delta2)*diro -->endfunction

Et il ne reste plus qua tester notre code :


-->clearglobal %pile;

68

Chapitre 2. Programmer : Arbres et matrices de ramication

-->N=10;val=1; -->[n,mat]=matrice_ramification(N,val); -->l=[1:N]/N; // les longueurs a utiliser pour les aretes de nombre i -->del=20*ones(1,N); // langle a utiliser pour les aretes de nombre i -->xbasc(); -->nc=N;cmap=[((1:nc).^2)/nc;1:nc;((1:nc).^2)/nc]/nc; -->xset("colormap",cmap) // langle a utiliser pour les aretes de nombre i -->calculer([0,0],[0,-1],N); -->m=valeurs(); -->x=m(:,1:2); -->y=m(:,3:4); -->plot2d(0,0,1,"010"," ",[mini(x),mini(y),maxi(x),maxi(y)]) -->for i=1:N --> I=find(m(:,5)==i); --> xset("thickness",i) // lepaisseur du trait d epend de lordre de larete. --> xsegs(x(I,:),y(I,:),N-i); -->end

Fig. 2.3 Arbre 1

2.1. Repr esentation graphique directe

69

Fig. 2.4 Arbre 2

70

Chapitre 2. Programmer : Arbres et matrices de ramication

Chapitre 3

Programmer : Arbres et DOL-syst` emes


3.0.1 DOL-syst` emes
Le but de ce T.P de programmation Scilab est la synth` ese dimages darbres. Les arbres sont obtenus aux moyens dexpression grammaticales et de r` egles de r e- ecriture [2]. On g en ere tout dabord des cha nes de caract` eres au moyen de r` egles de production ou de r e- ecriture, puis on reinterprete ces cha nes de caract` eres en les explorant sequentiellement et en associant une action ` a chaque lettre lue. Soit A un alphabet, on d esignera par A lensemble des mots que lon peut construire avec cet alphabet ( y compris le mot vide) et par A+ les mots non vide de A . On appellera DOL la donn ee dun triplet (A, , P ) ou A est un alphabet, est un mot non vide ( A+ ) appel e axiome et P est un ensemble de r` egle de r e ecriture (P A A ). Les r` egle de r e ecriture sont donc des couples (a, ) A A que lon ecrit en g en eral sous la forme a . A chaque lettre de lalphabet A doit correspondre au moins une r` egle de r e ecriture. Si aucune r` egle de r e ecriture nest sp eci ee explicitement pour a A alors on supposera que la r` egle a a est valide. Enn on appellera un DOL-syst` eme la donn ee dun L-syst` eme v eriant la propri et e suivante : pour tout a A il nexiste quun A tel que a . Le D veut dire d eterministe : pour r e ecrire un el ement de A il ny a quune solution. Comment utilise-t-on un DOL-syst` eme ? on part de laxiome et on remplace toutes les lettres de par le mot associ e dans la r` egle de r e ecriture. On obtient ainsi un nouveau mot 1 et on peut repeter le processus un nombre nies de fois. Considerons lexemple suivant : A F = {F, H, +, } (3.1) (3.2) (3.3) (3.4)

H F +H +F H F H = F

partant de laxiome on obtient apr` es une premi` ere application des r` egles de r e ecriture : 1 = H F H

72 puis ` a l etape 2 :

Chapitre 3. Programmer : Arbres et DOL-syst` emes

2 = F + H + F H F H F + h + F et ainsi de suite On codera un DOL-syt` eme en Scilab au moyen dune fonction qui re coit en entr ee une chaine de carat` ere et qui en sortie renvoit la cha ne de carat` ere obtenue apr` es application des r e- ecritures.
-->function [w]=Irewrite0(v) --> w=strsubst(v,F,X+F+X); R` egle : F H+F+H. On prot` ege les H nomm es X pour linstant. --> w=strsubst(w,H,F-H-F); R` egle : H F-H-F. --> w=strsubst(w,X,H); On renomme les X en H. -->endfunction

Pour eectuer N etape de r e ecriture il sut deectuer une boucle. On ecrit une fonction charg ee de cela :
-->function [w]=rewrite(macro,init,n) --> w=init; --> for i=1:n, w=macro(w);end -->endfunction

init est laxiome. init On applique les r e- ecriture

Et on obtient :
-->w=rewrite(Irewrite0,F,3) w = 3 niveaux de r e- ecriture ` a partir de F

H+F+H-F-H-F-H+F+H+F-H-F+H+F+H+F-H-F+H+F+H-F-H-F-H+F+H

3.0.2

Interpr etation des cha nes

Apr` es N niveaux de r e ecriture dans un DOL-syst` eme on obtient une cha ne n . On va interpr eter maintenant cette cha ne pour en faire un dessin. Lid ee est la suivante, on passe en revue les caract` ere de la cha ne n du premier au dernier et on associe ` a chaque caract` ere de A une action graphique. On reprend lexemple pr ec edent avec A = {H, F, +, }. On se place dans le plan et on se donne un point courant x et une direction d : Quand on lit un symbole H ou un symbole F (et de fa con plus g en erale quand on lit une lettre), on se d eplace dans la direction d dune longueur L. Le nouveau point courant devient x + l d. Quand on lit un + (resp ) on change la direction d dun angle (resp ). L et sont deux constantes que lon se donne et que lon pourra faire varier. En parcourant la cha ne n , on va d ecrire une courbe dans le plan. La fonction qui suit calcul_segments calcule les di erent segments qui vont composer la courbe et renvoie ces segments dans deux matrices x et y.

73

-->function [xs,ys]=calcul_segments(w,delta,l) --> delta = delta*%pi/180; --> Rm = [cos(delta),-sin(delta);sin(delta),cos(delta)] --> Rp = [1,-1;-1,1].*Rm; --> L=length(w); --> res=ones(4,L); Matrice pour stocker les segments calcul es --> count=1; premier indice utilisable pour stocker un segment --> pt=[0;0];dir=[0;1]; Point et direction initiaux. --> for i=1:L --> select part(w,i) Le $i$-i` eme caract` ere de w. --> case + then --> dir= Rp*dir; --> case - then --> dir= Rm*dir; --> else --> newpt=pt + l*dir; --> res(:,count)=[pt(1);newpt(1);pt(2);newpt(2)]; --> pt = newpt; --> count=count+1; --> end --> end --> xs=res(1:2,1:count-1); --> ys=res(3:4,1:count-1); -->endfunction -->w=rewrite(Irewrite0,F,7); 3 niveaux de r e- ecriture ` a partir de F -->[xs,ys]=calcul_segments(w,60,1); -->rect=[mini(xs),mini(ys),maxi(xs),maxi(ys)]*1.1 rect = ! - 3.461D-13 0. 121.93638 140.25 !

-->xsetech(frect=rect); -->xsegs(xs,ys);

Voir Figue 3.1

3.0.3

Dessiner un arbre

Pour pouvoir g en erer des structures arborescentes on va enrichir notre alphabet A de deux symboles [ et ]. Leur signication est la suivante : quand on rencontre un symbole [ il faut sauver la position ou lon se trouve dans une pile (empiler). Quand on lit un symbole ] il faut reprendre comme position courante la position qui etait au sommet de la pile et r etirer cette valeur de la pile (d epiler). Par exemple, la cha ne linterpr etation de la cha ne F[F]-F+ doit dessiner une structure en forme de Y . On etends le programme de calcul des segments pr ec edents pour quil interpr` ete les symboles [ et ]. On sauvegarde aussi dans la pile, en m eme temps que le point courant, un compteur qui va nous servir ` a compter le nombre dembranchement qui conduit ` a un sous arbre. On utilisera cela pour le graphique ult erieurement.

74

Chapitre 3. Programmer : Arbres et DOL-syst` emes

Fig. 3.1 Premier mod` ele

-->function [xs,ys,ordre]=calcul_segments(w,delta,l) --> delta = delta*%pi/180; --> Rm = [cos(delta),-sin(delta);sin(delta),cos(delta)] --> Rp = [1,-1;-1,1].*Rm; --> L=length(w); --> stack=ones(5,L); Matrice utilis ee comme pile --> stc=1; Premier indice utilisable dans la pile --> res=ones(5,L); Matrice pour stocker les segments calcul es --> count=1; Premier indice utilisable pour stocker un segment --> pt=[0;0];dir=[0;1]; --> ordre=1; Compteur darborescence --> for i=1:length(w) --> select part(w,i) --> case [ then --> stack(:,stc)=[pt;dir;ordre];stc=stc+1; Il faut empiler les valeurs courantes --> ordre=ordre+1; --> case ] then --> stc=stc-1;xx=stack(:,stc); Il faut d epiler les valeurs courantes --> pt=xx(1:2); dir=xx(3:4); ordre=xx(5); --> case + then --> dir= Rp*dir; Rotation + --> case - then --> dir= Rm*dir; Rotation --> else --> newpt=pt + l*dir; Calcul dun nouveau point --> res(:,count)=[pt(1);newpt(1);pt(2);newpt(2);ordre]; --> pt = newpt; --> count=count+1; --> end --> end

75
--> xs=res(1:2,1:count-1); --> ys=res(3:4,1:count-1); --> ordre=res(5,1:count-1); -->endfunction -->function [w]=Irewrite1(v) --> w=strsubst(v,F,F[+F]F[-F]F); -->endfunction -->stacksize(10000000); -->w=rewrite(Irewrite1,F,5); -->[xs,ys,ordre]=calcul_segments(w,30,1); -->rect=[mini(xs),mini(ys),maxi(xs),maxi(ys)]*1.1 rect = ! - 56.747303 0. 44.55 267.3 !

-->xsetech(frect=rect); -->xsegs(xs,ys);

Voir Figue 3.2

Fig. 3.2 Un mod` ele darbre On utilise maintenant pour chaque segment la valeur ordre pour changer l epaisseur et la couleur du segment ` a tracer. On choisit les couleurs dans une tables de couleur dans les verts allant du noir au vert clair.
-->function []=dessiner(xs,ys,ordre) --> rect=[mini(xs),mini(ys),maxi(xs),maxi(ys)]*1.1 --> xsetech(frect=rect); --> m=maxi(ordre);

On xe lechelle courante

76

Chapitre 3. Programmer : Arbres et DOL-syst` emes

--> if m <> 1 then --> cmap=[((1:m).^2)/m;1:m;((1:m).^2)/m]/m; --> xset("colormap",cmap) On change de table de couleur --> end --> is=size(xs,c); --> tm=maxi(ordre); --> for i=mini(ordre):maxi(ordre) --> I=find(ordre==i); On selectionne les segments dordre i --> xset("thickness",1*(tm-ordre(I(1)))); Epaisseur du trait fonction de lordre --> xsegs(xs(:,I),ys(:,I),i) Les segments dordre i avec la couleur i --> end -->endfunction -->function [w]=Irewrite2(v) --> w=strsubst(v,H,F-[[H]+H]+F[+FH]-H); --> w=strsubst(w,F,FF); -->endfunction -->set(old_style,on); -->w=rewrite(Irewrite2,H,5); -->[xs,ys,ordre]=calcul_segments(w,40,1); -->dessiner(xs,ys,ordre); On selectionne lancien mode graphique

Voir Figue 3.3

Fig. 3.3 Un mod` ele darbre Le d efaut des DOL-syst` emes vus pr ec edemment est que pour un niveaux N de r e ecriture x e les gures g en er ees sont toujours identiques. On peut etendre ce qui pr ec` ede en retirant laspect d eterministe, on sautorise alors ` a avoir plusieurs r` egles de r e ecriture pour une m eme. On se donne alors des probabilit e de choix des r egles que lon utilise au moment de lapplication des r e ecritures.

77

-->function [w]=Irewrite3(v) --> rew=[F[+F],F[-F],F[-F]F,F[+F]F] --> w=""; --> for i=1:length(v) --> if part(v,i)== F then --> w = w + rew(grand(1,uin,1,4)); --> else --> w = w +part(v,i) --> end --> end -->endfunction -->set(old_style,on); -->w=rewrite(Irewrite3,F,9); -->[xs,ys,ordre]=calcul_segments(w,32,1); -->dessiner(xs,ys,ordre); On selectionne lancien mode graphique

Voir Figue 3.4

Fig. 3.4 Un mod` ele darbre

78

Chapitre 3. Programmer : Arbres et DOL-syst` emes

Chapitre 4

Programmer : Musique serielle


Le but de ce T.P de programmation Scilab est de g en erer des partitions musicales en utilisant (librement) les r` egles de la musique s erielle ou en faisant g en erer la melodie par un syst` eme dynamique. On utilise Scilab pour g en erer un chier pmx. Puis ` a partir de ce chier des utilitaires (Unix ou Windows) permettent dobtenir une partition musicale o` u un chier Midi. Nous aurons donc besoin des utilitaires suivants : pmx qui permet de traduire un chier pmx en format Midi ou en format MusicTEX . musixtex qui permet dobtenir une partition (par exemple au format pdf) ` a partir dun chier MusicTEX. Le r ole de Scilab est de construire une chier MusicTEX.

4.1

Musique s erielle

On utilise des r` egles formul ees par Arnold Sch onberg pour construire notre partition musicale : Une phrase musicale (dite aussi serie de Sch onberg) de d epart P1 est dabord donn ee, elle consiste en la donn ee dans un ordre quelconque des douze sons de l echelle chromatique temp er ee, chacun de ces sons n etant pr esent e quune fois. Nous utiliserons dans Scilab la fonction grand pour g en erer al eatoirement cette s erie. A partir de cette premi` ere phrase musicale on en g en` ere trois autres. Une phrase r ecurrente P2 , obtenue en renversant lodre des notes de la phrase P1 de la derni` ere ` a la premi` ere note. Une phrase renvers ee P3 obtenue en changeant la direction des intervalles de la phrase P1 Une phrase r ecurrente renvers ee P4 obtenue en changeant la direction des intervalles de la phrase P2 On peut ensuite transposer sur les onze autres degr es de l echelle chromatique les quatres phrases initiale (Pi )i=1,...,4 . On obtient donc au nal 48 formes que lon peut utiliser pour composer un morceau, ce que nous ferons de fa con rudimentaire en tirant al eatoirement des phrases succ essives dans les 48 possibles. On peut encore jouer sur les rythmes et les auteurs de notes ( equivalence de toutes les notes du m eme nom entre elles).

80

Chapitre 4. Programmer : Musique serielle

4.1.1

G en erer les 48 phrases possibles

Comme il y a N = 12 notes dans la gamme chromatiques nous allons pour linstant dans la phase de g en eration les coder par des entiers 1, . . . , N . Nous nous limitons donc ` a des notes dans un m eme octave. Les transformation propos ees peuvent faire sortir de lintervalle 1, . . . , N et on sy ramenera en utilisant une transposition doctave apropri ee. Voila les fonctions de base pour g en erer les phrases initiales
-->function germe=initiale() --> N=12; --> notes=(1:N); --> germe=grand(1,prm,notes) ; -->endfunction -->function y=renverse_ecarts(x) --> // renversement des ecarts --> ecart=diff(x); --> y = cumsum([x(1);-ecart]); -->endfunction -->function y=recurrente(x) --> y=x($:-1:1) -->endfunction -->function y=moduloN(y) --> N=12; --> y = pmodulo(y,N); --> y(y==0) = N -->endfunction Tirage al eatoire dune s erie de Sch onberg

On tire une permutation al eatoire de 1, . . . , N

Calcul des ecarts succ essifs en nombre de demi-tons La s erie des ecarts renvers es

La s erie renvers ee en temps

On ram` ene les notes dans lintervalle 1, . . . , N

Que lon utilise maintenant pour g en erer les 48 phrases utilisables sous forme dune matrice N 48 :
-->germe=initiale(); Phrase initiale cod ee sous la forme dun vecteur colonne

-->pos=[germe,renverse_ecarts(germe),... Les quatres phrases associ ees cod ees sous forme dune matrice --> recurrente(germe),renverse_ecarts(recurrente(germe))]; -->pos=moduloN(pos); -->N=12; -->all=[pos]; -->for i=1:N-1 --> all=[all,moduloN(pos+i)]; -->end -->size(all) ans = On ram` ene les notes dans 1, . . . , N

Toutes les transpositions de nos quatres phrases

Une phrase par colonne et 48 colonnes

4.1. Musique s erielle


! 12. 48. !

81

4.1.2

Le codage des notes en pmx

Les 12 notes de la gamme chromatique (` a octave x e) sont cod ees en pmx par des cha nes de carat` eres que nous codons ici dans un vecteur ligne de cha nes de carat` eres Scilab :
-->notes_m = [cn,cs,dn,ds,e,fn,fs,gn,gs,an,as,b] ; -->notes_m = notes_m + 44; On xe la dur ee et loctave de fa con absolue

Nous allons g en erer ici un petit morceau de 8 mesure et chaque mesure va contenir une phrase possible (sans r ep etition) parmi les 48 possibles obtenue ` a nouveau par tirage al eatoire de loi uniforme sur les 48 phrases. Comme chaque phrase contient 12 notes, nous allons g en erer 3 triolets de croches par mesures. Un trilet de croches se code en pmx sous la forme dune cha ne de caract` ere Ax3 B C, o` u A, B et C sont les codes des trois notes qui composent le triolet. Une mesure se termine par le carat` ere /. Nous ecrivons une fonction qui renvoie un vecteur colonne de cha ne de carat` eres. Chaque ligne du vecteur codant une mesure du morceau.
-->function [txt]=morceau(all) --> p=size(all,c); --> I=grand(1,prm,(1:p)) ; --> pat=I(1:8); --> txt=string([]); --> for i=pat --> im = notes_m(all(:,i)) ; --> im(1:3:$) = im(1:3:$) +x3; --> im= strcat([im,/], ); joute le code de n de mesure --> txt=[txt;im]; --> end -->endfunction

p vaut 48 ! Une permutation al eatoire des 48 phrases On nen garde que 8

On transforme la phrase i en vecteur de cha ne Toutes les 3 notes, on forme un triolet On concat` ene les el ements de im et on ra On rajoute le code de la nouvelle mesure dans txt

Pour obtenir le codage du morceau en pmx il ne reste plus qu` a rajouter en ent ete xe et ` a ecrire le tout dans un chier.
-->txt=morceau(all); Un morceau de 8 mesures choisies dans all

-->head=[1 1 4 4 4 40.000; 0 0 2 16 0.0; --> t --> ./ --> Aa1br --> It60;w140m]; -->mputl([head;txt],grand.pmx) -->unix(pmx grand) Ent ete et ecriture dans un chier Il ne reste plus qu` a utiliser pmx

82
ans = 0.

Chapitre 4. Programmer : Musique serielle

La partition g en er ee est alors la suivante :

G4 4
3

3 3 4 6 6 4 6 6 4 4 4 6 6 4 4 43 6 63 4 6 6 4 3 3 3 3

3 3 6 4 6 4 6 4 4 6 4 4 6 G 6 6 4 6 3 6 4 63 4 4 3 3 3 3 3 3 3 3 4 4 6 4 6 4 6 G 4 6 4 6 6 3 6 6 4 4 6 4 4 6 5 3 3 3 3 3 3 G 6 4 4 6 4 6 6 6 43 4 7 3 3 3 6 6 6 4 4 6 4 43 4 6

Fig. 4.1 Partition g en er ee

4.2

Utilisation du syst` eme de Lorenz

-->//compute lorenz differential eqn solution -->y=ode(1.e-8*[1;1;1],0,0:1:100,loren); -->[n1,n2]=size(y) ; -->notes=y(1,:); -->mi=mini(notes);mx=maxi(notes); -->notes_b = [c,d,e,f,g,a,b] ; -->notes_n = [notes_b + 44, notes_b + 45]; -->notes_c = [notes_b + 84, notes_b + 85]; -->N=size(notes_n,*); -->v=y(2,:); -->vi=mini(abs(v));vx=maxi(abs(v)); -->I=find( abs(v) >= vi+ (vx-vi)/2); -->notes= int(1+ (notes-mi)*(N-1)/(mx-mi)); -->all_n = notes_n(notes);

4.2. Utilisation du syst` eme de Lorenz


-->all_c = notes_c(notes); -->all = all_n; -->all(I)= all_c(I); -->d = ones(all_n); -->d(I)= 0.5; -->// On regroupe les notes par mesure -->count=1; -->mes=string([]); -->while %t --> t=cumsum(d(count:$)); --> i=find(t > 4); --> if i<>[] then --> ti= sum(d(count:count+i(1)-2)); --> im = all(count:count+i(1)-2); --> if ti == 3.5 then --> im= strcat([im,r8,/], ); --> else --> im= strcat([im,/], ); --> end --> mes=[mes;im]; --> count=count+i(1)-1; --> else --> break --> end -->end -->head=[1 1 4 4 4 40.000 0; 0 4 16 0.0; --> t --> ./ --> Aa1br --> It260;w140m]; -->mputl([head;mes],lorenz.pmx) -->unix(pmx lorenz.pmx); -->unix(timidity -Ow lorenz.wav lorenz.mid);

83

La partition g en er ee est alors la suivante :

84

Chapitre 4. Programmer : Musique serielle

G4 4
5

( ? ( (

? - ? - ? (

( ?

? (

( - -

( - ? ? ( ?

G ( G
13 9

G G

17

21

Fig. 4.2 Partition g en er ee

Bibliographie
[1] N.Janey. Mod elisation et synth` ese dimages darbres et de bassins uviaux associant m ethodes combinatoires et plongement automatique darbres et cartes planaires. PhD thesis, Th` ese de lUniversit e de Franche-Comt e, http://raphaello.univ-fcomte.fr/These/Default.htm, 1992. [2] P.Prusinkiewicz and A.Lindenmayer. The Algorithmic beauty of plants. Springer, 1996. [3] X.G.Viennot, G.Eyrolles, N.Janey, and D.Arqu` es. Combinatorial analysis of ramied patterns and computer imagery of trees. Computer Graphics, 23 :3140, 1989.

Index
A
addinter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52

I
ilib_build . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 ilib_for_link . . . . . . . . . . . . . . . . . . . . . . . . . 56

argn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 ascii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

C
call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
call . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

cha nes de caract` eres . . . . . . . . . . . . . . . . . . 19 CheckLhs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 CheckRhs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 contour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 CreateVar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49

interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 builder.sce . . . . . . . . . . . . . . . . . . . . . . . . 50 examples . . . . . . . . . . . . . . . . . . . . . . . . . . 46 gateway . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 intersci . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 librairie dinterfa cage . . . . . . . . . . . . . .46

K
.*. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .13

L
length . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 linspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 loader.sce . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 logspace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

D
diag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

E
%eps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 eval3dp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 execstr . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20, 22 external link . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 eye . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

M
matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 sparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . .24 testmatrix . . . . . . . . . . . . . . . . . . . . . . . . 20 mlist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 msprintf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 msscanf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

F
fchamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 nd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

O
ones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

P G
getf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 GetRhsVar . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 grand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 grep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 param3d1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 part . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 plot3d . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 polarplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 primitive . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 proc edure de gestion des interfaces . . . . 52

H
histplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

Index quit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

87

R
rand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

S
select . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 sparse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 strcat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 strindex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 string . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 stripblanks . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 strsubst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

T
tlist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 tokens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 typeof . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

W
while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 who . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 whos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

X
xbasc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41, 43 xbasr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 xdel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 xget . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 xinit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 xpolys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 xrects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 xs2ps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 xset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 clipgrf . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 pixmap . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 thickness . . . . . . . . . . . . . . . . . . . . . . . . . . 43 wshow . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 wwpc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 xsetech . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .43 xtape . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Z
zeros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Vous aimerez peut-être aussi