next up previous contents
suivant: Programmation monter: intsci précédent: Prise en main   Table des matières

Sous-sections

Variables et types de variables

Ce chapitre est sûrement la partie la plus fondamentale que tout utilisateur de Scilab doit maîtriser. Il définit les opérations de création et de manipulation d'objets multi-indicés que peuvent être les matrices (de réels, booléens ...).

Variable

Définition

Le signe ``='' est le signe d'affectation pour une variable. L'affectation n'est pas explicitement déclarée au préalable (par son type et/ou sa taille) mais déterminée à l'écriture :
-->A=[1 2 ; 3 4]
 A  =
 
!   1.    2. !
!   3.    4. !



Remarque 1: Les variables sont formées d'une chaîne alphanumérique commençant par une lettre (mais aussi % $ ? #) de 24 caractères (au delà ils ne sont pas pris en compte).

Remarque 2: Il n'est pas possible de réaffecter des variables pré-définies ainsi que les fonctions primitives2.1.

-->%e=1
     !--error    13 
redefining permanent variable
-->exp=2e-3
  !--error    25 
bad call to primitive :exp

Une fois la variable définie pour voir son contenu il suffit de taper son nom et de valider :

-->A
 A  =
 
!   1.    2. !
!   3.    4. !



Remarque 3: Lors de l'exécution d'une commande apparaît la réponse ans, c'est une variable qui peut être réaffectée.

-->[2 3]
 ans  =
 
!   2.    3. !
 
-->B=ans
 B  =
 
!   2.    3. !



Remarque 4: Si une variable existe et contient par exemple une matrice, l'affectation de cette variable à une autre quantité (pas forcément de même type) n'engendre pas de message d'erreur ni avertissement.

Gestion

Il existe une commande qui permet de tester si une variable existe déjà
-->isdef('A')
 ans  =
 
  T
noter le passage en argument entre apostrophes (chaîne de caractères) et la réponse sous forme de booléen. Une alternative est l'utilisation de
-->exists('A')
 ans  =
 
    1.
avec la réponse qui vaut 0 ou 1 (faux vrai).

Scilab fournit des commandes utiles pour gérer les variables on peut citer

-->who
your variables are...
 
 A         ans       startup   ierr      MODE_X    scicos_pal          
 %helps    MSDOS     home      PWD       TMPDIR    plotlib   
 percentlib          soundlib  xdesslib  utillib   tdcslib   siglib    
 s2flib    roblib    optlib    metalib   elemlib   commlib   polylib   
 autolib   armalib   alglib    intlib    mtlblib   SCI       %F        
 %T        %z        %s        %nan      %inf      old       
 newstacksize        $         %t        %f        %eps      %io       
 %i        %e        
 using       5288 elements  out of    1000000.
          and         47 variables out of       1791

La fonction who renvoie la liste des variables (on retrouve quelques connaissances ``A'', ``%i'', ``%e'' et ``%eps''), des informations sur la place mémoire occupée et restante en nombre de mots (1 mot = 1 nombre double précision), et en dernière ligne le nombre de variables utilisées et disponibles (total).

Les commande whos(), whos -name 'début du(des) nom(s) de variable(s)', whos -type 'type de variable' renvoient des informations plus détaillées sur la taille des variables.

-->whos -name %
Name                     Type           Size           Bytes        
%F                       boolean        1 by 1         24           
%T                       boolean        1 by 1         24           
%z                       polynomial     1 by 1         56           
%s                       polynomial     1 by 1         56           
%nan                     constant       1 by 1         24           
%inf                     constant       1 by 1         24           
%t                       boolean        1 by 1         24           
%f                       boolean        1 by 1         24           
%eps                     constant       1 by 1         24           
%io                      constant       1 by 2         32           
%i                       constant       1 by 1         32  

 -->whos -type boolean
Name                     Type           Size           Bytes        
 
MSDOS                    boolean        1 by 1         24           
%F                       boolean        1 by 1         24           
%T                       boolean        1 by 1         24           
%t                       boolean        1 by 1         24           
%f                       boolean        1 by 1         24   

Une fonction très utile sur les matrices, et donc sur les variables est la fonction size. Notez que Scilab peut faire des matrices de presque tout !

-->size(A)
 ans  =
 
!   2.    2. !
size renvoie le nombre de lignes et colonnes.



\bgroup\color{black}\framebox{\textbf{A faire :}}\egroup size(2). Alors ? Regarder également: length(A), typeof(A), a=2*A.

Suppression

Il est possible de supprimer une variable de l'environnement par la commande :
-->clear A
ou
-->clear
qui cette fois supprime toutes les variables non protégées.

Nous préciserons ultérieurement l'existence de variables locale et globale avec leurs utilisations et propriétés respectives.

Tableaux

On parlera de tableaux au lieu de vecteurs colonne ou ligne.

