TP Scilab
Transcription
TP Scilab
Chapitre 1 Introduction 1.1 TP à rendre Le TP à faire individuellement ou en binôme consiste en différents exercices indiqués . par le logo Le compte rendu demandé est un seul fichier contenant les lignes de code commentés correspondant aux différents exercices et doit être à envoyer par e-mail à l’adresse [email protected] avant le 1er octobre. 1.2 Présentation Les séances machines proposées sont à faire avec le logiciel Scilab. Ce logiciel est libre et peut être téléchargé sur le site WEB www.scilab.org A l’UFRIM2AG, Scilab est installé sous Windows et Linux (PC), utiliser de préférence la version installée sous Linux. Deux niveaux sont proposés : – le niveau 1 (Bases) présente un survol des fonctionnalités de base de Scilab en restant proche de la syntaxe de Matlab. Les différents exemples à tester sont indiqués par l’icône et les instructions standard apparaissent sur fond rose // matrice carrée A = [2 3;9 8]; la syntaxe des commentaires en Scilab est similaire à C++ ou Java, et se trouve sur une ligne à la suite de 2 backslash \\ . En Matlab, un commentaire se trouve sur une ligne à la suite du caractère pourcentage % 1 – le niveau 2 (Utilisation avancée) présente un approfondissement de certains points en utilisant uniquement le langage Scilab. Lorsqu’une différence de syntaxe entre Scilab et Matlab existe alors celle-ci sera indiquée avec l’icône et le code Matlab apparaitra sur fond jaune, et le code Scilab sur fond bleu. Instruction standard (compatible Matlab et Scilab) A = [2 3;9 8]; Instruction compatible Matlab a = 2 * pi / 3; % angle égal à 120 degrés Instruction compatible Scilab a = 2 * %pi / 3; // angle égal à 120 degrés 1.3 Utilisation de SCILAB Pour démarrer SCILAB, double-cliquer sur l’icône correspondant ou taper la commande scilab & La fénêtre pricipale (Scilab console) s’ouvre avec différents menus et icônes correspondants et la partie commande. La première chose à faire est de se placer dans un répertoire de travail afin de stocker les différents fichiers de la séance : cliquer sur l’icône et choisir le répertoire de travail dans le dialogue. Pour tester les différents exemples et aussi écrire les scripts correspondants aux exercices demandés, il est conseillé d’utiliser l’éditeur intégré de Scilab possèdant les fonctionnalités et raccourcis clavier standards d’un éditeur. 2 Pour tester les exemples, il suffit de : – écrire les instructions dans l’éditeur, – sélectionner à la souris les lignes à exécuter, – cliquer avec le bouton de droite sur la sélection et choisir Evaluate selection dans le menu, ou de taper au clavier le raccourci Ctrl-E. Un fichier contenant des instructions en langage Scilab est un fichier texte dont l’extension est .sce ou .sci. Pour avoir de l’aide sur les différentes fonctions de Scilab, utiliser l’instruction help ou cliquer sur l’icône . 1.4 Informations complémentaires Des informations complémentaires sur Matlab et Octave se trouvent dans le document Matlab-like. 3 Chapitre 2 Les bases 2.1 2.1.1 Type scalaire Numérique Le type de base est le réel en double precision, chaque réel étant codé au format IEEE 64 bits (type double en C/C++, real*8 en Fortran) permettant les ordres de grandeur entre 10−308 et 10+308 et, la précision numérique limitée à 16 chiffres décimaux. Cela permet de représenter de manière exacte tout entier relatif dont la valeur absolue est inférieure environ à 2 250 000 000 000 000 = 2, 25 × 1015 a = 7 , b = a ^20 la virgule , sert à séparer plusieurs instructions sur une même ligne si une instruction se termine par le point-virgule ; a = 7; b = a ^20; 4 alors rien n’est affiché à l’écran Il est possible de manipuler des nombres complexes, la valeur imaginaire i = définie en Matlab par la variable i et en Scilab par la variable %i √ −1 est a = 2+ %i , b = -5+3*% i , c = a*b a = 2+i , b = -5+3*i , c = a * b Il est recommandé de redéfinir les constantes numériques en leur donnant un nom de variable différents (notamment la variable i qui est habituellement utilisée comme variable de boucle) I_CPLX = sqrt ( -1) M_PI = 3 . 1 4 1 5 9 2 6 5 35 897 932 38 462 643 M_E = exp (1) a = 2+ I_CPLX , b = -5+3* I_CPLX , c = a* b 2.1.2 Booléen Une valeur booléenne peut prendre une des valeurs VRAI ou FAUX. En Matlab, les deux constantes VRAI et FAUX sont definies par les variables true et false alors qu’en Scilab, elles sont définies par les variables %t et %f On pourra redéfinir ces deux valeurs ainsi : TRUE = 0 <1 FALSE = 1 <0 2.1.3 Chaine de caractères Une chaı̂ne de caractères se définit entre quotes Prenom = " Julien " Nom = "L " " Ecuyer " 5 ’ ou double-quotes " en Scilab. 2.2 Matrice, vecteur, base Pour définir une matrice, il faut mettre les différentes valeurs entre crochets [] , avec un espace entre chaque valeur d’une même ligne, le point-virgule ; indiquant le passage à la ligne suivante. 1 Les matrices A = 4 2 et les vecteurs u = −4 6 2 3 5 6 ,B= et v = 2 + i −3 −4 5 − 2i −1 + i 3i −4 I_CPLX = sqrt ( -1); A = [1 2 3 ; 4 5 6] B = [2+ I_CPLX -3 ; -4 5 -2* I_CPLX] u = [2 ; -4 ; 6] v = [ -1+ I_CPLX 3* I_CPLX -4] un vecteur-ligne est défini en séparant les valeurs par des espaces, et un vecteur-ligne est défini en séparant les valeurs par des points-virgules un scalaire est une matrice ou vecteur avec un seul élément faire attention à écrire une même valeur sans espace sinon elle sera interprétée comme deux valeurs différentes v = [ -1+ I_CPLX 3* I_CPLX -4] w = [ -1 + I_CPLX 3* I_CPLX -4] On accède à un élément d’un vecteur ou d’une matrice en indiquant son ou ses indices entre parenthèses () . 6 Avant de tester les instructions ci-dessous, deviner ce qu’on obtiendra à l’écran A = [1 3 5 7;2 4 6 8]; v = [6 5 4 7 9 0]; A (1 ,2) , A (2 ,1) , v (3) A (2 ,3) = v (5) On peut aussi traiter les matrices par bloc en utilisant l’opérateur : A = [1 4 7 10 13;2 5 8 11 14;3 6 9 12 15] B = [1 0;0 1] , C = [4 2;2 6] A (3 ,:) A (: ,1:2:5) A (1:2 ,3:4)= B D = [C B B;B C B;B B C] A (2: $ ,:) A (1 ,2:$ -1) A (:) Le symbole $ ( end en MATLAB) correspond au dernier indice de la dimension correspondante. La notation A(:) transforme la matrice A en un vecteur-colonne, les éléments d’une matrice étant stockés en mémoire colonne par colonne. La notation a:b crée un vecteur-ligne formé des valeurs a, a+1, a+2, . . .a+i, . . .et inférieures ou égales à b La notation a:pas:b crée un vecteur-ligne formé des valeurs a, a+pas, a+2*pas, . . .a+i*pas, . . .et inférieures (resp. supérieures) ou égales à b avec pas est une valeur strictement positive (resp. strictement négative) 1:10 2.3:6 1:2:20 0:0.1:1 0: -0.5: -4 7 2.3 2.3.1 Opérations de base Scalaires Les opérations de base sur les scalaires sont : addition (+) , soustraction (-) , multiplication (*) , division (/) , puissance (^) et sont les opérations habituelles sur les réels/complexes avec les priorités habituelles. calcul de 2 + 5 × 6 − I_CPLX= sqrt ( -1); 2 + 5*6 - 3^2/9 (1 -2* I_CPLX )^( -2) 2.3.2 1 32 et (1 − 2 i)−2 = 9 (1 − 2 i)2 Vecteurs/Matrices Dès qu’un opérande est un vecteur/matrice, le calcul matriciel est utilisé. Addition (+) ou soustraction (-) somme/différence élément par élément, les deux opérandes devant être de mêmes dimensions. on définit quatre matrices A, B1, B2, C, un vecteur-ligne (=matrice à une ligne) v et un vecteur-colonne (=matrice à une colonne) u. A = [1 2 3;4 5 6] , B1 = [0 1;1 0;1 1] , B2 = [1 2;2 3;5 9] C = [1 2;1 3] , v = [2 4 5] , u = [1;2;1] puis testez une par une les opérations suivantes : A + B1 B1 + C B1 - B2 u + v u + u + u les opérations sont faites uniquement si les dimensions concordent, dans le cas contraire, un message d’erreur (inconsistent operation) s’affiche. 8 il y a une exception dans le cas où l’un des deux opérandes est un scalaire : dans ce cas, le résultat est le tableau obtenu en faisant l’opération entre chaque élément du tableau et le scalaire. 2 + A A - 2 1 - u Multiplication entre vecteurs/matrices (*) si les deux opérandes sont des tableaux alors le produit matriciel est effectué (si les dimensions concordent). Tester les instructions suivantes une par une A * B1 B1 * A B1 * C B1 * B2 C * C A * u v u u v * * * * B u v u Transposée (’) le symbole quote ’ à la suite d’une matrice donne sa transposée. A’ B1 ’ C’ u’ u’ * u u * u’ 9 Puissance d’une matrice carrée (^) le symbole puissance ^ s’applique à une matrice carrée. calcul de C 2, C 3, C −1 (l’inverse de C) et C C −1 : C ^2 C ^3 C ^( -1) C * C ^( -1) une puissance négative peut être utilisée seulement pour une matrice inversible. Multiplication/division élément par élément (.*) en utilisant le point devant * ou /, on peut pour deux matrices de mêmes dimensions, obtenir une matrice de mêmes dimensions obtenue en faisant l’opération élément par élément : B1 .* B2 , C .* C , u .* u 3 .* A , u ./ 2 la puissance élément par élément peut être faite en utilisant point-circonflexe .^ . C .^ 2 , u .^ 3 pour diviser un scalaire par les éléments d’une matrice, il faut utiliser la division élément par élément entre deux matrices en mettant la valeur scalaire entre parenthèses Calcul de la matrice dont les éléments sont 3/Ai,j (3)./ A 2.4 2.4.1 Fonctions de base Fonctions usuelles La majorité des fonctions usuelles sont définies. Si l’opérande est une matrice ou un vecteur, la fonction s’applique élément par élément 10 A = [1 2; exp (1) 10] , t = 0:0.1:1 M_PI = 3 . 1 4 1 5 9 2 6 5 35 897 932 38 462 643 cos ( M_PI /4) tan ( t ) log ( A ) log10 ( exp (3)) sinh ( t ) cos ( t ).^2 + sin ( t ).^2 quand une expression mathématique doit s’appliquer à un tableau de valeurs, utiliser les opérateurs élément par élément ./ .* .^ 11 2.4.2 Fonctions ”matricielles” • sum (resp. prod) : calcule la somme (resp. le produit) des éléments d’un vecteur v ou la somme (resp. le produit) des éléments pour chaque rangée - ligne ou colonne - d’une matrice M u = [1 2 4] , v = [2;4; -6] A = [1 2 3;4 5 6] u = [1 2 4] , v = [2;4; -6] A = [1 2 3;4 5 6] % somme des éléments % d ’ un vecteur sum ( u ) , sum ( v) % produit des éléments % d ’ un vecteur prod ( u ) , prod ( v ) // somme des éléments // d ’ un vecteur sum ( u ) , sum ( v ) // produit des éléments // d ’ un vecteur prod ( u ) , prod (v ) % somme des lignes % d ’ une matrice sum (A , 1) % somme des colonnes % d ’ une matrice sum (A , 2) % somme des éléments % d ’ une matrice sum ( sum ( A )) // somme des lignes // d ’ une matrice sum (A , 1) // somme des colonnes // d ’ une matrice sum (A , 2) // somme des éléments // d ’ une matrice sum ( A ) • zeros (ones) : crée une matrice dont tous les éléments sont égaux à 0 (1) zeros (1 ,6) , ones (3 ,1) zeros (4 ,4) , ones (2 ,6) • eye : crée une matrice diagonale unitaire (matrice avec des 1 sur la diagonale principale et 0 ailleurs) Une matrice identité et une matrice non carrée eye (3 ,3) eye (3 ,5) 12 • diag : crée des matrices carrées diagonales à partir de vecteurs diag(v) crée une matrice carrée avec les valeurs du vecteur v sur la diagonale principale diag(v,k) crée une matrice carrée avec les valeurs du vecteur v sur la diagonale à distance k de la diagonale principale (à gauche si k < 0, à droite si k > 0) diag ([2 4 7 3]) diag ([2 4 7 3] , -1) diag ([2 4 7 3] ,2) • rand : crée une matrice dont tous les éléments sont des valeurs aléatoires de loi uniforme entre 0 et 1. Deux scalaires aléatoires, un vecteur aléatoire et une matrice aléatoire rand () , rand () , rand (5 ,1) , rand (3 ,5) • size et length size(M,1) et size(M,2) permettent de connaitre respectivement le nombre de lignes et le nombre de colonne d’une matrice M. length(v) donne le nombre d’éléments d’un vecteur. v =1:8 , A = zeros (3 ,6) size (v ,1) , size (v ,2) , length ( v) size (A ,1) , size (A ,2) 13 • linspace linspace(xmin,xmax,n) : crée un vecteur-ligne de dimension n dont les valeurs sont réparties linéairement (uniformément) entre xmin et xmax. Par défaut n est égal à 100. linspace(xmin,xmax,n) est équivalent à xmin:(xmax-xmin)/(n-1):xmax linspace (0 ,99) linspace (0 ,2 ,5) linspace (3 ,8 ,11) linspace (10 ,0 ,21) Cette fonction est très utile lorsqu’on souhaite créer un certain nombre de valeurs de x équiréparties dans un intervalle puis évaluer une fonction y = f (x). calcul de 20 valeurs de y = cos(x) pour x ∈ [0, 2 π] M_PI = 3 . 1 4 1 5 9 2 6 5 35 897 932 38 462 643 x = linspace (0 ,2* pi ,20) , y = cos ( x ) • meshgrid : crée une grille de points rectangulaire à l’aide de valeurs de paramètres données par vecteurs. Cela permet de générer des ensembles de points (xi, yj ) ou (xi, yj , zk ) définis suivant une grille rectangulaire, qui peuvent être utilisés pour évaluer des fonctions à deux variables. évaluation de la fonction z = f (x, y) = x + y 2 sur [0, 2] × [1, 4] : [x , y ] = meshgrid (0:0.5:2 ,1:1:4) , z = x + y .^ 2 14 En utilisant uniquement les fonctions et opérations vues jusqu’à présent : (1) écrire les instructions pour construire les vecteurs suivants : u1 = (3 6 9 . . . 27 30) u2 = (−π/2 − π/4 0 π/4 π/2 . . . 11π/4 3π) u3 = (0 1 4 9 . . . 81 100) (2) écrire les instructions afin de construire la matrice carrée suivante de dimension n avec n un entier positif : 2 1 0 ... ... ... 0 .. 1 2 1 . . .. 0 1 ... ... . . . . . . . . . . 0 ... .. A= .. . . .. .. 1 0 . . .. 1 2 1 0 ... ... ... 0 1 2 (3) écrire les instructions afin de construire la matrice de Vandermonde de degré n (dimension n + 1) avec n un entier positif : 1 0 0 0 ... 0 1 1 1 1 ... 1 1 2 4 8 . . . 2n A = (Ai,j )1≤i,j≤n+1 = (i − 1)j−1 = n 1 3 9 27 . . . 3 .. .. .. .. .. . . . . . 2 3 1 n n n . . . nn (4) écrire les instructions pour calculer n! (n factoriel) et Cnk = n! k!(n − k)! et si possible de la manière la plus concise (penser à utiliser les opérations matricielles). 15 2.5 Programmation Matlab et Scilab dispose d’instructions similaires aux langages de programmation impérative. 2.5.1 Entrée-sortie La procédure disp permet d’écrire à l’écran la valeur d’une expression. x = 1:8; disp ( x ) disp (5*9) On peut aussi utiliser la procédure printf ou mprintf similaire à celle du langage C pour des valeurs simples. x =6; printf(" La racine carrée de %f est %f \ n " , x , sqrt ( x )); pour écrire les valeurs d’une matrice, il est possible d’utiliser un format s’appliquant à chaque ligne x =[1 2 3;4 5 6] mprintf( " %f %f %f \ n" , x ); // écriture de 3 colonnes v = (0:5) ’ mprintf( " %d \ n" , v ); // écriture sur une colonne 16 La procédure input(info) permet de lire à l’écran une valeur scalaire ou un tableau (utiliser la notation avec les crochets et points-virgules) et de le stocker dans la variable x. info représente une chaine de caractère qui est écrite avant que l’utilisateur entre la valeur de x. x = input ( " Entrez un vecteur - ligne : " ); printf(" Norme de x = %f \n " , norm ( x )) On peut aussi utiliser les procédures scanf similaires à celle du langage C. 2.5.2 Test – test à une alternative (si ... alors ...) : if condition liste instructions end – test à deux alternatives (si ... alors ... sinon ...) : if condition liste instructions else liste instructions end – tests en cascade (si ... alors ... sinon si ... alors ...) if condition1 liste instructions elseif condition2 liste instructions else ... end Les opérateurs de comparaison sont ceux utilisés en langage C (==, <=, >=, <, >) sauf pour ”différent de” qui se note ∼= (au lieu de != en C). Les opérateurs booléens sont &, |, ∼, respectivement pour l’opérateur ET, l’opérateur OU et l’opérateur NON. 17 quelques expressions booléennes x = 9 x < 8 ( x >= 0) & ( x < 10) ~( x == 7) x = input ( " Entrer un reel : " ); if x <0 y = -1; elseif x >0 y = 1; else y = 0; end printf(" Signe de x = %d \n " ,y ); Ce script lit une valeur x, calcule puis affiche son signe y. 2.5.3 Boucle conditionnelle La boucle conditionnelle est celle où le test est fait en premier (tant que ... faire ...) while test liste instructions end x = input ( " Entrer un reel : " ); while x >= 0 printf ( " Racine de x = %f \ n" , sqrt ( x )); x = input ( " Entrer un reel : " ); end 18 2.5.4 Boucle incrémentale La boucle incrémentale correspond à la boucle où on utilise un compteur de boucle (pour ... variant de ... à ...) for variable = valeur initiale:valeur finale liste instructions end Dans ce cas, la variable varie de la valeur initiale à la valeur finale avec un pas de 1. for variable = valeur initiale:pas:valeur finale liste instructions end Dans ce cas, la variable varie de la valeur initiale à la valeur finale avec le pas spécifié (non nul). création d’une matrice M de dimension 5 × 10 avec M(k,l)=k-l . M = zeros (5 ,10) // création de la matrice avec des valeurs nulles for k =1:5 for l =1:10 M (k , l )= k -l end end disp ( M ) La forme générale de l’instruction for ... end est : for variable = matrice liste instructions end Dans ce cas, la variable varie en prenant chaque valeur de la matrice. premiers = [2 3 5 7 11 13 17 19]; for i = premiers printf ( " %d est premier \ n " , i ); end l’instruction continue permet d’aller à la fin de la liste d’instructions d’une boucle for ou while, et l’instruction break permet de sortir d’une boucle for ou while. 19 (1) Ecrire un script qui teste si un entier entre 2 et 1000000 (choisi par l’utilisateur) est un nombre premier. (2) Ecrire un script qui effectue les actions suivantes – soit n un entier assez grand (par exemple n = 100000), – générer n valeurs x(i) aléatoires entre 0 et 1, – générer n valeurs y(i) aléatoires entre 0 et 1, – compter p le nombre de couples (x(i), y(i)) tel que x(i)2 + y(i)2 ≤ 1, – écrire la valeur 4p/n 20 2.5.5 Fonctions Il est possible d’écrire des procédures avec des paramètres d’entrées et/ou des paramètres de sorties. La syntaxe est la suivante : function [liste sorties]=nom (liste entrees) instructions endfunction avec : – nom : l’identificateur de la procédure, – liste entrees : la suite des paramètres d’entrée (séparés par des virgules). S’il n’y a pas de paramètres d’entrée, on peut ne pas mettre pas les parenthèses. – liste sorties : la suite des paramètres des sorties (séparés par des virgules). S’il n’y a pas de paramètres de sortie ou un seul paramètre de sortie, on peut ne pas mettre pas les crochets. La procédure suivante resol trinome calcule les racines de l’équation x2 + bx + c = 0 En entrée : b,c sont les coefficients du binome, et en sortie r1,r2 sont les deux racines function [ r1 , r2 ] = resol_trinome (b , c) delta = b *b -4* c ; r1 = ( -b - sqrt ( delta ))/2; r2 = ( -b + sqrt ( delta ))/2; endfunction [ r1 , r2 ] = resol_trinome (2 , -3) [ r1 , r2 ] = resol_trinome (2 ,1) [ r1 , r2 ] = resol_trinome (2 ,5) En Matlab, une fonction se termine avec le mot-clé end au lieu de endfunction 21 2.6 Graphique Les graphiques sont tracés dans des fenêtres graphiques qui sont séparées de la fenêtre de contrôle. Pour créer une fenêtre graphique, on peut utiliser la procédure figure ou scf . 2.6.1 Tracé de courbes La procédure plot permet de tracer des ensembles de points et des courbes. Si x et y sont deux vecteurs-lignes de même dimension, alors l’instruction plot(x,y) trace une courbe en reliant les points x(k),y(k) entre eux. tracé de la fonction y = cos(x) pour x compris entre 0 et 2π scf ; x = linspace (0 ,2* %pi ); y = cos ( x ); plot (x ,y ) tracé de la fonction y = 1/(1 + x2) pour x compris entre −3 et 3 avec 11 valeurs seulement. scf ; x = linspace ( -3 ,3 ,11); y = (1)./(1+ x .* x ); plot (x ,y ) 22 On peut obtenir différents types de tracé en ajoutant un troisième paramètre qui est une chaı̂ne de caractères permettant de définir des styles standard pour la couleur, le tracé des courbes et des points : Couleur r rouge c cyan g vert m magenta b bleu y jaune k noir w blanc Style de ligne continue : pointillé court -pointillé long -: pointillé long court Marqueur de point + plus x croix ^ triangle haut o rond s carré v tri. bas * astérisque d losange < tri. gauche . point p étoile > tri. droite scf ; plot (x ,y , ’k ’) scf ; plot (x ,y , ’o ’) Plusieurs tracés peuvent être faits dans la même fenêtre graphique en utilisant plusieurs instructions plot dans une même figure. Par défaut Scilab trace les différents graphiques les uns sur les autres, alors que Matlab efface le précédent pour tracer le nouveau. Pour que Matlab trace les différents graphiques les uns sur les autres, il faut utiliser l’instruction spécifique hold on figure; hold on plot (x ,y , ’g - - ’) plot (x ,y , ’ or ’) scf ; plot (x ,y , ’g - - ’) plot (x ,y , ’ or ’) 23 Lors d’un tracé si le vecteur des abscisses x est omis, alors les points tracés sont (k,y(k)). tracé des valeurs d’un tableau y scf () y = [45 66 32 33 50 75 47 51]; plot (y , ’o ’) On peut utiliser la fonction plot pour tracer des courbes paramètrées dans le plan. tracé d’une spirale t = linspace (0 ,30 ,500); x = t .* cos ( t ); y = t .* sin ( t ); scf (); plot (x ,y , ’r ’) 24 2.6.2 Surfaces La représentation d’une surface image d’une fonction z = f (x, y ou (x, y, z) = (f 1(u, v), f 2(u, v), f 3(u, v)) peut être faite en la discrétisant suivant un maillage rectangulaire : – on crée d’abord une grille rectangulaire pour les paramêtres à l’aide de la fonction meshgrid, – on calcule la surface en utilisant des fonctions avec opérations élément par élément, – et on utilise une procédure (par exemple mesh) pour une représentation graphique en 3D. la gaussienne pour x et y entre -2 et 2 [ XG , YG ] = meshgrid ( -2:0.1:2 , -2:0.1:2); ZG = exp ( - XG .^2 - YG .^2); scf ; mesh ( XG , YG , ZG ) la sphere unité paramétrée en longitude (u) et latitude (v) [u , v ] = meshgrid ( linspace (0 ,2* %pi ,50) , ... linspace ( - %pi /2 , %pi /2 ,25)); XS = cos ( u ) .* cos (v ); YS = sin ( u ) .* cos (v ); ZS = sin ( v ); scf ; mesh ( XS , YS , ZS ) la notation ... en fin de ligne permet d’écrire une seule instruction sur plusieurs lignes. tracé d’un tore de petit rayon r1 et grand rayon r2 [u , v ] = meshgrid ( linspace (0 ,2* %pi ,50) , ... linspace (0 ,2* %pi ,25)); r1 = 1; r2 = 2; XT = cos ( u ) .* ( r2 + r1 * cos ( v )); YT = sin ( u ) .* ( r2 + r1 * cos ( v )); ZT = r1 * sin ( v ); scf ; mesh ( XT , YT , ZT ) 25 (1) Ecrire un script avec les fonctionnalités suivantes : – définition d’une fonction Bin (x) = B(n, i, x) à trois variables (n, i, x) avec i et n deux entiers tels que 0 ≤ i ≤ n et x réel (ou tableau de réels) tel que Bin (x) = n! xi(1 − x)n−i i!(n − i)! – calcul et tracé des n + 1 fonctions y = Bin (x), 0 ≤ i ≤ n avec n un entier entre 0 et 100 choisi par l’utilisateur et x variant entre 0 et 1 (2) Ecrire un script avec les fonctionnalités suivantes : – définition d’une fonction x = f (u, v) calculant x par la formule p x = −2 log u cos(2πv) – – – – – – où u et v sont deux valeurs entre 0 et 1. choix par l’utilisateur d’un entier n entre 1000 et 100000 calcul de n valeurs ai aléatoires de loi uniforme entre 0 et 1. calcul de n valeurs bi aléatoires de loi uniforme entre 0 et 1. calcul de n valeurs x(i) = f (ai, bi) avec ai et bi . pour tout entier j entre 1 et 40, calculer p(j) le nombre de valeurs x(i) comprise entre (j − 21)/10 et (j − 20)/10 tracé graphique des couples j, p(j) 26 Chapitre 3 Utilisation avancée 3.1 3.1.1 Type structuré Hyper-matrice Une hyper-matrice est un tableau dont le nombre de dimensions est supérieure à deux. Cela peut servir pour évaluer une fonction à plusieurs variables. A = rand (2 ,3 ,4) size ( A ) B = zeros (2 ,4 ,2 ,3) B (1 ,2 ,2 ,1)=4 3.1.2 Matrice creuse (sparse matrix) Une matrice creuse est une matrice (de grande taille) dont la proportion d’éléments non nuls (on parle de matrice creuse quand le nombre d’éléments non nuls est du même ordre que la dimension de la matrice). Les matrices creuses apparaissent dans de nombreux problèmes (calcul numérique, gestion de graphes, . . .) Pour des raisons de taille mémoire, il n’est parfois pas possible de manipuler des matrices sous forme de tableau bi-dimensionnel (une matrice carrée réelle de dimension 10000 nécessite une place mémoire de 800 Mo), si celle-ci est creuse, on préfère la stocker sous forme sparse, c’est à dire sous forme d’une liste correspondant aux éléments non nuls de la matrice, chaque élément de la liste étant le couple d’indices (i, j) associé à la valeur non nulle. La création d’une matrice creuse se fait à l’aide de la procédure sparse 27 0 0 7 0 La matrice A = 0 0 0 6 9 0 −2 0 // matrice creuse nulle de // dimensions 3 par 4 A = sparse ([] ,[] ,[3 ,4]) // affecter les valeurs // non nulles A (1 ,3)=7; A (2 ,4)=6; A (3 ,1)=9; A (3 ,3)= -2; // afficher de deux manieres A full ( A ) 3.1.3 Fonction Il est possible de définir des variables de type fonction pour utiliser par exemple une procédure comme paramètre d’une autre procédure. Définitions de la variable g correspondant à la fonction prédéfinie t 7→ sin(t) et de la variable h correspondant à la nouvelle fonction t 7→ 1/(1 + t2 ) et on utilise alors la procédure deff . g = sin deff ( " y= h ( t ) " , " y = (1)./(1+ t .^2) " ) Ensuite une variable fonction peut être utilisée comme paramètre d’une autre fonction. La fonction plotf trace la fonction y=f(x) pour x entre 0 et 1. function plotf ( f ) t = linspace (0 ,1 ,1000); scf ; plot (t , f (t )) endfunction plotf ( g) , plotf ( h ) 28 3.1.4 Tableau de cellules Un tableau de cellules est un tableau (vecteur ou matrice) dont chaque élément est de type quelconque. On accède aux différents éléments d’un tableau de cellules comme pour un tableau normal. Cependant en Scilab l’affectation à une cellule se fait à l’aide du champ entries A = cell (2 ,3) A (1 ,1). entries = 2 A (1 ,3). entries = [2 3] A (2 ,2). entries = ’ texte ’ A (1 ,1) A (2 ,2) 3.1.5 Structure Une structure est une variable avec plusieurs champs de type quelconque. s1 = struct( " Nom " ," Dupond " ," Prenom" ," Jean " ," Age " ,58) s2 = struct( " Nom " ," Martin " ," Prenom" ," Anne " ) s1 . Nom s2 . Age = 25 3.2 Entrée/Sortie 3.2.1 Clavier / Ecran Pour lire des données au clavier, on peut utiliser la procédure input. Lecture d’un nombre, d’une chaı̂ne de caractères et d’un tableau. La chaı̂ne de caractères doit être entrée entre quotes ’ (ou double-quotes " en Scilab) et la matrice entre crochets avec des points-virgules pour le passage à la ligne suivante n = input ( " Entrer un nombre entre 1 et 20 : " ) nom = input ( " Entrer un nom de pays : " ," s ") A = input ( " Entrer une matrice 2 x 2 : " ) 29 Pour écrire des résultats à l’écran, on peut utiliser la procédure disp ou bien la procédure mprintf reprenant la syntaxe de la procédure standard du langage C. n = input ( " Entrer un nombre entre 1 et 20 : " ); mprintf( " La valeur entrée est %d \ n " , n ) A = [11 4;21 25;37 6]; disp ( A ) printf(" La matrice A est égale à :\ n" ) printf(" | %2d %2d |\ n " , A ) Pour ecrire l’ensemble d’une matrice en une seule instruction, il suffit de spécifier un format correspondant à une ligne de la matrice (dans l’exemple ci-dessus deux entiers écrits chacun sur 2 caractères). 3.2.2 Fichier texte Pour les entrées/sorties sur fichier de type texte, le plus simple est d’utiliser les procédures mfscanf et mfprintf similaires aux procédures du langage C. En Scilab, l’ouverture (resp. la fermeture) d’un fichier se fait à l’aide de la procédure mopen (resp. mclose ). Ecriture d’une matrice dans un fichier texte : on écrit sur la première ligne le nombre de ligne et le nombre de colonnes, puis les valeurs de la matrice sur les lignes suivantes // matrice de valeurs aléatoires A = rand (10 ,2); // ouverture du fichier f = mopen ( " matrice . txt " ," w " ); nl = size (A ,1); nc = size (A ,2); // ecriture des dimensions mfprintf (f , " %d %d \n " , nl , nc ); // ecriture de la matrice for i =1: nl for j =1: nc mfprintf (f , " %f " , A (i , j )); end mfprintf (f ," \ n " ); end // fermeture du fichier mclose(f ); On vérifiera avec un éditeur de texte que le fichier matrice.txt a bien été créé. 30 La lecture d’un fichier texte se fait à l’aide de la procédure mfscanf similaire à celle du langage C. Ecrire une procédure dont l’en-tête est M = lire matrice(nom fichier) avec en entrée une chaı̂ne de caractère contenant le nom du fichier à lire, et en sortie la matrice lue. La tester avec différentes matrices. 3.2.3 Fichier binaire Scilab fournit les procédures mget et mput similaires aux procédures fread et fwrite du langage C. 3.3 Programmation avancée 3.3.1 Variables locales et globales Les variables utilisées en Matlab et Scilab sont stockées en mémoire. Il est possible de connaı̂tre les variables définies par l’utilisateur grâce aux instructions who (mode abrégé) et whos (mode détaillé). La procédure clear permet d’effacer de la mémoire certaines variables ou toutes. Exécutez les instructions suivantes une par une whos zthq zthq = 30; zthq zthq = rand (10 ,2); zthq clear zthq zthq clear whos 31 Par défaut, les variables utilisées dans les procédures sont locales à celle (leur portée est limitée au corps de la procédure). Pour utiliser une même variable dans plusieurs procédures, il est nécessaire de les déclarer avec l’instruction global La variable a est une variable globale aux procédures init et f. La variable b est une variable globale aux procédures init et g. function init () global a b a = 2; b = 4; endfunction function f () global a a = a +1; b = 0; printf( " f () : a = %d , b = %d \ n " , a , b ); endfunction function g () global b b = b +3; a = 0; printf( " g () : a = %d , b = %d \ n " , a , b ); endfunction init (); f (); f (); g (); g (); 32 3.3.2 Utilisation de plusieurs procédures Il est possible de déclarer plusieurs procédures à la suite. Alors que Scilab permet la déclaration de procédures locales à l’intérieur d’autres procédures, Matlab ne le permet pas, et les procédures doivent être déclarées au même niveau les unes à la suite des autres. La gestion des fonctions définies sous forme de fichiers externes diffère entre Matlab et Scilab. En Scilab toutes les fonctions définies dans un fichier source peuvent être utilisées par l’utilisateur À CONDITION que le fichier ait été chargé au préalable à l’aide de la procédure exec En Matlab, si plusieurs fonctions sont définies dans un fichier source, seule la première fonction sera utilisable et son identificateur correspondra au nom du fichier sans l’extension .m En Scilab, un fichier source peut contenir plusieurs fonctions. Pour charger un fichier source et avoir accès à l’ensemble de ses fonctions, on peut utiliser la procédure exec. Pour charger tous les fichiers sources d’un répertoire, on utilise la procédure getd. 3.3.3 Récursivité Il est possible d’écrire des fonctions récursives. La fonction ”factorielle” Définir la fonction suivante function p = fact ( n ) if n <1 p =1; else p = n* fact (n -1); end endfunction puis appeler la fonction for i =0:10 printf( " %d ! = %d \n " , i , fact ( i )); end 33 3.3.4 Test des arguments d’une fonction Les variables n’étant pas explicitement typées, il est conseillé de tester leur type et éventuellement leur dimension notamment lorsqu’elles sont des paramètres d’une fonction. On peut aussi initialiser des arguments par défaut s’ils ne sont pas fournis. Définir la fonction resol trinome ci-dessous qui calcule les deux racines de l’équation x + bx + c = 0 2 function [ r1 , r2 ] = resol_trinome (b , c) delta = sqrt ( b .* b -4* c ); r1 = (b - delta )/2; r2 = ( b + delta )/2; endfunction La fonction telle qu’elle est définie nécessite deux paramètres scalaires en entrée et renvoie deux valeurs en sortie. Si le nombre d’arguments en entrée et/ou en sortie est incorrect, si un argument en entrée est incorrect, une erreur se produira. Par exemple, exécuter les instructions suivantes. [ r1 , r2 ] = resol_trinome (1) // erreur car le deuxième parametre est manquant r1 = resol_trinome (1 , -2) // ne donne que la première racine [ r1 , r2 ] = resol_trinome (1 , " -2 ") // le deuxieme argument n ’ est pas numérique [ r1 , r2 , r3 ] = resol_trinome (1 , -2) // erreur car trop d ’ argument en sortie 34 On peut alors complèter la fonction resol trinome afin de tester les arguments : // resol_trinome : résolution de l ’ équation x*x+b*x+c = 0 // syntaxe [r1 , r2 ] = resol_trinome (b ,c) // Entrées : b ,c = coefficients du binome ( par défaut b=c =0) // Sorties : r1 , r2 = les deux racines function [ r1 , r2 ] = resol_trinome (b , c) // test des arguments lors de l ’ appel nargout = argn (1); // nombre d ’ arguments en sortie nargin = argn (2); // nombre d ’ arguments en entrée if nargin >2 error ( " il faut ( au plus ) deux arguments en entrée" ) end if nargout ~=2 error ( " il faut deux arguments en sortie" ) end // // if if affecter des valeurs par défaut en entrée si les arguments n ’ ont pas été fournis nargin <1 then b =0; end nargin <2 then c =0; end // tester le type des arguments en if ~(... type ( b )==1 & ... // test si b type ( c )==1 & ... // test si c length( b )==1 & ... // test si b length( c )==1 ... // test si c ) error ( " les arguments en entrée end // les instructions de la fonction delta = sqrt (b *b -4* c ); r1 = ( -b - delta )/2; r2 = ( -b + delta )/2; endfunction 35 entrée est est est est de de un un type numérique type numérique scalaire scalaire doivent etre scalaires " ) puis tester les différents instructions suivantes : resol_trinome (1 ,2) [ r1 , r2 , r3 ] = resol_trinome (1 ,2) [ r1 , r2 ] = resol_trinome ([1 ,2] ," 3 " ) [ r1 , r2 ] = resol_trinome () [ r1 , r2 ] = resol_trinome (3) Il est possible de créer des procédures avec un nombre quelconque d’argument (comme la procédure printf). Dans ce cas, dans la déclaration de la procédure, on utilisera la variable prédéfinie varargin qui sera une liste d’arguments quelconque. function f ( varargin ) nargin = length( varargin ); mprintf( " La fonction f est appelee avec %d argument ( s )\ n " , ... nargin) for i =1: nargin mprintf ( " Argument %i : " , i ); disp ( varargin ( i )) end endfunction 36 (1) Ecrire une procédure dont l’en-tête est function r=factorial(n) qui calcule n! (n entier avec la convention habituelle n! = 1 si n ≤ 0) et une deuxième procédure dont l’en-tête est function r=nchoosek(n,k) qui calcule Cnk = n!/(k!(n−k)!) (n et k entiers avec la convention Cnk = 0 si n < 0 ou k < 0 ou k > n). (2) Ecrire une procédure qui calcule numériquement l’integrale d’une fonction f sur un intervalle [a, b] par la méthode de Simpson : h f (a) + 4f (a + h/2) + 2f (a + h) + 4f (a + 3h/2) + . . . 6 +4f (b − 3h/2) + 2f (b − h) + 4f (b − h/2) + f (b) " # Z n n−1 b X X h = f (a) + 4 f (a + (2i − 1)h/2) + 2 f (a + ih) + f (b) ≃ f (x)dx 6 a i=1 i=1 I= avec n un entier > 0, et h = (b − a)/n. La procédure doit avoir 4 paramètres en entrée : a et b (réels) les bornes de l’intervalle, f une variable fonction (de la forme y = f (x)) et n entier pair, et un paramètre en sortie : la valeur I. (3) Ecrire une procédure qui évalue la valeur d’un polynôme de degré n p(t) = cn tn + cn−1 tn−1 + · · · + c1 t + c0 par le schéma de Horner : p(t) = . . . (cn × t + cn−1 ) × t + cn−1 × t + · · · + c1 × t + c0 La procédure doit avoir 2 paramètres en entrée : C le vecteur des coefficients (de longueur n + 1 : C(i + 1) = ci ) et t un réel, vecteur ou matrice (dans le cas d’un vecteur ou matrice, le polynôme doit être évalué en chaque valeur de t) et un paramètre en sortie : la valeur pt (de même dimension que t), évaluation du polynome en t. 37 3.4 3.4.1 Graphique avancé Tracé multiple dans une fenêtre Il est possible dans une même fenêtre de tracer plusieurs graphiques, chacun avec son propre repère. Pour cela, utiliser la procédure subplot(nl,nc,num) pour tracer dans une partie de la fenêtre. Tracé des fonctions fk (t) = exp(−t2)cos(2k t) pour 1 ≤ k ≤ 6 et −pi ≤ t ≤ pi M_PI = 3 . 1 4 1 5 9 2 6 5 35 89 793 23 846 264 3; t = linspace ( - M_PI , M_PI , 1000); figure (); for k =1:6 y = exp ( - t .^2).* cos (2^ k * t ); subplot (2 ,3 ,k ) plot (t , y ); end 3.4.2 Couleurs et plus encore . . . La procédure plot permet de tracer des courbes ou points avec 8 couleurs de base possibles à l’aide des caractères krgbcmyw . Il est possible de définir d’autres couleurs en spécifiant la couleur à l’aide de l’option Color et en précisant une couleur au format RGB (triplet de 3 valeurs entre 0 et 1) Tracé des fonctions fk (t) = exp(−t2)cos(2k t) pour 1 ≤ k ≤ 6 et −pi ≤ t ≤ pi avec differentes couleurs t = linspace ( - %pi , %pi , 1000); scf ; for k =1:6 y = exp ( - t .^2).* cos (2^ k * t ); subplot (2 ,3 ,k ) plot (t ,y , " Color " ,[k /6 ,1 ,1 -k /6]); end D’autres attributs (épaisseur, style de tracé, . . .) peuvent être personnalisés. 38 3.4.3 Objets graphiques Tout tracé graphique génère un certain nombre d’objets suivant la hiérarchie suivant : – chaque appel à la procédure scf (ou figure ) crée un objet de type figure – chaque repère dans une figure correspond à un objet de type axes – chaque tracé dans un repère crée un objet graphique particulier Chaque type d’objet graphique possède ses propres champs auxquels il est possible d’accèder et les modifier éventuellement. Figures Chaque appel à la procédure scf crée un nouvel objet SCILAB de type figure qui apparait sous forme d’une fenêtre graphique séparée. Création de 3 graphiques t = linspace (0 ,2* %pi ,1000); f1 = scf (); plot (t , cos ( t ) ," r " ); f2 = scf (); plot (t , sin ( t ) ," k " ); Il est alors possible de tracer dans une fenêtre graphique déjà créée en l’indiquant comme argument de la procédure scf Tracé des fonctions y = cos(2t) et y = cos(3t) dans la figure f1 scf ( f1 ); plot (t , cos (2* t ) , " b " ); plot (t , cos (3* t ) , " m " ); Les différents champs d’un objet graphique sont visibles en utilisant par exemple la procédure disp disp ( f1 ); On peut alors modifier un champ de l’objet en changeant sa valeur. Modifier le nom, la taille de la fenêtre et sa couleur de fond. f1 . figure_name = " Graphique %d " ; f1 . figure_size = [500 ,400]; f1 . background = 7; 39 Certains champs sont parfois liés entre eux. Modifier la taille de la fenêtre en utilisant le champ axes size disp ( f1 . figure_size ); disp ( f1 . axes_size ); f1 . axes_size = [500 ,400]; disp ( f1 . figure_size ); disp ( f1 . axes_size ); Une figure peut être fermée en utilisant la procédure close ou xdel close ( f1 ) Axes Les axes (ou repères) sont les objets-fils des figures. Par défaut, chaque figure contient un axe. L’instruction sublot crée plusieurs axes dans une figure. La structure correspondante peut être obtenue avec la procédure gca() ou bien le champ children d’un objet fenêtre. tracé d’un cercle f = scf (); t = linspace (0 ,2* M_PI ,1000); x = cos ( t ); y = sin ( t ); plot (x ,y ); Il est probable que la figure soit une ellipse et non un cercle. En effet, par défaut l’axe se positionne par rapport aux dimensions de la figure, et les bornes du repère correspondent aux bornes des vecteurs x et y. On peut alors récupérer la structure de l’axe : a = gca (); // l ’ axe courant puis modifier certaines propriétés (exécuter les instructions une par une pour voir les modifications correspondantes). – avoir un repère isométrique (même échelle) : champs isoview et cube scaling a . isoview = " on " ; a . cube_scaling = " off " ; – changer les bornes du repère : champ data bounds = [xmin,ymin;xmax,ymax] a . tight_limits = " on " ; a . data_bounds =[ -1.2 , -1.1;1.2 ,1.1]; 40 – modifier la position de l’axe dans la figure : champ margins = [gauche, droite, haut, bas] exprimé en proportion par rapport aux dimensions de la figure a . margins = [0.55 ,0.05 ,0.2 ,0.4]; – ajouter un titre : champ title qui est un objet de type Label a . title . text = " Cercle " ; On peut aussi ajouter des axes supplémentaires à une figure, pour avoir des tracés séparés dans une même fenêtre. ajout d’un axe et tracé d’une spirale. a2 = newaxes (); // créer un nouvel objet axe sca ( a2 ); // et en faire l ’ axe courant plot ( t .* cos ( t *5) , t .* sin (t *5) , ’r ’ ); a2 . isoview = " on " ; a2 . cube_scaling = " off " ; a2 . title . text = " Spirale " ; a2 . margins = [0.05 ,0.55 ,0.2 ,0.4]; le menu Edit d’une fenêtre graphique permet de d’ouvrir un dialogue afin d’éditer les objets de la fenêtre. 41 3.4.4 Tracés Tout tracé dans un axe crée un objet graphique qui peut être alors modifié. un objet de type Polyline. scf (); a = gca (); t =0:9; x = cos (t * %pi /5); y= sin ( t* %pi /5); plot (x ,y , ’r - ’); set (a , " isoview " ," on " ); set (a , " cube_scaling " ," off " ); set (a , " auto_scale " ," off " ); on peut accéder ou modifier les champs d’une structure avec les procédures get et set On récupère l’objet correspondant au tracé (ici une Polyline) c = get (a , " children " ); // objet Composite p = get (c , " children " ); // objet Polyline On peut ensuite modifier les champs de l’objet Polyline p (exécuter les instructions une par une) // fermer le polygone set (p , " closed" ," on " ); // tracer en pointillé set (p , " line_style " ,2); // ajouter une marque pour chaque sommet set (p , " mark_mode " ," on " ); set (p , " mark_style " ,3); set (p , " mark_size " ,6); // modifier un point p . data (1 ,:) = [0 ,0]; 42 un objet de type Surface [x , y ] = meshgrid ( -2:0.1:2 , -2:0.1:2); z = exp ( -x .^2 -3* y .^2); f = scf (); // la figure a =f . children ; // l ’ axe correspondant f . color_map = jetcolormap (256); // changer la table de couleurs surf (x ,y , z ); set (a , " isoview " ," on " ); set (a , " cube_scaling " , " off " ); On peut alors récupérer l’objet s correspondant au tracé de la surface, et modifier certains de ses champs (exécuter les instructions une par une) // objet correspondant à la surface s =a . children ; // aretes non visibles s . color_mode = -1; // interpolation des couleurs pour chaque face s . color_flag =3; // une couleur par face s . color_flag =2; // aretes visibles s . color_mode =2; // mode filaire s . color_mode =0; 3.4.5 Impression/Sauvegarde d’un graphique Le menu File d’une figure permet des opérations de chargement/sauvegarde : – Print : impression – Export : sauvegarde sous forme d’un fichier image. Différents formats sont disponibles, les formats GIF ou EPS sont recommandés pour l’importation ultérieure dans un logiciel de traitement de texte. – Save/Load : sauvegarde/chargement au format SCILAB 43 Ecrire un script qui trace sur un même graphe les différentes fonctions (fk ) avec k entier entre 0 et 10 tel que : f0(t) = 1 fk (t) = fk−1(t) + (−1)k t2k (2k)! on prendra t ∈ [−2π, 2π], et on fixera les bornes de l’axe à [−2, 2] pour les ordonnées. On fera en sorte de tracer les différentes courbes avec différentes couleurs. 44 3.5 Interaction avec la souris La procédure xclick suspend l’exécution d’instructions jusqu’à ce que l’utilisateur clique dans une fenêtre graphique. Cette procédure permet notamment de récupérer la position d’un point dans une fenêtre (par rapport à l’axe courant) la procédure suivante permet de sélectionner un ensemble de points dans une nouvelle fenêtre. // selectionne à la souris une suite de points // dans la fenetre f // syntaxe : [x ,y] = input_poly (f) // avec f = identificateur d ’ une fenetre // si f n ’ est pas fourni , // une nouvelle fenetre est créée // x ,y = vecteurs - lignes des abscisses // et ordonnées des points // cliquer chaque point avec le bouton gauche et // le dernier avec le bouton droite function [x , y] = inputpoly ( f ) if argn (2)==0 f = scf (); else scf ( f ); end a = gca (); // figer les axes a . auto_scale = " off "; // les afficher a . axes_visible = [ " on " ," on " ," on " ]; // ainsi que le rectangle englobant a . box = " on " ; // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ // suite sur la page suivante // @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 45 // initialiser les tableaux x et y x = []; y = []; entree = 1; while entree ==1 [ c_i , c_x , c_y ]= xclick (); if c_i ==0 | c_i ==2 | c_i ==3 | c_i ==5 // évènement click souris plot ( c_x , c_y , " ro " ); x = [ x c_x ]; y = [ y c_y ]; if c_i ==2 | c_i ==5 // click souris droit : fin de la boucle entree =0; end end end endfunction le script suivant permet de saisir à la souris les sommets d’un polygone puis d’en tracer le contour. [x , y ] = inputpoly (); plot ([ x x (1)] ,[ y y (1)] , "b " ); (1) Ecrire un script SCILAB permettant : a) d’acquérir à la souris un ensemble de n + 1 points Pi = (xi, yi) avec 1 ≤ i ≤ n + 1, b) de tracer le polygone ouvert [P1 , P2 , . . . , Pn , Pn+1], c) et la courbe de Bézier correspondante : B = {M(t) = n X i=0 (n) Pi+1Bi (t), t ∈ [0, 1]} 46 (n) avec Bi (t) = n! ti (1 − t)n−i i!(n − i)! 3.6 Interfaçage avec un langage de programmation Scilab étant un langage interprèté, il peut en découler une certaine lenteur à l’exécution. Il est possible d’utiliser des procédures compilées en langage Fortran ou C afin d’accélérer certaines opérations. le script suivant implémente en SCILAB le tri par insertion d’un tableau. // la procédure SCILAB // Entree : T = une tableau de réels // Sortie : TT = le tableau trié par ordre croissant function TT = tri_insertion ( T ) n = length( T ); // nombre de valeurs à trier TT = zeros ( T ); // l ’ algorithme de tri par insertion for i =1: n v = T( i ); j = i ; boucle = %t ; while boucle & j >1 if TT (j -1) > v then // décaler la valeur TT (j -1) TT (j ) = TT (j -1); j = j -1; else boucle = %f ; end end // inserer la valeur v dans TT à l ’ indice j TT ( j ) = v ; end endfunction // générer un tableau de n valeurs aléatoires entre 0 et 100 n = 2000; T = round ( rand (1 , n )*100); // utiliser la procédure Scilab et mesurer le temps CPU mprintf( " Tri en utilisant la procédure Scilab \ n" ) timer (); TTrieS = tri_insertion ( T ); cpu_time = timer (); mprintf( " Temps utilisé : %f \ n \n " , cpu_time ); En exécutant ce script avec n=1000 valeurs, le temps CPU est de quelques secondes. 47 On peut écrire le fichier tri insertion.c contenant une procédure tri insertion en langage C : /* la procédure trie le tableau T de n valeurs en le tableau TT trié par ordre croissant Entrée : T = tableau de double n = pointeur sur un entier TT = tableau de double Sortie : TT = le tableau T trié */ void tri_insertion ( double T [] , int *n , double TT []) { int i ,j , boucle ; double v ; /* l ’ algorithme de tri par insertion */ for ( i =0; i <* n ; i ++) { v = T[ i ]; j = i; boucle = 1; while ( boucle && j >0) { if ( TT [j -1] > v ) { /* decaler la valeur TT (j -1) */ TT [j ] = TT [j -1]; j = j -1; } else boucle = 0; } /* inserer la valeur v dans TT à l ’ indice j */ TT [ j ] = v ; } } Tous les paramètres de la procédure C doivent être pointeur (ou tableau) d’un type scalaire (float, double, int ou char). 48 Pour utiliser cette procédure C dans SCILAB, il faut la compiler et la charger. // créer la librairie à partir du source en langage C ilib_for_link ( ’ tri_insertion ’ ,’ tri_insertion . c ’ ,[] , " c" ) // charger la librairie exec loader . sce puis l’utiliser à l’aide de la procédure SCILAB call : mprintf( " Tri en utilisant la procédure C \ n" ) timer (); TTrieC = call ( " tri_insertion " , T ,1 , "d " , n ,2 , " i " , ... " out " ,[1 , n ] ,3 , " d" ); cpu_time = timer (); mprintf( " Temps utilisé : %f \ n \n " , cpu_time ); Les arguments de la procédure call sont : – une chaı̂ne de caractères correspondant au nom de la procédure C – suivie de triplets, chaque triplet correspondant aux paramètres en entrée de la procédure C : – l’identificateur de la variable SCILAB, – la position correspondante dans la liste d’arguments de la procédure C – le type ("r" pour float, "d" pour double, "i" pour int, "c" pour char) Dans notre cas, la variable T tableau de réels en double précision est passée comme argument 1 de la procédure tri insertion et la variable n entier est passée comme argument 2. – suivis de la chaı̂ne "out" et de triplets pour les paramètres de sortie, chaque triplet étant composé : – la taille du paramètre en sortie, – la position correspondante dans la liste d’arguments de la procédure C – le type ("r" pour float, "d" pour double, "i" pour int, "c" pour char) Dans notre cas, il faut récupèrer le tableau trié TTrieS de dimensions 1 × n correspondant à l’argument 3 de la procédure tri insertion. Il est possible d’écrire directement en langage C une procédure d’interface avec SCILAB afin d’utiliser les procédures plus simplement sans passer par la procédure call (voir la procédure SCILAB ilib build). 49