Génération

La génération de tableaux (ou vecteurs) peut se faire ``manuellement'' par une expression de la forme vue précédemment
-->A=[1 2 3 4 5],B=[0 2 4 6 8 10],D=[]
avec des espaces (ou virgules) séparant les éléments pour une écriture ligne et de points virgules pour une écriture colonne. Il est possible d'avoir un tableau vide (D).

Une syntaxe plus adaptée à la création des tableaux A et B et la suivante

-->A=1:5,B=0:2:10
 A  =
 
!   1.    2.    3.    4.    5. !
 B  =
 
!   0.    2.    4.    6.    8.    10. !
Autrement dit
début : borne supérieure
pour avoir un incrément automatique de 1 entre début et borne supérieure, ou alors
début : incrément : borne supérieure
pour spécifier l'incrément.

Attention cette dernière commande possède deux comportements à connaître , le premier est

-->2:1
 ans  =
 
     []
où la réponse est le tableau vide. Le second
-->1:1.1:4
 ans  =
 
!   1.    2.1    3.2 !
on voit ici que la dernière valeur est celle qui est inférieure à la borne indiquée. Cette dernière spécification peut engendrée des difficultés par exemple
-->0:1/3:1
 ans  =
 
!   0.    0.3333333    0.6666667    1. !
tandis que
-->0:1/3+2*%eps:1
 ans  =
 
!   0.    0.3333333    0.6666667 !

Pour palier à cette particularité il existe la commande linspace

-->linspace(0,1,4)
 ans  =
 
!   0.    0.3333333    0.6666667    1. !
qui s'emploie sous la forme linspace(début,fin,nombre de valeurs). Cette fois le tableau résultat contient forcément les valeurs limites.

Voir également logspace(début,fin,nombre de valeurs)2.2.

Extraction et affectation

Bien sûr, avoir des tableaux sans la possibilité d'accéder aux valeurs ne serait pas du plus grand intérêt. On a vu l'usage des crochets [ et ] pour la création de tableaux, on utilisera pour l'extraction les parenthèses ( et ) exemples :
-->t=1:5;
-->t(1),t(4)
 ans  =
 
    1.  
 ans  =
 
    4.
L'accès aux éléments se fait donc simplement et naturellement, noter que les indices commencent à 1 (héritage du fortran).

Ces accès aux éléments du tableau permettent également d'affecter (tout ou) une partie du tableau :

-->t(1)=5
 t  =
 
!   5.    2.    3.    4.    5. !

L'extraction et l'affectation jouent un rôle identique le tout étant de pointer sur le(s) élément(s) choisi(s).

-->t(1)=t(5)
 t  =
 
!   5.    2.    3.    4.    5. !

Nous avons déjà utilisé la fonction size, pour les tableaux la fonction length parait plus judicieuse, renvoyant la longueur totale de l'objet (même pour une matrice).

-->length(t)
 ans  =
 
    5.

Néanmoins il existe une petite astuce pour atteindre le dernier élément d'un tableau, c'est l'utilisation dans l'expression de $ :

-->t($)
 ans  =
 
    5.

Nous avons ici les fonctions standards d'extraction que possèdent la plupart des langages de programmation, mais des langages tels que le fortran 90 ou Matlab2.3 offrent la possibilité de directement pointer sur un sous-ensemble d'un tableau :

-->t(2:5)
 ans  =
 
!   2.    3.    4.    5. !
 
-->t([3 4])
 ans  =
 
!   3.    4. !
ici on met entre parenthèses un ensemble d'indices. Ceci est valable à l'extraction comme à l'affectation.
-->t(1:3)=3:-1:1
 t  =
 
!   3.    2.    1.    4.    5. !

A noter quelques particularités, la possibilité est offerte d'avoir redondance des indices avec deux comportements :

- à l'extraction

-->t([2 2])
 ans  =
 
!   2.    2. !
- à l'affectation :
-->t([1 1])=1:2 
 t  =
 
!   2.    2.    1.    4.    5. !
avec au final la dernière valeur affectée (dans l'ordre des indices).



\bgroup\color{black}\framebox{\textbf{A faire :}}\egroup



Regardons une autre particularité. Si on essaye d'extraire la valeur du 6ème élément de t alors

-->t(6)
      !--error    21 
invalid index
ce qui était prévisible, par contre
-->t(6)=1
 t  =
 
!   2.    2.    1.    4.    5.    1. !
affecte dynamiquement une valeur supplémentaire à t. Maintenant faisons
-->t(10)=1
 t  =
 
!   2.    2.    1.    4.    5.    1.    0.    0.   0.   1. !
on constate que automatiquement est ré-alloué un tableau de taille suffisante complété de 0.



Remarque : L'utilisation intensive de cette (re)allocation dynamique peut engendrer des temps d'exécution prohibitifs.

Il est possible également de contracter l'écriture de certaines affectations

-->t(1:6)=2
 t  =
 
!   2.    2.    2.    2.    2.    2.    0.    0.    0.    1. !
la partie entre parenthèses étant vue comme un ensemble d'indices pour lequel on affecte la valeur 2. Suivant ce principe on peut allouer des valeurs en dehors de la taille du tableau comme précédemment.

Par contre si la variable n'est pas pré-définie, l'interpréteur renvoie un tableau colonne.

-->T(1:5)=1
 T  =
 
!   1. !
!   1. !
!   1. !
!   1. !
!   1. !

\bgroup\color{black}\framebox{\textbf{A Faire :}}\egroupt=[], t($+3)=1.

Concaténation

Précédemment nous venons de voir qu'il est possible d'affecter (ou d'extraire) la valeur d'un tableau par l'indice correspondant. Scilab reconnaît une autre forme syntaxique qui est la suivante :
-->a=[1 2:5] 
 a  =
 
!   1.    2.    3.    4.    5. !
 
-->b=[a  6:7]
 b  =
 
!   1.    2.    3.    4.    5.    6.    7. !
on peut ``concaténer'' deux ou plusieurs vecteurs en les écrivant entre crochets, cela peut donner des variantes du type
-->a=[0 a 0]
 a  =
 
!   0.    1.    2.    3.    4.    5.    0. !

Cette forme d'écriture peut être utilisée lors de l'extraction

-->[x,y,z]=(1,2,3)
 z  =
 
    3.  
 y  =
 
    2.  
 x  =
 
    1.
ou avec des tailles de vecteurs différentes
-->[x,y,z]=(1:2,2:3,3:5)
 z  =
 
!   3.    4.    5. !
 y  =
 
!   2.    3. !
 x  =
 
!   1.    2. !
Cette écriture contractée peut être utilisée pour permuter des variables
-->[x,y,z]=(z,x,y)      
 z  =
 
!   2.    3. !
 y  =
 
!   1.    2. !
 x  =
 
!   3.    4.    5. !

Suppression d'éléments

La suppression d'un élément se fait à l'aide de [ ]
-->a=1:5; a(3)=[]
 a  =
 
!   1.    2.    4.    5. !
comme pour l'affectation on peut faire) une suppression multiple
-->a=1:5; a(1:2:5)=[]  
 a  =
 
!   2.    4. !

Par contre la commande

-->a(:)=[]
 a  =
 
     []
ne supprime pas la variable mais la conserve vide, pour faire disparaître la variable il faut utiliser la commande clear.

Primitives Scilab

Les fonctions usuelles s'appliquent sur les tableaux élément par élément.

Il existe quelques fonctions spécifiques :


Exercices

  1. Faire sum([]).
  2. Faire prod([]).
  3. Écrire simplement 5! avec la fonction prod.
  4. Initialiser le vecteur de taille 10 avec $ v_i=\frac{1}{i}$.
  5. Générer un vecteur aléatoire $ v$ de taille 10 (rand(1,10) et le normaliser pour la norme euclidienne ( $ \Vert v\Vert=\sqrt{\sum_i x_i^2}$).
  6. Générer le tableau des puissances de $ 2$ jusqu'a $ 2^8$;
  7. Écrire un vecteur contenant les valeurs de $ \sin(n2\pi/N)$, $ n=1..N$, pour $ N=20$.
  8. Inverser l'ordre du vecteur précedent.
  9. Générer un vecteur de nombres allant de $ 1$ jusqu'a $ 3$ par pas de $ 0.2$.
  10. Extraire du précédent vecteur les rangs multiples de $ 5$.



Matrices

Génération

Comme pour les tableaux, on peut définir ``manuellement'' les matrices. Mais il y a quelques primitives qui peuvent faciliter cette tâche.



Les primitives ones(), zeros() et eye() peuvent être utilisées en passant comme argument une matrice. Le résultat possède les mêmes dimensions que la matrice en argument.

-->A=rand(2,2); ones(A)
 ans  =
 
!   1.    1. !
!   1.    1. !

Extraction et affectation

Comme pour les tableaux on peut extraire un élément par la syntaxe
-->A=eye(3,3); A(1,1)
 ans  =
 
    1.

Mais on peut spécifier des ensembles d'indices :

-->A([1 2],[2 3])
 ans  =
 
!   0.    0. !
!   1.    0. !
on extrait la sous matrice intersection des ligne 1 et 2 avec les colonnes 3 et 4. Cette syntaxe est identique à l'affectation
-->A([1 2],[2 3])=2*ones(2,2)
 A  =
 
!   1.    2.    2. !
!   0.    2.    2. !
!   0.    0.    1. !

Comme pour les tableaux on peut utiliser la redondance des indices

-->A([1 1 1],:)
 ans  =
 
!   1.    2.    2. !
!   1.    2.    2. !
!   1.    2.    2. !
Remarquer l'usage de : spécifiant tous les indices de colonne (ou ligne). On peut également se servir de $
-->A(:,$)
 ans  =
 
!   2. !
!   2. !
!   1. !

Il est possible de considérer une matrice comme un vecteur, ce vecteur est composé des colonnes de la matrice mises bout à bout :

-->A(3)
 ans  =
 
    0. 

-->A(1:$)
 ans  =
 
!   1. !
!   0. !
!   0. !
!   2. !
!   2. !
!   0. !
!   2. !
!   2. !
!   1. !



Remarque : Cette représentation de la matrice sous forme de vecteurs colonnes correspond au mode de stockage des matrices (colonnes par colonnes).

Concaténation

Il est possible de tirer partie de la structure bloc d'une matrice pour sa définition

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

Suppression d'éléments

On ne peut pas, à proprement parler, supprimer un élément d'une matrice mais on peut supprimer une ou plusieurs rangée
-->A=matrix(1:9,3,3); A(:,[2 3])=[]
 A  =
 
!   1. !
!   2. !
!   3. !

Primitives Scilab

Les fonctions sum, cumsum, prod, cumprod, mean, max, min possèdent trois syntaxes, une agissant sur la matrice entière et les deux autres respectivement sur les lignes (row) et les colonnes (colum)
-->A=rand(3,3)
 A  =
 
!   0.2113249    0.3303271    0.8497452 !
!   0.7560439    0.6653811    0.6857310 !
!   0.0002211    0.6283918    0.8782165 !
 
-->max(A,'r')
 ans  =
 
!   0.7560439    0.6653811    0.8782165 !
 
-->max(A,'c')
 ans  =
 
!   0.8497452 !
!   0.7560439 !
!   0.8782165 !
 
-->max(A)
 ans  =
 
    0.8782165

On peut ajouter des fonctions d'extraction comme :

Comme Scilab est un environnement de manipulation matriciel, on retrouve la plupart des outils de calcul matriciel tels :

et quelques autres fonctions...


Exercices

  1. Générer une matrice de taille 10x10 diagonale de $ 2$.
  2. Inverser les lignes ou colonnes pour obtenir à partir de la matrice précédente une matrice antidiagonale.
  3. Générer une matrice aléatoire de taille 3x4

  4. Assembler les matrices suivante

    $ \left(\begin{array}{c c c c}
1.& 1.& 1.& 2.\\
1.& 1.& 1.& 3.\\
1.& 1.& 1.& 4.\\
1.& 2.& 3.& 4.
\end{array}\right)$ $ \left( \begin{array}{c c c}
1.& 4.& 7.\\
2.& 5.& 8.\\
3.& 6.& 9.
\end{array}\right)$ $ \left( \begin{array}{c c c}
2.& 1.& 2.\\
1.& 1.& 1.\\
2.& 1.& 2.
\end{array}\right)$ $ \left(\begin{array}{c c c c}
1.& 1.& 1.& 1.\\
2.& 2.& 2.& 2.\\
3.& 3.& 2.& 3.\\
4.& 4.& 4.& 4.
\end{array}\right)$

  5. Générer 2 matrices aléatoires de taille 4x4, former la matrice dont chaque élément et le sup des éléments correspondants des 2 premières matrices ( $ c_{ij}=\sup(a_{ij},b_{ij})$).

Booléens

Opérateurs de comparaison

On a déjà vu dans la prise en main que le type booléen pouvait se composer en matrice avec les conjonctions \bgroup\color{black}$ \mathbf{\&}$\egroup (et), \bgroup\color{black}$ \mathbf{\vert}$\egroup (ou) et \bgroup\color{black}$ \mathbf{\sim}$\egroup (non) (attention à la compatibilité des dimensions !).

Mais la capacité matricielle des opérateurs de conjonction, offrant la possibilité de travailler avec des matrices booléennes s'étend aux opérateurs de comparaisons :

-->A=1:5; A>3
 ans  =
 
! F F F T T !
Les opérateurs de comparaison sont \bgroup\color{black}$ \mathbf{>}$\egroup, \bgroup\color{black}$ \mathbf{>=}$\egroup, \bgroup\color{black}$ \mathbf{<}$\egroup, \bgroup\color{black}$ \mathbf{<=}$\egroup, \bgroup\color{black}$ \mathbf{==}$\egroup (égalité), \bgroup\color{black}$ \mathbf{\sim =}$\egroup ou \bgroup\color{black}$ \mathbf{<>}$\egroup (différent).

De plus il existe des version vectoriel des opérateurs de conjonction

-->M=(1:5)>3
 M  =
 
! F F F T T !
-->or(M)
 ans  =
 
  T  
-->and(M)
 ans  =
 
  F
Ces commandes ce déclinent également sous forme matricielle, avec le commutateur de ligne ou de colonne.
-->M=rand(3,3)>0.4
 M  =
 
! F F T !
! T T T !
! F T T !

-->and(M,'r')
 ans  =
 
! F F T !

-->and(M,'c')
 ans  =
 
! F !
! T !
! F !

Génération

Comme vu dans la section précédente les opérateurs de comparaisons sont les principaux outils pour la construction de matrices de booléens. Neanmoins on peut rendre booléen certaines expression :
-->a=round(rand(3,3))
 a  =
 
!   0.    0.    1. !
!   1.    1.    1. !
!   0.    1.    1. !
 
-->a|a
 ans  =
 
! F F T !
! T T T !
! F T T !
Cet exemple montre que les valeurs nulle d'une matrice sont interprétées comme la valeur booléenne fausse. Tout ce qui n'est pas nul est vrai. On peut par ce jeu créer des vecteurs ou matrices de booléens avec une syntaxe peu esthétique mais fonctionnelle :
-->v=~ones(1,5)
 v  =
 
! F F F F F !
 
-->u=~zeros(1,7)
 u  =
 
! T T T T T T T !

-->w=~round(rand(1,7))
 w  =
 
! T T F F T F T !

Il est toujours possible d'utiliser des fonctions classiques comme les commandes matrix(), diag() ...

-->d=~zeros(1,4)
 d  =
 
! T T T T !
 
-->B=diag(d)
 B  =
 
! T F F F !
! F T F F !
! F F T F !
! F F F T !

De manière plus anecdotique, il existe différentes passerelles entre le calcul booléen et le calcul réel. Il est possible de sommer un booléen avec un réel les valeurs 0 et \bgroup\color{black}$ 1$\egroup, faisant office de valeurs fausses et vraies.

Compression

Scilab offre la possibilité d'extraire d'une matrice tout ou une partie à l'aide d'une matrice booléenne, spécifiant les éléments à retenir
-->A=rand(2,2)  
 A  =
 
!   0.2113249    0.0002211 !
!   0.7560439    0.3303271 !
 
-->T=[%t %f;%f %t]
 T  =
 
! T F !
! F T !
 
-->A(T)
 ans  =
 
!   0.2113249 !
!   0.3303271 !

Ceci peut donner lieu à des expressions de la forme

-->A(A>0.5)
 ans  =
 
    0.7560439

Primitives Scilab

Il y a une primitive particulièrement utile, c'est la commande find qui s'applique sur des tableaux ou matrices booléennes et renvoie le(s) indices correspondants aux éléments vrais
-->T=[%t %f %f %t]
 T  =
 
! T F F T !
 
-->find(T)
 ans  =
 
!   1.    4. !

La commande find peut également renvoyer les indices de lignes et colonnes de la recherche.

\bgroup\color{black}\framebox{\textbf{A faire :}}\egroup


Exercices

  1. Générer 2 matrices aléatoires de taille 5x5 (A et B). Trouver la matrice booléenne correspondant aux élément de A supérieurs à ceux de B (vrai si $ a_{ij}>b_{ij}$).
  2. Générer 1 matrice aléatoire de taille 5x5, extraire les éléments compris entre 0.3 et 0.7.
  3. Générer 1 vecteur aléatoire de taille 1x10, soustraire $ 1$ aux éléments plus grand que $ 0.5$.
  4. Générer 1 matrice aléatoire de taille 5x5 de nombre entier compris entre 0 et 10. Trouver les éléments égaux à 0.

Polynômes et Fractions rationnelles

Scilab permet la manipulation des polynômes et fractions rationnelles définissant pour cela deux types : polynomial et rational.

Génération

Scilab possède une variable pré-définie : %s. Cette dernière représente le monôme de degré 1 et permet la création de polynômes ou de fractions rationnelles par une syntaxe de la forme
-->p=1+%s+2*%s^2
 p  =
 
              2  
    1 + s + 2s   
 
-->q=p/(1 + %s)
 q  =
 
              2  
    1 + s + 2s   
    ----------   
      1 + s



\bgroup\color{black}\framebox{\textbf{A faire :}}\egroup typeof(p), typeof(q), q('num'), q('den') avec p et q définis ci-dessus.

La possibilité est offerte avec la commande poly de directement définir un polynôme par ses racines (par défaut) ou bien par ses coefficients

-->r=poly([0 1 2],'s')
 r  =
 
           2   3  
    2s - 3s + s   

-->r2=poly([0 1 2],'s','coeff')
 r2  =
 
          2  
    s + 2s
Les commandes roots() et coeff() permettent les opérations inverses (ou effectue le calcul des racines pour la première).

Les commandes algébriques usuelles : somme, multiplication, division et puissance sont valides.



Remarque1 : le caractère 's' (variable symbolique) a été utilisé dans la définition du polynôme r, l'utilisateur a le choix de sa variable polynomiale, par contre les compositions (somme ...) nécessitent l'emploi de polynômes possédant la même variable

-->poly([0 1 2],'x') + poly([1 1],'s')
                                    !--error     4 
undefined variable : %p_a_p                  
La commande varn() peut résoudre se problème.



Remarque2 : la commande poly peut prendre une matrice carrée comme argument, le résultat est dans ce cas le polynôme caractéristique de la matrice

-->poly([2 1; 1 2],'x')
 ans  =
 
              2  
    3 - 4x + x
si la matrice n'est pas carrée alors les éléments sont lus colonne par colonne et c'est donc le polynôme défini par ces racines qui est retourné.

Évaluation

Pour évaluer un polynôme (et fraction), la commande horner(polynôme,valeurs) intervient

-->p=poly([1 1 2],'x'); horner(p,[0 0.5])
 ans  =
 
! - 2.  - 0.375 !

-->horner(p,[0 1;1 0.5])                     
 ans  =
 
! - 2.    0.    !
!   0.  - 0.375 !

Primitives Scilab

Scilab possède quelques fonctions dédiées au calcul des polynômes et fractions.


Exercices

  1. Écrire le polynôme $ p(x)=1+x+3x^2-x^3$.
  2. Écrire le polynôme $ q(x)=(x-1)(x-2)(x-3)$, Calculer les racines de $ q$.
  3. Même question que précédemment mais avec $ q(x)=\prod_{i=1}^{n}
(x-i)$, pour $ n=15,20,25$
  4. Écrire la fraction $ f(x)=\frac{x(1-2x)}{(x+1)(x-1)}$.

Chaîne de caractère(s)

Génération

Les chaînes de caractères constituent un type Scilab , et à ce titre, elles admettent des règles d'usage et de comportement.

Une chaîne de caractères est une expression délimitée par simple apostrophe (') ou double apostrophe (").

-->a='coucou' , b="hello"
 a  =
 
 coucou   
 b  =
 
 hello
pour faire apparaître la simple ou double apostrophe dans l'expression, il faut doubler l'apostrophe
-->c='voici une apostrophe : ''  une double apostrophe "".'
 c  =
 
 voici une apostrophe : '  une double apostrophe ".

Il est possible de transformer toute expression numérique en chaîne de caractères avec la commande string().

-->string(tan(0.5))
 ans  =
 
 0.5463025   
 
-->typeof(ans)
 ans  =
 
 string



Remarque : Attention les caractères accentués de notre chère langue ne donnent pas toujours le rendu escompté2.5

-->c='é'                                       
 c  =
 
 !

La chaîne de caractères, comme la plupart des types Scilab, admet une syntaxe matricielle.

-->A=["une" "matrice" ; "de" "caractères"]
 A  =
 
!une  matrice      !
!                  !
!de   caracteres  !

Concaténation

La concaténation se fait à l'aide du signe +
-->a="tan(0.5)="+string(tan(0.5))
 a  =
 
 tan(0.5)=0.5463025

Dans le cas d'une matrice on peut utiliser la commande strcat() qui permet de mettre bout à bout les éléments de la matrice (parcours par colonnes)

-->A=["une" "de";"matrice" "caracteres"];      
 
-->strcat(A)                              
 ans  =
 
 unematricedecaracteres   
 
-->strcat(A," ")                          
 ans  =
 
 une matrice de caracteres
Dans ce dernier cas la concaténation est effectuée avec un espace intercalé entre chaque terme.

la concaténation admet des extensions naturelles entre une matrice (de caractères) et un scalaire (également chaîne de caractères)

-->A=['a';'b';'c']
 A  =
 
!a  !
!   !
!b  !
!   !
!c  !
 
-->'(' + A + ')'
 ans  =
 
!(a)  !
!     !
!(b)  !
!     !
!(c)  !

Extraction

La commande part() permet d'extraire tout ou une partie d'une chaîne de caractères
-->a="hello"  
 a  =
 
 hello   
 
-->part(a,1)  
 ans  =
 
 h   
 
-->part(a,[1 3 5])
 ans  =
 
 hlo
le tableau passé en paramètre correspondant aux positions des caractères à extraire. Cette commande est souvent utilisée avec la commande length qui permet d'avoir la longueur de chaîne (attention au cas matriciel).

la commande strindex() retourne la position du caractère ou chaîne spécifié en argument.

-->strindex(a,'l')                       
 ans  =
 
!   3.    4. !
 
-->strindex(a,'ll')                      
 ans  =
 
    3.

Primitives Scilab

Scilab possède un jeu restreint de fonctions dédiées à la manipulation de chaînes de caractères.



A noter la commande evstr qui évalue une chaîne de caractère :

-->a=1; b='2*a' ; evstr(b)
 ans  =
 
    2.
ou encore la commande execstr qui demande à l'interpréteur l'exécution Scilab de cette chaîne :
-->execstr('a=%t')
 
-->a              
 a  =
 
  T
Ces dernières commandes sont relativement anodines, néanmoins, comme nous somme dans un environnement interprété, cela peut donner un caractère ``dynamique'' au programme, permettant même de s'auto-générer !


Exercices

  1. Former la chaîne de caractère "1,2,3,4,5".
  2. Trouver les positions de 'o' dans 'bonjour', remplacer les occurences de 'o' par '-'.
  3. Former la chaîne 'pi=3.1415927' en utilisant la variable prédéfinie %pi.

Liste

Scilab offre la possibilité de construire des types ``list''. Ce type de variable permet de gérer des structures de données complexes. Il est possible ainsi dans une variable de type ``list'' de faire cohabiter tous types de variables, même d'autres listes, sans condition de compatibilité.

Génération

Pour obtenir une liste il suffit d'utiliser le mot réservé list sous la forme
-->a=list(1,1:2,rand(2,3),"toto")
 a  =
       a(1)
 
    1.  
 
       a(2)
 
!   1.    2. !
 
       a(3)
 
!   0.2113249    0.0002211    0.6653811 !
!   0.7560439    0.3303271    0.6283918 !
 
       a(4)
 
 toto
on obtient une liste indicée contenant nos éléments.

Il est possible de créer une liste vide

-->b=list()
 b  =
 
     ()

Affectation-Extraction

Le type list se comporte comme un tableau mono-dimensionnel, chaque élément étant référencé par son numéro de liste2.6. D'où pour obtenir un des éléments on a la syntaxe d'extraction
-->a=list(1,1:2,"toto");  
-->a(2)                             
 ans  =
 
!   1.    2. !
L'affectation d'un élément se fait de la même manière
-->a(1)=5:10
 a  =
       a(1)
 
!   5.    6.    7.    8.    9.    10. !
 
       a(2)
 
!   1.    2. !
 
       a(3)
 
 toto

On a vu que pour les tableaux on pouvait affecter (ou extraire) un élément ou une partie (ensemble d'indices). Pour le type list les choses ne sont plus tout à fait identiques. En effet si on affecte une partie de liste, alors la réponse est immédiate

-->a(1:2)=[2,2:3]
               !--error    43 
not implemented in scilab....

Par contre à l'extraction nous avons le comportement suivant

-->a(1:2)     
       !--error    41 
incompatible LHS
mais
-->[s,t]=a(1:2)
 t  =
 
!   1.    2. !
 s  =
 
    1.
il est donc permis de ``multi-extraire'' les éléments d'une liste avec l'utilisation des crochets.

Suppression d'éléments

Il existe une liste particulière c'est la liste null(). Pour supprimer un élément de liste il suffit de faire
-->a=list(1,1:2,"toto");
-->a(2)=null()
 a  =
       a(1)
 
    1.  
 
       a(2)
 
 toto
pour voir le deuxième élément de a disparaître. Noter le ré-ordonnancement automatique.

On ne peut toujours pas supprimer un ensemble d'indices

-->a(1:2)=null()        
              !--error    43 
not implemented in scilab....

Mais attention le comportement de null() peut être radical

-->a=list(1,1:2,"toto");
-->a=null()             
-->a
  !--error     4 
undefined variable : a



Remarque : l'élément list(), liste vide est une liste, mais pas null().

On peut accéder aux champs d'un élément de la liste par un mode d'extraction hiérarchique. Dans l'exemple suivant le second élément de la liste est un tableau, voici la syntaxe pour directement obtenir la première valeur du tableau :

-->a=list(1,1:2,"toto")    //definition de a
-->a(2)
 ans  =
 
!   1.    2. !
 
-->a(2)(1)
 ans  =
 
    1.

Ajout d'éléments

Le type list se comporte comme une liste séquentielle à multiples entrées (en début, fin ou à indice).





\bgroup\color{black}\framebox{\textbf{Faire :}}\egroup a=list(), a($)=2:3 , a($+1)=2:3.

Liste de listes

Une liste peut contenir elle même une autre liste
-->a=list(1,list("hello",1:2))
 a  =
       a(1)
 
    1.  
 
       a(2)
 
 
        a(2)(1)
 
 hello   
 
        a(2)(2)
 
!   1.    2. !

Dans ce cas on peut extraire ou affecter avec les deux indices de liste

-->a(2)(2)=null()
 a  =
       a(1)
 
    1.  
 
       a(2)
 
 
        a(2)(1)
 
 hello

On peut faire des listes de listes de listes ...

-->a=list();
-->for i=1:5, a=list(a); ,end
-->a
 a  =
       a(1)
 
 
        a(1)(1)
 
 
         a(1)(1)(1)
 
 
          a(1)(1)(1)(1)
 
 
           a(1)(1)(1)(1)(1)
 
     ()

Liste typée

La liste typée (mot clef : mlist2.7) est un ``objet'' Scilab très intéressant. Elle possède :

Cet ensemble de fonctionnalités permet d'étendre la structure algébrique à d'autres formes de représentation. On pourra consulter le help de rational pour voir une construction de fraction rationnelle (une fraction rationnelle est composée de deux polynômes, un ``num''-érateur et un ``den''-ominateur).

Déclaration

On parlera ici de déclaration de listes typées. En effet cette structure nécessite un peu plus d'attention lors de sa création. Il faut en spécifier les différents champs dès sa création, on ne peut en rajouter dynamiquement.

La syntaxe de déclaration est la suivante :

variable_type=([nom_type;nom_champ1 ;nom_champ2;...],champ1,champ2 ,...)



Exemple

-->fraction=mlist(['rational';'num';'den'],%s,1+%s)
 fraction  =
 
 
       fraction(1)
 
!rational  !
!          !
!num       !
!          !
!den       !
 
       fraction(2)
 
    s   
 
       fraction(3)
 
    1 + s
On voit sur l'exécution de cet exemple qu'une liste typée est une liste, qui contient en premier élément un vecteur colonne de chaînes de caractères qui renseigne de la structure de la variable



\bgroup\color{black}\framebox{\textbf{A faire :}}\egroup Tapez type(fraction),typeof(fraction), noter le rôle joué par la fonction typeof.

Extraction et affectation

Il existe trois modes d'accès aux éléments. Le premier qui sera totalement oublié par la suite est l'accès par élément de list, ce qui peut donner sur l'exemple précédent :
-->fraction(2)
 ans  =
 
    s   
 
--> fraction(3)=1-%s 
 
 
       fraction(1)
 
!rational  !
!          !
!num       !
!          !
!den       !
 
       fraction(2)
 
    s   
 
       fraction(3)
 
    1 - s
Mais ceci est à proscrire, car l'ordre d'attribution dans la liste typée n'est pas en fonction de l'ordre des noms des différents champs, c'est l'ordre ``d'arrivée'' qui prédomine.

Les deux autres façons se font par le nom des champs et sont strictement équivalentes :

 -->fraction.num
 ans  =
 
    s  
 
-->fraction.den=1-%s
 fraction  =
 
 
       fraction(1)
 
!rational  !
!          !
!num       !
!          !
!den       !
 
       fraction(2)
 
    s   
 
       fraction(3)
 
    1 - s
ou alors
-->fraction('num')
 ans  =
 
    s   
 
-->fraction(``den'')=1-%s
 fraction  =
 
 
       fraction(1)
 
!rational  !
!          !
!num       !
!          !
!den       !
 
       fraction(2)
 
    s   
 
       fraction(3)
 
    1 - s

Surcharge d'opérateur

La surcharge d'opérateur (algébrique) peut permettre la construction ``d'objets'' pour lesquels on définit leurs comportements avec les opérateurs binaires de sommation, multiplication ...

L'opérateur unaire qui peut apporter un peu de confort est ``l'opérateur'' d'affichage. Le mécanisme d'affichage pour les listes typées est le suivant : l'interpréteur identifie s'il possède parmi ses variables la fonction nom_type_p, si celle-ci n'existe pas c'est la fonction d'affichage de list qui est usitée.



Exemple Pour notre exemple de fraction rationnelle on peut définir (en ligne dans Scilab 2.6):

function %rational_p(fr)
    disp(fr.num);
    disp('  --------');
    disp(fr.den);
endfunction
pour obtenir le résultat suivant :
-->fraction
 fraction  =
 
 
    s   
 
   --------   
 
    1 - s
Remarquez que l'on utilise de manière imbriquée les différentes fonctions d'affichage des différents types (ici c'est la fonction du type polynome).

Si on cherche à sommer notre ``rational'' à un scalaire l'essai infructueux nous donne :

-->1+fraction
    !--error     4 
undefined variable : %s_a_rational
ici l'interpréteur de Scilab cherche la fonction %s_a_rational() correspondant à l'opérateur binaire de sommation (``_a_'') entre un scalaire à gauche (``s'') et un type rational à droite. Il paraît légitime d'informer Scilab sur nos intentions de sommation en définissant la fonction suivante :
function out=%s_a_rational(s,f)
    out=f;
    out.num=out.num + s*out.den;
endfunction
Ainsi la somme peut se passer correctement.



\bgroup\color{black}\framebox{\textbf{A faire :}}\egroup Après avoir fait les étapes proposées en exemple, faire fraction +1.

Le nom des fonctions de surcharge pour les opérateurs binaires suit la règle :

%type1_symbol_opération_ type2


next up previous contents
suivant: Programmation monter: intsci précédent: Prise en main   Table des matières
2003-10-15