4. Séries/vecteurs et tableaux nD, chaînes, structures, tableaux cellulaires, maps

4.1 Séries (ranges)

Séries


4:00 min
Présentation des séries linéaires et logarithmiques

L'opérateur MATLAB/Octave : (deux points, en anglais "colon") est très important. Il permet de construire des séries linéaires sous la forme de vecteurs ligne, notamment utilisés pour l'adressage des éléments d'un tableau.

série=début:fin
série=colon(début,fin)
Crée une série numérique linéaire débutant par la valeur début, auto-incrémentée de "1" et se terminant par la valeur fin. Il s'agit donc d'un vecteur ligne de dimension 1xM (où M=fin-début+1). Si fin<début, crée une série vide (vecteur de dimension 1x0)
Ex:
série=début:pas:fin
série=colon(début,pas,fin)
Crée une série numérique linéaire (vecteur ligne) débutant par la valeur début, incrémentée ou décrémentée du pas spécifié et se terminant par la valeur fin. Crée une série vide (vecteur de dimension 1x0) si fin<début et que le pas est positif, ou si fin>début et que le pas est négatif
Ex:

Lorsqu'on connait la valeur de début, la valeur de fin et que l'on souhaite générer des séries linéaires ou logarithmique de nbval valeurs, on peut utiliser les fonctions suivantes :

série=linspace(début,fin {,nbval})
Crée une série (vecteur ligne) de nbval éléments linéairement espacés de la valeur début jusqu'à la valeur fin. Si l'on omet le paramètre nbval, c'est une série de 100 éléments qui est créée
Ex: v=linspace(0,-5,11) crée v=[0.0 -0.5 -1.0 -1.5 -2.0 -2.5 -3.0 -3.5 -4.0 -4.5 -5.0]
série=logspace(début,fin {,nbval})
Crée une série logarithmique (vecteur ligne) de nbval éléments, débutant par la valeur 10début et se terminant par la valeur 10fin. Si l'on omet le paramètre nbval, c'est une série de 50 éléments qui est créée
Ex: x=logspace(2,6,5) crée x=[100 1000 10000 100000 1000000]


Sous Octave depuis la version 3, la syntaxe début:pas:fin (plutôt qu'avec linspace) est particulièrement intéressante au niveau utilisation mémoire ! En effet, quelle que soit la taille de la série qui en découle, celle-ci n'occupera en mémoire que 24 octets (c'est-à-dire l'espace de stockage nécessaire pour stocker en double précision les 3 valeurs définissant la série) !
      Ex: s1=0:10/99:10; et s1=linspace(0,10,100); sont fonctionellement identiques, mais :
      - sous MATLAB 7.x : les variables s1 et s2 consomment toutes deux 800 octets (100 réels double précision)
      - alors que sous Octave 3.x : s2 consomme aussi 800 octets, mais s1 ne consomme que 24 octets !!!
        noter cependant que, selon son usage, cette série est susceptible d'occuper aussi 800 octets (p.ex. s1' ou s1*3)

Pour construire des séries d'un autre type (géométrique, etc...), il faudra réaliser des boucles for ou while... (voir chapitre "Structures de contrôle").

4.2 Vecteurs (ligne ou colonne)

Vecteurs et tableaux


12:00 min
Introduction aux vecteurs et tableaux

MATLAB/Octave ne fait pas vraiment de différence entre un scalaire, un vecteur, une matrice ou un tableau à N-dimensions, ces objets pouvant être redimensionnés dynamiquement. Un vecteur n'est donc qu'une matrice NxM dégénérée d'une seule ligne (1xM) ou une seule colonne (Nx1).

RAPPEL IMPORTANT: les éléments du vecteurs sont numérotés par des entiers débutant par la valeur 1 (et non pas 0, comme dans la plupart des autres langages de programmation).

On présente ci-dessous les principales techniques d'affectation de vecteurs par l'usage des crochets [ ], et adressage de ses éléments par l'usage des parenthèses ( ).

Syntaxe Description
vec=[val1 val2 val3 ...]

         =[val var expr ...]

Création d'un vecteur ligne vec contenant les valeurs val, variables var, ou expressions expr spécifiées.
Celles-ci doivent être délimitées par des espace, tab ou , (virgules).

Ex: v1=[1 -4 5], v2=[-3,sqrt(4)] et v3=[v2 v1 -3] retournent v3=[-3 2 1 -4 5 -3]

vec=[val ; var ; expr ...]

         =[val1
            val2
            ... ]

         =[var val var val ...]'

Création d'un vecteur colonne vec contenant les valeurs val (ou variables var, ou expressions expr) spécifiées.
Celles-ci doivent être délimitées par des ; (point-virgules) (1ère forme ci-contre) et/ou par la touche enter (2e forme).
La 3ème forme ci-contre consiste à définir un vecteur ligne et à le transposer avant de l'affecter à vec.

Ex:
v4=[-3;5;2*pi], v5=[11 ; v4], v6=[3 4 5 6]' sont des vecteurs colonne valides
• mais v7=[v4 ; v1] provoque une erreur car on combine ici un vecteur colonne avec un vecteur ligne

vec' Transpose le vecteur vec. Si c'était un vecteur ligne, il devient un vecteur colonne, ou vice-versa
vec(indices) Forme générale de la syntaxe d'accès aux éléments d'un vecteur, où indices est un vecteur (ligne ou colonne) de valeurs entières positives désignant les indices des éléments concernés de vec. Typiquement indices peut prendre les formes suivantes :
ind1:indN : séquence contiguë (série) d'indices allant de ind1 jusqu'à indN
ind1:pas:indN : séquence d'indices de ind1 à indN espacés par un pas
[ind1 ind2 ...] : indices ind1, ind2 ... spécifiés (séquence discontinue) (notez bien les crochets [ ])
S'agissant de l'indice indN, on peut utiliser la valeur end pour désigner le dernier élément du vecteur

Ex: Les exemples ci-dessous sont simplement dérivés de cette syntaxe générale :
v3(2) retourne la valeur "2", et v4(2) retourne "5"
v4(2:end) retourne un vecteur colonne contenant la 2e jusqu'à la dernière valeur de v4, c'est-à-dire dans le cas présent [5;6.28]
v3(2:2:6) retourne un vecteur ligne contenant la 2e, 4e et 6e valeur de v3, c'est-à-dire [2 -4 -3]
v6([2 4]) retourne un vecteur colonne contenant la 2e et la 4e valeur de v6, c'est-à-dire [4 6]'
• si v8=[1 2 3], alors v8(6:2:10)=44 étend v8 qui devient [1 2 3 0 0 44 0 44 0 44]

for k=i{:p}:j
  vec(k)=expression
end
Initialise les éléments (spécifiés par la série i{:p}:j) du vecteur ligne vec par l'expression spécifiée

Ex: for i=2:2:6, v9(i)=i^2, end crée le vecteur v9=[0 4 0 16 0 36] (les éléments d'indice 1, 3 et 5 n'étant pas définis, ils sont automatiquement initialisés à 0)

vec(indices)=[] Destruction des éléments indicés du vecteur vec (qui est redimensionné en conséquence)

Ex: soit v10=(11:20) c'est-à-dire [11 12 13 14 15 16 17 18 19 20]
• l'instruction v10(4:end)=[] redéfini v10 à [11 12 13]
• alors que v10([1 3:7 10])=[] redéfini v10 à [12 18 19]

length(vec) Retourne la taille (nombre d'éléments) du vecteur ligne ou colonne vec

4.3 Matrices (tableaux 2D)

Une matrice MATLAB/Octave est un tableau rectangulaire à 2 dimensions de NxM éléments (N lignes et M colonnes) de types nombres réels ou complexes ou de caractères. La présentation ci-dessous des techniques d'affectation de matrices (avec les crochets [ ] ) et d'adressage de ses éléments (parenthèses ( )) est donc une généralisation à 2 dimensions de ce qui a été vu pour les vecteurs à 1 dimension (chapitre précédent), la seule différence étant que, pour se référer à une partie de matrice, il faut spécifier dans l'ordre le(s) numéro(s) de ligne puis de colonne(s) séparés par une virgule ",".

Comme pour les vecteurs, les indices de ligne et de colonne sont des valeurs entières débutant par 1 (et non pas 0 comme dans la plupart des autres langages).

On dispose en outre de fonctions d'initialisation spéciales liées aux matrices.

Syntaxe Description
mat=[v11 v12 ... v1m ;
              v21 v22 ... v2m ;
              ... ... ... ... ;
              vn1 vn2 ... vnm ]
Définit une matrice mat de n lignes x m colonnes dont les éléments sont initialisés aux valeurs vij. Notez bien que les éléments d'une ligne sont séparés par des espace, tab ou , (virgules), et que les différentes lignes sont délimitées par des ; (point-virgules) et/ou par la touche enter. Il faut qu'il y aie exactement le même nombre de valeurs dans chaque ligne, sinon l'affectation échoue.

Ex: m1=[-2:0 ; 4 sqrt(9) 3] définit la matrice de 2 lignes x 3 colonnes avant pour valeurs [-2 -1 0 ; 4 3 3]

mat=[vco1 vco2 ...]
ou mat=[vli1 ; vli2 ; ...]
Construit la matrice mat par concaténation de vecteurs colonne vcoi ou de vecteurs ligne vlii spécifiés. Notez bien que les séparateurs entre les vecteurs colonne est l'espace, et celui entre les vecteurs ligne est le ; ! L'affectation échoue si tous les vecteurs spécifiés n'ont pas la même dimension.

Ex: si v1=1:3:7 et v2=9:-1:7, alors m2=[v2;v1] retourne la matrice [9 8 7 ; 1 4 7]

[mat1 mat2 {mat3...}] ou
horzcat(mat1, mat2 {,mat3...})

 respectivement:
[mat4; mat5 {; mat6...}] ou
vertcat(mat1, mat2 {,mat3...})

Concaténation de matrices (ou vecteurs). Dans le premier cas, on concatène côte à côte (horizontalement) les matrices mat1, mat2, mat3... Dans le second, on concatène verticalement les matrices mat4, mat5, mat6... Attention aux dimensions qui doivent être cohérentes : dans le premier cas toutes les matrices doivent avoir le même nombre de lignes, et dans le second cas le même nombre de colonnes.

Ex: ajout devant la matrice m2 ci-dessus de la colonne v3=[44;55] : avec m2=[v3 m2] ou avec m2=horzcat(v3,m2), ce qui donne m2=[44 9 8 7 ; 55 1 4 7]

ones(n{,m})
zeros(n{,m})
Renvoie une matrice numérique de n lignes x m colonnes dont tous les éléments sont mis à la valeur 1, respectivement à 0.
Si m est omis, crée une matrice carrée de dimension n.

Ex: c * ones(n,m) renvoie une matrice n x m dont tous les éléments sont égaux à c

eye(n{,m}) Renvoie une matrice numérique identité de n lignes x m colonnes dont les éléments de la diagonale principale sont mis à la valeur 1, et les autres éléments à 0. Si m est omis, crée une matrice carrée de dimension n
true(n{,m})
false(n{,m})
Renvoie une matrice logique de n lignes x m colonnes dont tous les éléments sont mis à la valeur logique Vrai, respectivement à Faux.
Si m est omis, crée une matrice carrée de dimension n.
diag(vec)

diag(mat)

Appliquée à un vecteur vec ligne ou colonne, cette fonction retourne une matrice carrée dont la diagonale principale porte les éléments du vecteur vec et les autres éléments sont égaux à "0"

Appliquée à une matrice mat (qui peut ne pas être carrée), cette fonction retourne un vecteur-colonne formé à partir des éléments de la diagonale de cette matrice

mat2=repmat(mat1,M,N) Renvoie une matrice mat2 formée à partir de la matrice mat1 dupliquée en "tuile" M fois verticalement et N fois horizontalement

Ex: repmat(eye(2),1,2) retourne [1 0 1 0 ; 0 1 0 1]

mat=[] Crée une matrice vide mat de dimension 0x0
[n m]=size(var)
taille=size(var,dimension)

n=rows(mat_2d)
m=columns(mat_2d)

La première forme renvoie, sur un vecteur ligne, la taille (nombre n de lignes et nombre m de colonnes) de la matrice ou du vecteur var. La seconde forme renvoie la taille de var correspondant à la dimension spécifiée (dimension=1=> nombre de lignes, 2=> nombre de colonnes).

Les fonctions rows et columns retournent respectivelement le nombre n de lignes et nombre m de colonnes.

Ex: mat2=eye(size(mat1)) définit une matrice identité "mat2" de même dimension que la matrice "mat1"

length(mat) Appliquée à une matrice, cette fonction analyse le nombre de lignes et le nombre de colonnes puis retourne le plus grand de ces 2 nombres (donc identique à max(size(mat))). Cette fonction est par conséquent assez dangereuse à utiliser sur une matrice !
numel(mat)      (NUMber of ELements) Retourne le nombre d'éléments du tableau mat (donc identique à prod(size(mat)) ou length(mat(:)), mais un peu plus "lisible")
mat(indices1,indices2) Forme générale de la syntaxe d'accès aux éléments d'une matrice (tableau à 2 dimensions), où indices1 et indices2 sont des vecteurs (ligne ou colonne) de valeurs entières positives désignant les indices des éléments concernés de mat. indices1 se rapporte à la première dimension de mat c'est-à-dire les numéros de lignes, et indices2 à la seconde dimension c'est-à-dire les numéros de colonnes.
Dans la forme simplifiée où l'on utilise : la place de indices1, cela désigne toutes les lignes ; respectivement si l'on utilise : la place de indices2, cela désigne toutes les colonnes.

Ex: Les exemples ci-dessous sont simplement dérivés de cette syntaxe générale :
• si l'on a la matrice m3=[1:4; 5:8; 9:12; 13:16]
    m3([2 4],1:3) retourne [5 6 7 ; 13 14 15]
    m3([1 4],[1 4]) retourne [1 4 ; 13 16]

mat(indices) Lorsque l'on adresse une matrice à la façon d'un vecteur en ne précisant qu'un vecteur d'indices, l'adressage s'effectue en considérant que les éléments de la matrice sont numérotés de façon continue colonne après colonne.

Ex: m3(3) retourne 9, et m3(7:9) retourne [10 14 3]

mat(:) Retourne un vecteur colonne constitué des colonnes de la matrice (colonne après colonne).

Ex:
• si m4=[1 2;3 4], alors m4(:) retourne [1 ; 3 ; 2 ; 4]
mat(:)=val réinitialise tous les éléments de mat à la valeur val

mat(indices1,indices2)=[] Destruction de lignes ou de colonnes d'une matrice (et redimensionnement de la matrice en conséquence). Ce type d'opération supprime des lignes entières ou des colonnes entières, donc on doit obligatoirement avoir : pour indices1 ou indices2.

Ex: en reprenant la matrice m3 ci-dessus, l'instruction m3([1 3:4],:)=[] réduit cette matrice à la seconde ligne [5 6 7 8]

On rapelle ici les fonctions load {-ascii} fichier_texte et save -ascii fichier_texte variable (décrites au chapitre "Workspace") qui permettent d'initialiser une matrice à partir de valeurs numériques provenant d'un fichier_texte, et vice-versa.

4.4 Tableaux nD (multidimensionnels)

Généralités

Sous la dénomination de "tableaux multidimensionnels" (multidimensional arrays, ND-Arrays), il faut simplement imaginer des matrices ayant plus de 2 indices (ex: B(2,3,3)). S'il est facile de se représenter la 3e dimension (voir Figure ci-contre), c'est un peu plus difficile au-delà :
    - 4 dimensions pourrait être vu comme un vecteur de tableaux 3D
    - 5 dimensions comme une matrice 2D de tableaux 3D
    - 6 dimensions comme un tableau 3D de tableaux 3D...
Un tableau tridimensionnel permettra, par exemple, de stocker une séquence de matrices 2D de tailles identiques (pour des matrices de tailles différentes, on devra faire appel aux "tableaux cellulaires" décrits plus loin) relatives à des données physiques de valeurs spatiales (échantillonées sur une grille) évoluant en fonction d'un 3e paramètre (altitude, temps...).

Les tableaux multidimensionnels sont supportés depuis longtemps sous MATLAB, et depuis la version 2.1.51 d'Octave.

Ce chapitre illustre la façon de définir et utiliser des tableaux multidimensionnels. Les exemples, essentiellement 3D, peuvent sans autre être extrapolés à des dimensions plus élevées.

Tableaux nD en pratique

La génération de tableaux multidimensionnels peut s'effectuer simplement par indexation, c'est-à-dire en utilisant un 3ème, 4ème... indice de matrice.

Ex:
Certaines fonctions MATLAB/Octave déjà présentées plus haut permettent de générer directement des tableaux multidimensionnels lorsqu'on leur passe plus de 2 arguments : ones, zeros, rand, randn.

Ex:
Voir aussi les fonctions de génération et réorganisation de matrices, telles que repmat(tableau,[M N P ...]) et reshape(tableau,M,N,P...), qui s'appliquent également aux tableaux multidimensionnels.
Les opérations dont l'un des deux opérandes est un scalaire, les opérateurs de base (arithmétiques, logiques, relationnels...) ainsi que les fonctions opérant "élément par élément" sur des matrices 2D (fonctions trigonométriques...) travaillent de façon identique sur des tableaux multidimensionnels, c'est-à-dire s'appliquent à tous les éléments du tableau. Par contre les fonctions qui opèrent spécifiquement sur des matrices 2D et vecteurs (algèbre linéaire, fonctions "matricielles" telles que inversion, produit matriciel, etc...) ne pourront être appliquées qu'à des sous-ensembles 1D (vecteurs) ou 2D ("tranches") des tableaux multidimensionnels, donc moyennement un usage correct des indices de ces tableaux !

Ex:
Certaines fonctions présentées plus haut (notamment les fonctions statistiques min, max, sum, prod, mean, std...) permettent de spécifier un "paramètre de dimension" d qui est très utile dans le cas de tableaux multidimensionnels. Illustrons l'usage de ce paramètre avec la fonction sum :
sum(tableau, d )
Calcule la somme des éléments en faisant varier le d-ème indice du tableau

Ex: dans le cas d'un tableau de dimension 3x4x5 (nombre de: lignes x colonnes x profondeur)

La génération de tableaux multidimensionnels peut également s'effectuer par la fonction de concaténation de matrices (voire de tableaux !) de dimensions inférieures avec la fonction cat

cat(d, mat1, mat2)

Concatène les 2 matrices mat1 et mat2 selon la d-ème dimension. Si d=1 (indice de ligne) => concaténation verticale. Si d=2 (indice de colonne) => concaténation horizontale. Si d=3 (indice de "profondeur") => création de "couches" suppémentaires ! Etc...

Ex:

Les fonctions ci-dessous permettent de connaître la dimension d'un tableau (2D, 3D, 4D...) et la "taille de chaque dimension" :
vect=size(tableau)
taille=size(tableau, dimension)
Retourne un vecteur-ligne vect dont le i-ème élément indique la taille de la i-ème dimension du tableau
Retourne la taille du tableau correspondant à la dimension spécifiée

Ex:

numel(tableau)       (NUMber of ELements)
Retourne le nombre d'éléments tableau. Identique à prod(size(tableau)) ou length(mat(:)), mais un peu plus "lisible"
Ex: pour le tableau B ci-dessus, numel(B) retourne donc 18
ndims(tableau)
Retourne la dimension tableau : 2 pour une matrice 2D et un vecteur ou un scalaire (vus comme des matrices dégénérées !), 3 pour un tableau 3D, 4 pour un tableau quadri-dimensionnel, etc... Identique à length(size(tableau))
Ex: pour le tableau B ci-dessus, ndims(B) retourne donc 3


Il est finalement intéressant de savoir, en matière d'échanges, qu'Octave permet de sauvegarder des tableaux multidimensionnels sous forme texte (utiliser save -text ...), ce que ne sait pas faire MATLAB.

4.5 Opérateurs matriciels sur tableaux

4.5.1 Opérateurs arithmétiques

Opérateurs de base


6:40 min
Présentation des opérateurs de base

La facilité d'utilisation et la puissance de MATLAB/Octave proviennent en particulier de ce qu'il est possible d'exprimer des opérations matricielles de façon très naturelle en utilisant directement les opérateurs arithmétiques de base (déjà présentés au niveau scalaire au chapitre "Opérateurs de base"). Nous décrivons ci-dessous l'usage de ces opérateurs dans un contexte matriciel (voir aussi help arith et help slash).

Opérateur ou fonction Description
+ ou fonction plus(m1,m2,m3,...)
     - ou fonction minus(m1,m2)
Addition et soustraction. Les arguments doivent être des vecteurs ou matrices de même dimension, à moins que l'un des deux ne soit un scalaire auquel cas l'addition/soustraction applique le scalaire sur tous les éléments du vecteur ou de la matrice.

Ex: [2 3 4]-[-1 2 3] retourne [3 1 1], et [2 3 4]-1 retourne [1 2 3]

* ou fonction mtimes(m1,m2,m3,...) Produit matriciel. Le nombre de colonnes de l'argument de gauche doit être égal au nombre de lignes de l'argument de droite, à moins que l'un des deux arguments ne soit un scalaire auquel cas le produit applique le scalaire sur tous les éléments du vecteur ou de la matrice.

Ex:
[1 2]*[3;4] ou [1 2]*[3 4]' produit le scalaire "11" (mais [1 2]*[3 4] retourne une erreur!)
2*[3 4] ou [3 4]*2 retournent [6 8]

.* ou fonction times(m1,m2,m3,...) Produit éléments par éléments. Les arguments doivent être des vecteurs ou matrices de même dimension, à moins que l'un des deux ne soit un scalaire (auquel cas c'est identique à l'opérateur *).

Ex: si m1=[1 2;4 6] et m2=[3 -1;5 3]
    • m1.*m2 retourne [3 -2 ; 20 18]
    • m1*m2 retourne [13 5 ; 42 14]
    • m1*2 ou m1.*2 retournent [2 4 ; 8 12]

kron Produit tensoriel de Kronecker
\ ou fonction mldivide(m1,m2) Division matricielle à gauche
A\B est la solution "X" du système linaire "A*X=B". On peut distinguer 2 cas :
  • Si "A" est une matrice carrée NxN et "B" est un vecteur colonne Nx1, A\B est équivalent à inv(A)*B et il en résulte un vecteur "X" de dimension Nx1
  • S'il y a surdétermination, c'est-à-dire que "A" est une matrice MxN où M>N et B est un vecteur colonne de Mx1, l'opération A\B s'effectue alors selon les moindres carrés et il en résulte un vecteur "X" de dimension Nx1
/ ou fonction mrdivide(m1,m2) Division matricielle (à droite)
B/A est la solution "X" du système "X*A=B" (où X et B sont des vecteur ligne et A une matrice). Cette solution est équivalente à B*inv(A) ou à (A'\B')'
./ ou fonction rdivide(m1,m2) Division éléments par éléments. Les 2 arguments doivent être des vecteurs ou matrices de même dimension, à moins que l'un des deux ne soit un scalaire auquel cas la division applique le scalaire sur tous les éléments du vecteur ou de la matrice. Les éléments de l'objet de gauche sont divisés par les éléments de même indice de l'objet de droite
.\ ou fonction ldivide(m1,m2) Division à gauche éléments par éléments. Les 2 arguments doivent être des vecteurs ou matrices de même dimension, à moins que l'un des deux ne soit un scalaire. Les éléments de l'objet de droite sont divisés par les éléments de même indice de l'objet de gauche.

Ex: 12./(1:3) et (1:3).\12 retournent tous les deux le vecteur [12 6 4]

^ ou fonction mpower Elévation à la puissance matricielle. Il faut distinguer les 2 cas suivants (dans lesquels "M" doit être une matrice carrée et "scal" un scalaire) :
  • M^scal : si scal est un entier>1, produit matriciel de M par elle-même scal fois ; si scal est un réel, mise en oeuvre valeurs propres et vecteurs propres
  • scal^M : mise en oeuvre valeurs propres et vecteurs propres
.^ ou fonction power ou .** Elévation à la puissance éléments par éléments. Les 2 arguments doivent être des vecteurs ou matrices de même dimension, à moins que l'un des deux ne soit un scalaire. Les éléments de l'objet de gauche sont élevés à la puissance des éléments de même indice de l'objet de droite
[,] ou horzcat
    [;] ou vertcat, cat
Concaténation horizontale, respectivement verticale (voir chapitre "Matrices" ci-dessus)
( ) Permet de spécifier l'ordre d'évaluation des expressions

4.5.2 Opérateurs relationnels et logiques

Les opérateurs relationnels et logiques, qui ont été présentées au chapitre "Opérateurs de base", peuvent aussi être utilisées sur des vecteurs et matrices. Elles s'appliquent alors à tous les éléments et retournent donc également des vecteurs ou des matrices.
      Ex: si l'on a a=[1 3 4 5] et b=[2 3 1 5], alors c = a==b ou c=eq(a,b) retournent le vecteur c=[0 1 0 1]

4.6 Quelques fonctions matricielles

4.6.1 Réorganisation de matrices

Fonction Description
Opérateur '
  ou fonction ctranspose
Transposition normale de matrices réelles et transposition conjuguée de matrices complexes. Si la matrice ne contient pas de valeurs complexes, ' a le même effet que .'

Ex: v=(3:5)' crée directement le vecteur colonne [3 ; 4 ; 5]

Opérateur .'
ou fonction transpose
Transposition non conjuguée de matrices complexes

Ex: si l'on a la matrice complexe m=[1+5i 2+6i ; 3+7i 4+8i], la transposition non conjuguée m.' fournit [1+5i 3+7i ; 2+6i 4+8i], alors que la transposition conjuguée m' fournit [1-5i 3-7i ; 2-6i 4-8i]

reshape(var,M,N) Cette fonction de redimensionnement retourne une matrice de M lignes x N colonnes contenant les éléments de var (qui peut être une matrice ou un vecteur). Les éléments de var sont lus colonne après colonne, et la matrice retournée est également remplie colonne après colonne. Le nombre d'éléments de var doit être égal à MxN, sinon la fonction retourne une erreur.

Ex: reshape([1:8],2,4) et reshape([1 5 ; 2 6 ; 3 7 ; 4 8],2,4) retournent [1 3 5 7 ; 2 4 6 8]

vec = mat(:) Déverse la matrice mat colonne après colonne sur le vecteur-colonne vec

Ex: si m=[1 2 ; 3 4] , alors m(:) retourne le vecteur-colonne [1 ; 3 ; 2 ; 4]

sort(var {,mode})

sort(var, d {,mode})

Fonction de tri par éléments (voir aussi la fonction unique décrite plus bas). Le mode de tri par défaut est 'ascend' (tri ascendant), à moins que l'on spécifie 'descend' pour un tri descendant
  • appliqué à un vecteur (ligne ou colonne), trie dans l'ordre de valeurs croissantes les éléments du vecteur
  • appliqué à une matrice var, trie les éléments à l'intérieur des colonnes (indépendemment les unes des autres)
  • si l'on passe le paramètre d=2, trie les éléments à l'intérieur des lignes (indépendemment les unes des autres)

Ex: si m=[7 4 6;5 6 3], alors sort(m) retourne [5 4 3 ; 7 6 6]
      sort(m,'descend') retourne [7 6 6 ; 5 4 3]
      et sort(m,2) retourne [4 6 7 ; 3 5 6]

sortrows(mat {,no_col}) Trie les lignes de la matrice mat dans l'ordre croissant des valeurs de la première colonne, ou dans l'ordre croissant des valeurs de la colonne no_col.
S'il s'agit d'une matrice cellulaire, les éléments de la colonne de tri doivent être de type chaîne !

Ex: en reprenant la matrice m de l'exemple précédent : sortrows(m) (identique à sortrows(m,1)) et sortrows(m,3) retournent [5 6 3 ; 7 4 6], alors que sortrows(m,2) retourne [7 4 6 ; 5 6 3]

fliplr(mat)
flipud(mat)
Retournement de la matrice mat par symétrie horizontale (left/right),
respectivement verticale (up/down)

Ex: fliplr('abc') retourne 'cba'
fliplr([1 2 3 ; 4 5 6]) => [3 2 1 ; 6 5 4], flipud([1 2 3 ; 4 5 6]) => [4 5 6 ; 1 2 3]

flip(tableau, dim)

flipdim(tableau, dim)

Retourne le tableau (qui peut avoir n'importe quelle dimension) selon sa dimension dim.
Noter que la fonction flipdim est appelée à disparaître.

Ex: flip([1 2 ; 3 4], 1) permute les lignes => retourne [3 4 ; 1 2]
flip([1 2 ; 3 4], 2) permute les colonnes => retourne [2 1 ; 4 3]

rot90(mat {,K}) Effectue une rotation de la matrice mat de K fois 90 degrés dans le sens inverse des aiguilles d'une montre. Si K est omis, cela équivaut à K=1

Ex: rot90([1 2 3 ; 4 5 6]) => retourne [3 6 ; 2 5 ; 1 4]
rot90([1 2 3 ; 4 5 6],-2) => retourne [6 5 4 ; 3 2 1]

permute, ipermute, tril, triu Autres fonctions de réorganisation de matrices...

4.6.2 Fonctions mathématiques sur tableaux

Les fonctions mathématiques présentées au chapitre "Fonctions de base" peuvent aussi être utilisées sur des vecteurs et matrices. Elles s'appliquent alors à tous les éléments et retournent donc également des vecteurs ou des matrices.
      Ex: si l'on définit la série (vecteur ligne) x=0:0.1:2*pi, alors y=sin(x) ou directement y=sin(0:0.1:2*pi) retournent
      un vecteur ligne contenant les valeurs du sinus de "0" à "2*pi" avec un incrément de "0.1"

4.6.3 Calcul matriciel et statistiques

Fonctions mathématiques, statistiques et de calcul matriciel


8:15 min
Présentation des fonctions mathématiques, statistiques et de calcul matriciel

On obtient la liste des fonctions matricielles avec help elmat et help matfun.

Fonction Description
norm(vec) Calcule la norme (longueur) du vecteur vec.
On peut aussi passer à cette fonction une matrice (voir help)
dot(vec1,vec2) Calcule la produit scalaire des 2 vecteurs vec1 et vec2 (ligne ou colonne). Equivalent à vec1 * vec2' s'il s'agit de vecteurs-ligne, ou à vec1' * vec2 s'il s'agit de vecteurs-colonne
On peut aussi passer à cette fonction des matrices (voir help)
cross(vec1,vec2) Calcule la produit vectoriel (en 3D) des 2 vecteurs vec1 et vec2 (ligne ou colonne, mais qui doivent avoir 3 éléments !).
inv(mat) Inversion de la matrice carrée mat. Une erreur est produite si la matrice est singulière (ce qui peut être testé avec la fonction cond qui est plus approprié que le test du déterminant)
det(mat) Retourne le déterminant de la matrice carrée mat
trace(mat) Retourne la trace de la matrice mat, c'est-à-dire la somme des éléments de sa diagonale principale
rank(mat) Retourne le rang de la matrice mat, c'est-à-dire le nombre de lignes ou de colonnes linéairement indépendants
min(var {,d})
    max(var {,d})
Appliquées à un vecteur ligne ou colonne, ces fonctions retournent le plus petit, resp. le plus grand élément du vecteur. Appliquées à une matrice var, ces fonctions retournent :
  • si le paramètre d est omis ou qu'il vaut 1 : un vecteur ligne contenant le plus petit, resp. le plus grand élément de chaque colonne de var
  • si le paramètre d vaut 2 : un vecteur colonne contenant le plus petit, resp. le plus grand élément de chaque ligne de var
  • ce paramètre d peut être supérieur à 2 dans le cas de "tableaux multidimensionnels" (voir plus bas)
sum(var {,d})
    prod(var {,d})
Appliquée à un vecteur ligne ou colonne, retourne la somme ou le produit des éléments du vecteur. Appliquée à une matrice var, retourne un vecteur ligne (ou colonne suivant la valeur de d, voir plus haut sous min/max) contenant la somme ou le produit des éléments de chaque colonne (resp. lignes) de var

Ex: prod([2 3;4 3] {,1}) retourne le vecteur ligne [8 9], prod([2 3;4 3],2) retourne le vecteur colonne [6 ; 12] et prod(prod([2 3;4 3])) retourne le scalaire 72

cumsum(var {,d})
cumprod(var {,d})
Réalise la somme partielle (cumulée) ou le produit partiel (cumulé) des éléments de var. Retourne une variable de même dimension que celle passée en argument (vecteur -> vecteur, matrice -> matrice)

Ex: cumprod(1:10) retourne les factorielles de 1 à 10, c-à-d. [1 2 6 24 120 720 5040 40320 362880 3628800]

mean(var {,d}) Appliquée à un vecteur ligne ou colonne, retourne la moyenne arithmétique des éléments du vecteur. Appliquée à une matrice var, retourne un vecteur ligne (ou colonne suivant la valeur de d, voir plus haut sous min/max) contenant la moyenne arithmétique des éléments de chaque colonne (resp. lignes) de var. Un troisième paramètre, spécifique à Octave, permet de demander le calcul de la moyenne géométrique ('g') ou de la moyenne harmonique ('h').
std(var {,f{,d}}) Appliquée à un vecteur ligne ou colonne, retourne l'écart-type des éléments du vecteur. Appliquée à une matrice var, retourne un vecteur ligne (ou colonne suivant la valeur de d, voir plus haut sous min/max) contenant l'écart-type des éléments de chaque colonne (resp. lignes) de var.
Attention : si le flag "f" est omis ou qu'il vaut "0", l'écart-type est calculé en normalisant par rapport à "n-1" (où n est le nombre de valeurs) ; s'il vaut "1" on normalise par rapport à "n"
median(var {,d}) Calcule la médiane
cov Retourne vecteur ou matrice de covariance
eig, eigs, svd, svds, cond, condeig... Fonctions en relation avec vecteurs propres et valeurs propres (voir help)

lu, chol, qr, qzhess,
schur, svd, housh, krylov...
Fonctions en relation avec les méthodes de décomposition/factorisation de type :
- LU, Cholesky, QR, Hessenberg,
- Schur, valeurs singulières, householder, Krylov...

4.6.4 Fonctions de recherche

Fonction Description
vec = find(mat)

[v1, v2 {, v3 }] = find(mat)

Recherche des indices des éléments non-nuls de la matrice mat
• Dans la 1ère forme, MATLAB/Octave retourne un vecteur-colonne vec d'indices à une dimension en considérant les éléments de la matrice mat colonne après colonne
• Dans la seconde forme, les vecteurs-colonne v1 et v2 contiennent respectivement les numéros de ligne et de colonne des éléments non nuls ; les éléments eux-mêmes sont éventuellement déposés sur le vecteur-colonne v3

Remarques importantes :
• À la place de mat vous pouvez définir une expression logique (voir aussi le chapitre "Indexation logique" ci-dessous) ! Ainsi par exemple find(isnan(mat)) retournera un vecteur-colonne contenant les indices de tous les éléments de mat qui sont indéterminés (égaux à NaN).
• Le vecteur vec résultant permet ensuite d'adresser les éléments concernés de la matrice, pour les récupérer ou les modifier. Ainsi par exemple mat(find(mat<0))=NaN remplace tous les éléments de mat qui sont inférieurs à 0 par la valeur NaN.

Ex 1: soit la matrice m=[1 2 ; 0 3]
find(m) retourne [1 ; 3 ; 4] (indices des éléments non-nuls)
find(m<2) retourne [1 ; 2] (indices des éléments inférieurs à 2)
m(find(m<2))=-999 retourne [-999 2 ; -999 3] (remplacement des valeurs inférieures à 2 par -999)
[v1,v2,v3]=find(m) retourne indices v1=[1 ; 1 ; 2] v2=[1 ; 2 ; 2], et valeurs v3=[1 ; 2 ; 3]

Ex 2: soit le vecteur v=1:10
v(find(and(v>=4, v<=6))) = v(find(and(v>=4, v<=6))) + 30 ajoute 30 à tous les éléments dont la valeur est comprise entre 4 et 6, donc modifie ici v et retourne v=[1 2 3 34 35 36 7 8 9 10]

unique(mat) Retourne un vecteur contenant les éléments de mat triés dans un ordre croissant et sans répétitions. Si mat est une matrice ou un vecteur-colonne, retourne un vecteur-colonne ; sinon (si mat est un vecteur-ligne), retourne un vecteur-ligne. (Voir aussi les fonctions sort et sortrows décrites plus haut).
mat peut aussi être un tableau cellulaire (contenant par exemple des chaînes)

Ex:
• si m=[5 3 8 ; 2 9 3 ; 8 9 1], la fonction unique(m) retourne alors [1 ; 2 ; 3 ; 5 ; 8 ; 9]
• si a={'pomme','poire';'fraise','poire';'pomme','fraise'}, alors unique(a) retourne {'fraise';'poire';'pomme'}

intersect(var1,var2)

setdiff(var1,var2)

union(var1,var2)

Retourne un vecteur contenant, de façon triée et sans répétitions, les éléments qui :
  • intersect: sont communs à var1 et var2
  • setdiff: existent dans var1 mais n'existent pas dans var2
  • union: existent dans var1 et/ou dans var2
Le vecteur résultant sera de type colonne, à moins que var1 et var2 soient tous deux de type ligne.

var1 et var2 peuvent être des tableaux cellulaires (contenant par exemple des chaînes)

Sous Octave, var1 et var2 peuvent être des matrices numériques, alors que MATLAB est limité à des vecteurs numériques

Ex:
• si a={'pomme','poire';'fraise','cerise'} et b={'fraise','abricot'}, alors
      - setdiff(a,b) retourne {'cerise';'poire';'pomme'}
      - union(m1,m2) retourne {'abricot';'cerise';'fraise';'poire';'pomme'}
si m1=[3 4 ; -1 6 ; 6 3] et m2=[6 -1 9], alors intersect(m1,m2) retourne [-1 6]

4.6.5 Fonctions logiques

Outre les fonctions logiques de base (qui, pour la plupart, s'appliquent aux matrices : voir chapitre "Fonctions de base"), il existe des fonctions logiques spécifiques aux matrices décrites ici.

Fonction Description
isequal(mat1,mat2) Retourne le scalaire vrai ("1") si tous les éléments de mat1 sont égaux aux éléments de mat2, faux ("0") sinon
isscalar(var)
isvector(var)
Retourne le scalaire vrai si var est un scalaire, faux si c'est un vecteur ou tableau ≥ 2-dim
Retourne le scalaire vrai si var est un vecteur ou scalaire, faux si tableau ≥ 2-dim
iscolumn(var)
isrow(var)
Retourne le scalaire vrai si var est un vecteur colonne ou scalaire, faux si tableau ≥ 2-dim
Retourne le scalaire vrai si var est un vecteur ligne ou scalaire, faux si tableau ≥ 2-dim
mat3 = ismember(mat1,mat2) Cherche si les valeurs de mat1 sont présentes dans mat2 : retourne une matrice mat3 de la même dimension que mat1mat3(i,j)=1 si la valeur mat1(i,j) a été trouvée quelque-part dans dans mat3, sinon mat3(i,j)=0. Les matrices (ou vecteurs) mat1 et mat2 peuvent avoir des dimensions différentes.
mat1 et mat2 peuvent être des tableaux cellulaires (contenant par exemple des chaînes)

Ex: Si a=[0 1 2 ; 3 4 5] et b=[2 4;6 8;10 12;14 16;18 20], la fonction ismember(a,b) retourne alors [0 0 1 ; 0 1 0]
Si a={'pomme','poire';'fraise','cerise'} et b={'fraise','abricot'}, alors ismember(a,b) retourne [0 0 ; 1 0]

any(vec) et all(vec)

any(mat) et all(mat)

Retourne le scalaire vrai si l'un au moins des éléments du vecteur vec n'est pas nul, respectivement si tous les éléments ne sont pas nuls

Comme ci-dessus, mais analyse les colonnes de mat et retourne ses résultats sur un vecteur ligne

4.7 Indexation logique

Indexation logique


06:43 min
L'indexation logique est un mécanisme particulièrement efficace, car vectorisé, permettant de remplacer très avantageusement les boucles dans certaines situation, et par conséquent de gagner du temps d'exécution.
Cette technique, qui s'applique à des tableaux de dimension quelconque (i.e. vecteurs, tableaux 2D, tableaux à N-dimension), consiste à indexer des tableaux non pas par des indices (numéro de ligne, de colonne...), mais par des "tableaux logiques", c'est-à-dire des tableaux contenant des valeurs logiques (vrai ou faux). Elle permet de modifier des tableaux ou de récupérer certaines valeurs d'un tableau. Elle s'applique non seulement aux tableaux de nombre (virgule flottante, integer) mais aussi aux chaînes, tableaux cellulaires, etc...

Introduction

Sous le terme d' "indexation logique" (logical indexing, logical subscripting) on entend la technique d'indexation par une matrice logique, c'est-à-dire une matrice booléenne (i.e. exclusivement composée de valeurs true ou false). Ces "matrices logiques d'indexation" résultent le plus souvent :

Il faudrait en principe que les dimensions de la matrice logique soient identiques à celles de la matrice que l'on indexe (cela engendrant, dans le cas contraire, des différences de comportement entre MATLAB et Octave...).

L'avantage de l'indexation logique réside dans le fait qu'il s'agit d'un mécanisme vectorisé (donc bien plus efficaces qu'un traitement basé sur des boucles for ou while).

Dans ce qui vient d'être dit, le terme "matrice" désigne bien entendu également des tableaux multidimensionnels ou de simples vecteurs (ligne ou colonne). Et encore mieux : l'indexation logique peut aussi être appliquée à des structures et des tableaux cellulaires ! (Voir les exemples spécifiques dans les chapitres traitant de ces deux types de données).

Utilisation de l'indexation logique

vec = mat(mat_log)
Examine la matrice mat à travers le "masque" de la matrice logique mat_log (de mêmes dimensions que mat), et retourne un vecteur-colonne vec comportant les éléments de mat(i,j) où mat_log(i ,j)=true. Les éléments sont déversés dans vec en examinant la matrice mat colonne après colonne.

Remarques importantes :
mat_log peut être (et est souvent !) une expression logique basée sur la matrice mat elle-même. Ainsi, par exemple, mat(mat>val) (indexation de la matrice mat par la matrice logique produite par mat>val) retournera un vecteur-colonne contenant tous les éléments de mat qui sont supérieurs à val.
• On peut rapprocher cette fonctionnalité de la fonction find décrite plus haut. Pour reprendre l'exemple ci-dessus, mat(find(mat>val)) (indexation de la matrice mat par le vecteur d'indices à une dimension produit par find(mat>val)) retournerait également les éléments de mat qui sont supérieurs à val.

Ex:
• Soit la matrice m=[5 3 8 ; 2 9 3 ; 8 9 1] ; m(m>3) retourne le vecteur-colonne [5 ; 8 ; 9 ; 9 ; 8] (contenant donc les éléments supérieurs à 3)
• Si l'on construit manuellement une matrice logique m_log1=[1 0 1;0 1 0;1 1 0], on ne peut pas faire m(m_log1), car m_log1 n'est alors pas considéré par MATLAB/Octave comme une matrice logique (booléenne) mais comme une matrice de nombres... et MATLAB/Octave essaie alors de faire de l'indexation standard avec des indices nuls, d'où l'erreur qui est générée ! Il faut plutôt faire m_log2=logical(m_log1) (ou m_log2=(m_log1~=0)), puis m(m_log2). On peut bien entendu aussi faire directement m(logical(m_log1)) ou m(logical([1 0 1;0 1 0;1 1 0])). En effet, regardez avec la commande whos, les types respectifs de m_log1 et de m_log2 !
• Pour éliminer les valeurs indéterminées (NaN) d'une série de mesures s=[-4 NaN -2.2 -0.9 0.3 NaN 1.5 2.6] en vue de faire un graphique, on fera s=s(~isnan(s)) ou s=s(isfinite(s)) qui retournent toutes deux s=[-4 -2.2 -0.9 0.3 1.5 2.6]

mat(mat_log) = valeur
Utilisée sous cette forme-là, l'indexation logique ne retourne pas un vecteur d'éléments de mat, mais modifie certains éléments de la matrice mat : tous les éléments de mat(i,j) où mat_log(i ,j)=true seront remplacés par la valeur spécifiée. Comme cela a été vu plus haut, la matrice logique mat_log devrait avoir les mêmes dimensions que mat, et mat_log peut être (et est souvent !) une expression logique basée sur la matrice mat elle-même.

Ex:
• En reprenant la matrice m=[5 3 8 ; 2 9 3 ; 8 9 1] de l'exemple ci-dessus, l'instruction m(m<=3)=-999 modifie la matrice m en remplaçant tous les éléments inférieurs où égaux à 3 par -999 ; celle-ci devient donc [5 -999 8 ; -999 9 -999 ; 8 9 -999]
• L'indexation logique peut aussi être appliquée à des chaînes de caractères pour identifier ou remplacer des caractères. Soit la chaîne str='Bonjour tout le monde'. L'affectation str(isspace(str))='_' remplace dans str tous les caractères espace par le caractère '_' et retourne donc str='Bonjour_tout_le_monde'

4.8 Chaînes de caractères

Chaînes de caractères


16:51 min
Cette vidéo présente l'usage des chaînes de caractères basées sur le type char. Nous voyons notamment comment :
• définir des chaînes de caractères
• les concaténer
• comparer des chaînes
• faire des recherches et substitutions dans les chaînes
Il faut noter qu'il existe encore 2 autres types d'objets que l'on peut utiliser pour manipuler des chaînes :
• le type tableau cellulaires, très flexible, que l'on présente dans une autre vidéo
• le type string (qui fait son apparition sous MATLAB 2017 mais reste à ce jour très peu utilisé)

4.8.1 Généralités

Comme dans tous les langages, MATLAB/Octave permet de manipuler du texte, c'est à dire des "chaînes de caractères". On dispose pour cela de différents types d'objets :
var_char = 'chaîne de caractères'
Lorsque l'on affecte une chaîne à une variable de type char, la chaîne doit être délimitée par des apostrophes.
Si la chaîne contient elle-même des apostrophes, le mécanisme d'échappement consiste à dédoubler les apostrophes dans la chaîne.

Ex: section = 'Sciences et ingénierie de l''environnement'

var_char(i:j)
En terme de stockage, les chaînes de type char sont des vecteurs-ligne dans lesquels les différents caractères de la chaîne correspondent aux éléments du vecteur. Avec la syntaxe ci-dessus on récupère la partie de la chaîne var_char comprise entre le i-ème et le j-ème caractère.

Ex: suite à la définition ci-dessus, section(13:22) retourne la chaîne "ingénierie", et section(29:end) retourne la chaîne "environnement"

a) var_char = "chaîne de caractères"
b) var_string = "chaîne de caractères"   (depuis MATLAB R2017)
Lorsque l'on délimite la chaîne par des guillemets au lieu d'apostrophes :

a) sous Octave : cela crée également une variable de type char ; cette notation permet de définir, dans la chaîne, des caractères spéciaux ainsi :
    \t pour le caractère tab
    \n pour un saut à la ligne ("newline") ; mais la chaîne reste cependant un vecteur ligne et non une matrice
    \" pour le caractère "
    \' pour le caractère '
    \\ pour le caractère \
Ex: str = "Texte\ttabulé\net sur\t2 lignes"
  pour obtenir l'équivalent sous MATLAB (ou Octave) : str = sprintf('Texte\ttabulé\net sur\t2 lignes')

b) Sous MATLAB, la délimitation de chaîne par guillemets crée un objet de type string. Ce type, qui fait donc son apparition sous MATLAB R2017, n'a rien à voir avec le type char, et nous le présenterons ultérieurement dans ce support de cours.

[s1 s2 ...]
La concaténation de chaînes s'opère de la même manière que pour des vecteurs/tableaux.
Avec la syntaxe ci-dessus, on concatène donc horizontalement les chaînes s1, s2 ...

Ex: soit s1=' AAA ', s2='CCC ', s3='EEE ' ; avec [s1 s2 s3] on retourne " AAA CCC EEE "

strcat(s1,s2 ...)
Concatène horizontalement les chaînes s1, s2... en supprimant les caractères espace terminant les chaînes s1, s2... ("trailing blanks") mais pas les espace commençant celles-ci !

Ex: soit s1=' AAA ', s2='CCC ', s3='EEE ' ; avec strcat(s1,s2,s3) on retourne " AAACCCEEE"

mat_char = strvcat(s1,s2 ...)
Concatène verticalement les chaînes s1, s2 ... Produit donc une matrice de chaînes de caractères mat_char contenant la chaîne s1 en 1ère ligne, s2 en seconde ligne, etc... Les chaînes éventuellement vides sont ignorées, c'est-à-dire ne produisent dans ce cas pas de lignes blanches (contrairement à char ou str2mat).

Remarque importante: pour produire cette matrice mat_char, MATLAB/Octave complètent automatiquement chaque ligne par le nombre nécessaire de caractères espace ("trailing blanks") afin que toutes les lignes soient de la même longueur (même nombre d'éléments, ce qui est important dans le cas où les chaînes s1, s2 ... n'ont pas le même nombre de caractères). Cet inconvénient n'existe pas si l'on recourt à des tableaux cellulaires plutôt qu'à des matrices de chaînes.
On peut convertir une matrice de chaînes en un "tableau cellulaire de chaînes" avec la fonction cellstr.

Ex:
• en utilisant les variables s1, s2, s3 de l'exemple précédent, mat=strvcat(s1,s2,s3) retourne la matrice de chaînes de dimension 3x16 caractères :
    Jules Dupond    
    Albertine Durand
    Robert Muller   
    par la suite mat=strvcat(mat,'xxxx') permettrait d'ajouter une ligne supplémentaire à cette matrice
• pour stocker ces chaînes dans un tableau cellulaire, on utiliserait tabl_cel={s1;s2;s3} ou tabl_cel={'Jules Dupond';'Albertine Durand';'Robert Muller'}
• ou pour convertir la matrice de chaîne ci-dessus en un tableau cellulaire, on utilise tabl_cel=cellstr(mat)

mat_char = char(s1,s2 ...)
mat_char = str2mat(s1,s2 ...)
mat_char = [s1 ; s2 ...]
Concatène verticalement les chaînes s1, s2... de la même manière que strvcat, à la nuance près que les éventuelles chaînes vides produisent dans ce cas une ligne vide. La 3ème forme ne fonctionne que sous Octave (MATLAB générant une erreur si les chaînes s1, s2... n'ont pas toutes la même longueur)
mat_char(i,:)
mat_char(i,j:k)
Retourne la i-ème ligne du tableau de chaînes mat_char,
respectivement la sous-chaîne de cette ligne allant du j-ème au k-ème caractère
Ex: en reprenant la matrice "mat" de l'exemple ci-dessus, mat(2,:) retourne "Albertine Durand", et mat(3,8:13) retourne "Muller"

4.8.2 Usage de caractères spéciaux (accentués...) dans des variables, scripts/fonctions, fichiers de données

Caractères spéciaux dans les chaînes

Tant que l'on fait usage des caractères "imprimables" de la table ASCII 7-bit (à 128 caractères), il n'y a aucun souci particulier sous MATLAB ou Octave, que ce soit au niveau des chaînes, de l'écriture de code ou des entrées/sorties fichier. Il faut simplement remarquer que s'agissant de MATLAB chaque caractère occupe en mémoire 2 octets, contre 1 octet sous Octave (ce que vous pouvez vérifier avec la commande whos var_char). Mais dans les deux cas le i-ème caractère d'une chaîne var_char s'obtient par var_char(i).
Les choses se compliquent un peu sous Octave lorsqu'on utilise des caractères spéciaux, par exemple les caractères accentués. Ceux-ci sont alors stockés sur 2 octets, contrairement aux caractères non accentués (ASCII 7-bit) stockés sur 1 octet, et cela peut poser des problèmes lorsqu'on accède aux caractères de la chaîne par leur indices... et des incompatibilités avec MATLAB.

Ex: soit la variable de type char vchar='123éô678' contenant donc 2 caractères accentués ;
- sous Octave celle-ci n'occupe pas 8 octets mais 10, car les caractères "é" et "o" en occupent chacun 2 (encodés en UTF-8) ;
- alors que vchar(2:3) retourne la sous-chaîne "23" (comme on s'y attend logiquement),
  si l'on fait vchar(4) on n'obtient pas "é" mais quelque-chose de non imprimable ; pour récupérer "é" il faut faire vchar(4:5) !
- de façon analogue il faudrait donc faire vchar(4:7) pour récupérer la chaîne "éô" !
- on constate donc que ce sont les octets qui sont indicés et non pas les caractères :-(
- de même ce que length(vchar) retourne, c'est le nombre d'octets (10) et non pas la longueur effective de la chaîne (8)
L'exemple ci-dessus montre qu'il faut être très prudent sous Octave lorsqu'on accède, par leurs indices/positions, aux caractères d'une chaîne susceptible de contenir des caractères spéciaux. Par contre la plupart des fonctions de manipulation de chaînes présentées aux chapitres suivants ne posent pas de problème. Par exemple, pour poursuivre l'exemple ci-dessus, la fonction strrep(vchar, 'éô, '45') fonctionne comme il faut et retourne bien la chaîne "12345678" (qui occupe alors 8 octets). De même l'usage de caractères accentués dans des graphiques ne semble plus poser de problèmes depuis Octave 5.
De façon générale, la situation de Octave par rapport aux support des caractères spéciaux et encodage est décrite dans cette page du Wiki Octave.

Caractères spéciaux dans le code (scripts et fonctions)

Dans l'interface graphique de Octave GUI, sous Edit>Preferences>Editor>File handling se trouve un menu déroulant "Text encoding used for loading and saving" qui permet de spécifier quel doit être l'encodage des M-files que vous éditez avec l'éditeur intégré. Notez que par défaut sous Windows ce réglage est à "SYSTEM" (qui semble correspondre à ISO-8859-1), alors que sous macOS et Linux il est à "UTF-8" !

S'agissant de MATLAB, un tel réglage de l'encodage des M-files par l'éditeur intégré n'existe pas. Il existe deux fonctions, slCharacterEncoding(encodage) et feature, mais elles sont un peu obscures et sans grand effet... C'est donc ici MATLAB qui est le parent pauvre, et si l'on veut faire usage d'encodages particuliers (UTF-8...), on est actuellement contraint d'utiliser des éditeurs externes, et l'affichage des caractères spéciaux dans la fenêtre console peut en souffrir !

Encodage lors des entrées-sorties sur fichiers

Lorsqu'un programme MATLAB/Octave réalise des écritures dans un fichier, l'encodage de celui-ci correspondra au type d'encodage du script ! S'agissant de Octave, l'encodage des fichiers sera donc par défaut "UTF-8" sous macOS et Linux, et "ISO-8859-1" sous Windows ; mais cela peut être changé comme décrit plus haut. MATLAB n'offre actuellement pas cette souplesse.

Pour conclure, on peut dire que la gestion des caractères spéciaux (accentués...) n'est actuellement pas optimum, autant sous MATLAB qe Octave (avec des difficultés qui ne sont pas les mêmes selon le logiciel utilisé). Ces problèmes sont en outre susceptibles d'engendrer des incompatibilités au niveau de la portabilité MATLAB↔Octave.

4.8.3 Fonctions générales relatives aux chaînes

Sous MATLAB, help strfun donne la listes des fonctions relatives aux chaînes de caractères.

Notez que, pour la plupart des fonctions ci-dessous, l'argument string désigne une chaîne de type char, mais dans bien des cas ce peut aussi être un tableau cellulaire de chaînes !

Fonction Description
length(string) Retourne le nombre de caractères de la chaîne string
deblank(string)
strtrim(string)

blanks(n)

Supprime les car. espace terminant string (trailing blanks)
Supprime les car. espace débutant et terminant string (leading & trailing blanks)

Retourne une chaîne de n caractères espace

string(offset:offset+(length-1))

substr(string, offset {, length})

Retourne de la chaîne string la sous-chaîne débutant à la position offset et de longueur length
Avec la fonction substr :
- si length n'est pas spécifié, la sous-chaîne s'étend jusqu'à la fin de string
- si l'on spécifie un offset négatif, le décompte s'effectue depuis la fin de string

Ex: si l'on a str='abcdefghi', alors
substr(str,3,4) retourne 'cdef', identique à str(3:3+(4-1))
substr(str,3) retourne 'cdefghi', identique à str(3:end)
substr(str,-3) retourne 'ghi', identique à str(end-3+1:end)

strfind(cell_string,s1)

ou findstr(string,s1 {,overlap})

Retourne, sur un vecteur ligne, la position dans string de toutes les chaînes s1 qui ont été trouvées. Si ces fonctions ne trouvent pas de sous-chaîne s1, elles retournent un tableau vide []

Noter que la fonction findstr est appelée à disparaître. Elle ne peut en outre qu'analyser des chaînes simples mais pas des tableaux cellulaires de chaînes, contrairement à strfind.
Si le paramètre optionnel overlap est présent et vaut 0, findstr ne tient pas compte des occurences superposées (voir exemple ci-dessous)

Ex: si l'on a str='Bla bla bla *xyz* bla etc...', alors
star=strfind(str,'*') retournent le vecteur [13 17] indiquant la position des "*" dans la variable "str"
str(star(1)+1:star(2)-1) retourne la sous-chaîne de "str" se trouvant entre "*", soit "xyz"
length(strfind(str,'bla')) retourne le nombre d'occurences de "bla" dans "str", soit 3
isempty(strfind(str,'ZZZ')) retourne "vrai" (valeur 1), car la sous-chaîne "ZZZ" n'existe pas dans "str"
strfind('abababa','aba') retourne [1 3 5], alors que findstr('abababa','aba',0) retourne [1 5]

strmatch(mat_string,s1 {,'exact'} ) Retourne un vecteur-colonne contenant les numéros des lignes de la matrice de chaîne mat_string qui 'commencent' par la chaîne s1. En ajoutant le paramètre 'exact', ne retourne que les numéros des lignes qui sont 'exactement identiques' à s1.

Ex: strmatch('abc', str2mat('def abc','abc','yyy','abc xxx')) retourne [2 ; 4]
En ajoutant le paramètre 'exact', ne retourne que [ 2 ]

regexp(mat_string, pattern)

regexpi(mat_string, pattern)

Effectue une recherche dans mat_string à l'aide du motif défini par l'expression régulière pattern (extrêmement puissant... lorsque l'on maîtrise les expression régulières Unix). La seconde forme effecte une recherche "case insensitive" (ne différenciant pas majuscules/minuscules).
strrep(string,s1,s2) Retourne le résultat du remplacement dans la chaîne string de toutes les occurrences de s1 par s2

Ex: strrep('abc//def//ghi/jkl','//','|') retourne "abc|def|ghi/jkl"

regexprep(s1, pattern, s2) Effectue un remplacement, dans s1, par s2 là où l'expression régulière pattern est satisfaite
erase(string, s1) Retourne le résultat de la suppression dans la chaîne string de toutes les occurrences de s1. Noter que string et s1 peuvent être non seulement des chaînes mais aussi des tableaux cellulaires de chaînes ou des tableaux de caractères.

Ex: erase('abc def abcxyz', 'abc') retourne ' def xyz'
erase('abc def abcxyz', {'abc', 'xyz'}) retourne ' def '
erase({'abc123', 'xyz456'}, {'abc', 'xyz'}) retourne {'123', '456'}

strsplit(string,str_sep) Découpe la chaîne string selon le(s) séparateur(s) str_sep (qui peut être une chaîne ou un vecteur cellulaire de chaînes), et retourne les sous-chaînes résultantes sur un vecteur cellulaire ligne

Ex: strsplit('ab*c//def//ghi/jkl','//') retourne {'ab*c', 'def', 'ghi/jkl'}
et strsplit('ab*c//def//ghi/jkl',{'//', '/', '*'}) retourne {'ab', 'c', 'def', 'ghi', 'jkl'}

ostrsplit(string,cars_sep) Propre à Octave, cette fonction découpe la chaîne string en utilisant les différents caractères de cars_sep, et retourne les sous-chaînes résultantes sur un vecteur cellulaire de chaînes.

Ex: ostrsplit('abc/def/ghi*jkl','/*') retourne le vecteur cellulaire {'abc','def','ghi','jkl'}

[debut fin]=strtok(string,delim) Découpe la chaîne string en 2 parties selon le(s) caractère(s) de délimitation énuméré(s) dans la chaîne delim ("tokens") : sur debut est retournée la première partie de string (caractère de délimitation non compris), sur fin est retournée la seconde partie de string (commençant par le caractère de délimitation).
Si le caractère de délimitation est tab, il faudra entrer ce caractère tel quel dans delim (et non pas '\t' qui serait interprété comme les 2 délimiteurs \ et t).
Si ce que l'on découpe ainsi ce sont des nombres, il faudra encore convertir les chaînes résultantes en nombres avec la fonction str2num (voir plus bas).

Ex: [debut fin]=strtok('Abc def, ghi.', ',:;.') découpera la chaîne en utilisant les délimiteurs de phrase habituels et retournera, dans le cas présent, debut='Abc def' et fin=', ghi.'

string = sprintf(format, var1 {, var2...})
var|mat = sscanf(string, format {,size})
Écriture formatée ou lecture formatée de chaînes.
Pour plus de détails, voir le chapitre "Entrées-sorties formatées".
[var1, var2... ] =
strread(string,format {,n} {,'delimiter',delimiteur})
Découpe la chaîne string en fonction du format spécifié (et éventuel delimiteur), et dépose le résultat sur plusieurs variables var1, var2... de types découlant des spécifications de format.
Pour plus de détails, voir le chapitre "Entrées-sorties formatées".
strjust(string,'left|center|right') Justifie la chaîne ou la matrice de chaîne var à gauche, au centre ou à droite. Si l'on ne passe à cette fonction que la chaîne, la justification s'effectue à droite
sortrows(mat_string) Trie par ordre alphabétique croissant les lignes de la matrice de chaînes mat_string
vect_log = string1==string2 Comparaison caractères après caractères de 2 chaînes string1 et string2 de longueurs identiques (retourne sinon une erreur !). Retourne un vecteur logique (composé de 0 et de 1) avec autant d'élément que de caractères dans chaque chaîne.
Pour tester l'égalité exacte de chaînes de longueur indéfinie, utiliser plutôt strcmp ou isequal (voir ci-dessous).
strcmp(string1,string2) ou isequal(string1,string2)

strcmpi(string1,string2)

strncmp(string1,string2,n)
strncmpi(string1,string2,n)

Compare les 2 chaînes string1 et string2: retourne 1 si elles sont identiques, 0 sinon.

La fonction strcmpi ignore les différences entre majuscule et minuscule ("casse")

Ne compare que les n premiers caractères des 2 chaînes
La fonction strncmpi ignore les différences entre majuscule et minuscule ("casse")

ischar(var)

isletter(string)

isspace(string)

Retourne 1 si var est une chaîne de caractères, 0 sinon. Ne plus utiliser isstr qui va disparaître.

Retourne un vecteur de la taille de string avec des 1 là où string contient des caractères de l'alphabet, et des 0 sinon.

Retourne un vecteur de la taille de string avec des 1 là où string contient des caractères de séparation (espace, tab, "newline", "formfeed"), et des 0 sinon.

isstrprop(var, propriete) Test les propriétés de la chaîne var (alphanumérique, majuscule, minuscule, espaces, ponctuation, chiffres décimaux/hexadécimaux, caractères de contrôle...)
Sous Octave, implémenté depuis la version 3.2.0

4.8.4 Fonctions de conversion relatives aux chaînes

Fonction Description
lower(string)
    upper(string)
Convertit la chaîne string en minuscules,
respectivement en majuscules
double(string) Convertit les caractères de la chaîne string en leurs codes décimaux selon la table ASCII ISO-Latin-1

Ex: double('àéèçâêô') retourne le vecteur [ 224 233 232 231 226 234 244 ] (code ASCII de ces caractères accentués)

char(var) Convertit les nombres de la variable var en caractères (selon encodage 8-bits ISO-Latin-1)

Ex: char(224) retourne le caractère "à", char([233 232]) retourne la chaîne "éè"

sprintf(format,variable(s)...) Permet de convertir un(des) nombre(s) en une chaîne (voir chapitre "Entrées-sorties")
Voir aussi les fonctions int2str et num2str (qui sont cependant moins flexibles)
num2str(var {,precision}) Convertit le(s) nombre(s) de var en chaîne. Le paramètre precision permet de définir le nombre de chiffres significatifs.
Si var est un scalaire ou un vecteur ligne, le résultat sera une chaîne. Si var est un tableau 2D, le résultat sera un tableau de chaînes.
Pour un paramétrage plus fin de la conversion, on utilisera la fonction sprintf ci-dessus.

Ex: num2str([3.4, 6, pi], 8) retourne la chaîne "3.4       6       3.1415927"

mat2str(mat {,n}) Convertit la matrice mat en une chaîne de caractère incluant les crochets [ ] et qui serait dont "évaluable" avec la fonction eval (voir ci-dessous). L'argument n permet de définir la précision (nombre de chiffres). Cette fonction peut être intéressante pour sauvegarder une matrice sur un fichier (en combinaison avec fprintf, voir chapitre "Entrées-sorties").

Ex: mat2str(eye(3,3)) produit la chaîne "[1 0 0;0 1 0;0 0 1]"

sscanf(string,format) Permet de récupérer le(s) nombre(s) se trouvant dans la chaîne string (voir chapitre "Entrées-sorties")
str2num(string) Convertit en nombres le(s) nombre(s) se trouvant dans la chaîne string.
Pour des possibilités plus élaborées, on utilisera la fonction sscanf ci-dessus.

Ex: str2num('12 34 ; 56 78') retourne la matrice [12 34 ; 56 78]

eval(expression) Évalue (exécute) l'expression MATLAB/Octave spécifiée

Ex: si l'on a une chaîne str_mat='[1 3 2 ; 5.5 4.3 2.1]', l'expression eval(['x=' str_mat]) permet d'affecter les valeurs de cette chaîne à la matrice x

4.9 Structures (records)

Structures


09:13 min
Lorsqu'il s'agit de stocker des données structurées, c'est-à-dire des objets composés de différents champs (par exemple des personnes, avec des champs tels que leur nom, prénom, année de naissance, adresse...), le type de donnée "structure" (parfois dénommé record ou enregistrement), que nous présentons dans cette vidéo, est particulièrement approprié.
Il apporte en effet une grande lisibilité au programme, facilitant son écriture ainsi que sa maintenance. Très polyvalent, ce type de donnée permet aussi de réaliser des tableaux de structure, et les champs d'une structure peuvent être de n'importe quel type (chaîne, nombre, tableau cellulaire...) voire même être constitués d'une arborescence de sous-champs, sous-sous-champs, etc...
Bien entendu des méthodes vectorisées peuvent aussi être appliquées aux structures, par exemple l'indexation logique.

4.9.1 Généralités

Une "structure" (ou enregistrement, record) est un type MATLAB/Octave permettant de définir des objets composés de différents "champs" nommés (fields) qui peuvent être de différents types (chaînes, matrices, tableaux cellulaires...). Ces champs peuvent eux-mêmes se composer de sous-champs, etc... Et finalement MATLAB/Octave permet de créer des "tableaux de structures" (structures array) multidimensionels.

On accède aux champs d'une structure avec la syntaxe structure.champ.sous_champ.... Notez donc l'usage du caractère . comme séparateur (typique des langages orientés objets).

Exemple Pour illustrer les concepts de base relatifs aux structures, prenons l'exemple d'une structure permettant de stocker des personnes avec leurs différents attributs (nom, prénom, age, adresse, etc...).

A) Création d'une structure personne par définition des attributs du 1er individu :

  • avec personne.nom='Dupond' la structure est mise en place et contient le nom de la 1ère personne ! (vérifiez avec whos personne)
  • avec personne.prenom='Jules' on ajoute un champ prenom à cette structure et l'on définit le prénom de la 1ère personne
  • et ainsi de suite : personne.age=25 ; personne.code_postal=1010 ; personne.localite='Lausanne'
  • on peut, à ce stade, vérifier le contenu de la structure en frappant personne
Tableau de structures personne
nom: Dupond       prenom: Jules
age: 25
code_postal: 1010     localite: Lausanne
enfants: -
tel.prive: 021 123 45 67   tel.prof: 021 987 65 43
nom: Durand       prenom: Albertine
age: 30
code_postal: 1205     localite: Geneve
enfants: Arnaud     Camille
tel.prive: -     tel.prof: -
nom: Muller       prenom: Robert
age: 28
code_postal: 2000     localite: Neuchatel
enfants: -
tel.prive: -     tel.prof: -

B) Définition d'autres individus => la structure devient un tableau de structures :

C) Ajout de nouveaux champs à un tableau de structures existant :

D) Accès aux structures et aux champs d'un tableau de structures :
    - la notation structure(i) retourne la i-ème structure du tableau de structures structure
    - par extension, structure([i j:k]) retournerait un tableau de structures contenant la i-ème structure et les structures j à k du tableau structure
    - avec structure(i).champ on accède au contenu du champ spécifié du i-ème individu du tableau structure

E) Suppression de structures ou de champs :
    - pour supprimer des structures, on utilise la notation habituelle structure(...)=[]
    - pour supprimer des champs, on utilise la fonction structure = rmfield(structure,'champ')

F) Champs de type matrices ou tableau cellulaire :
    - habituellement les champs sont de type scalaire on chaîne, mais ce peut aussi être des tableaux classiques ou des tableaux cellulaires !

G) Matrices de structures :
    - ci-dessus, personne est en quelque-sorte un vecteur-ligne de structures
    - on pourrait aussi définir (même si c'est un peu "tordu") un tableau bi-dimensionnel (matrice) de structures
      en utilisant 2 indices (numéro de ligne et de colonne) lorsque l'on définit/accède à la structure,
      par exemple personne(2,1) ...


Il est finalement utile de savoir, en matière d'échanges, qu'Octave permet de sauvegarder des structures sous forme texte (utiliser save -text ...), ce que ne sait pas faire MATLAB.

4.9.2 Fonctions spécifiques relatives aux structures

Fonction Description
struct
setfield
rmfield

Ces fonctions ont été illustrées dans l'exemple ci-dessus...
numfields(struct) Retourne le nombre de champs de la structure struct
fieldnames(struct)

struct_elements(struct)

Retourne la liste des champs de la structure (ou du tableau de structures) struct. Cette liste est de type "tableau cellulaire" (à 1 colonne) sous MATLAB, et de type "liste" dans Octave.
La fonction struct_elements fait de même, mais retourne cette liste sous forme d'une matrice de chaînes.
getfield(struct,'champ') Est identique à struct.champ, donc retourne le contenu du champ champ de la structure struct
isstruct(var)

isfield(struct,'champ')

Test si var est un objet de type structure (ou tableau de structures) : retourne 1 si c'est le cas, 0 sinon.

Test si champ est un champ de la structure (ou du tableau de structures) struct : retourne 1 si c'est le cas, 0 sinon.

[n m]=size(tab_struct)

length(tab_struct)

Retourne le nombre n de lignes et m de colonnes du tableau de structures tab_struct,

respectivement le nombre total de structures

   for k=1:length(tab_struct)
     % on peut accéder à tab_struct(k).champ
   end
On boucle ainsi sur tous les éléments du tableau de structures tab_struct pour accéder aux valeurs correspondant au champ spécifié.
Ex: for k=1:length(personne), tab_cel_noms{k}=personne(k).nom ; end (voir plus haut)
 for [ valeur , champ ] = tab_struct
     % on peut utiliser champ
     %               et valeur
   end
Propre à Octave, cette forme particulière de la structure de contrôle for ... end permet de boucler sur tous les éléments d'un tableau de structures tab_struct et accéder aux noms de champ et aux valeurs respectives

4.10 Tableaux cellulaires (cells arrays)

Tableaux cellulaires


09:17 min
Cette vidéo présente le type de données le plus polyvalent sous MATLAB/Octave, c'est-à-dire le tableau cellulaire (cells array).
Tout comme les tableaux de nombres, les tableaux cellulaires peuvent avoir n'importe quelle dimension (c-à-d. vecteur, tableau à 2, 3 ou N dimension), mais leur originalité réside dans le fait que les cellules de ceux-ci peuvent contenir des données de n'importe quel type, voire même des tableaux imbriqués.
Plusieurs fonctions MATLAB/Octave retournent automatiquement des tableaux cellulaires, notamment certaines fonctions de manipulation de texte, et c'est donc important de maîtriser ce type.
Nous voyons ici comment utiliser ce type de données, c'est-à-dire créer et manipuler des tableaux cellulaires.

4.10.1 Généralités

Le "tableau cellulaire" ("cells array") est le type de donnée MATLAB/Octave le plus polyvalent. Il se distingue du tableau standard en ce sens qu'il peut se composer d'objets de types différents (scalaire, vecteur, chaîne, matrice, structure... et même tableau cellulaire, permettant ainsi même de faire des tableaux cellulaires imbriqués dans des tableaux cellulaires !).

Pour définir un tableau cellulaire et accéder à ses éléments, on recourt aux accolades { } (notation qui ne désigne ici pas, contrairement au reste de ce support de cours, des éléments optionnels). Ces accolades seront utilisées soit au niveau des indices des éléments du tableau, soit dans la définition de la valeur qui est introduite dans une cellule. Illustrons ces différentes syntaxes par un exemple.

Exemple:

A) Nous allons construire le tableau cellulaire 2D de 2x2 cellules T ci-contre par étapes successives. Il contiendra donc les cellules suivantes :
  - une chaîne 'hello'
  - une matrice 2x2 [22 23 ; 24 25]
  - un tableau contenant 2 structures (nom et age de 2 personnes)
  - et un tableau cellulaire 1x2 imbriqué { 'quatre'     44 }
Tableau cellulaire T

'hello'
2223
2425
personne
  nom: 'Dupond' age: 25
  nom: 'Durand' age: 30

{ 'quatre'     44 }

B) Pour accéder aux éléments d'un tableau cellulaire, il faut bien comprendre la différence de syntaxe suivante :
    - la notation tableau (i,j) (usage de parenthèses) retourne le "container" de la cellule d'indice i,j du tableau (tableau cellulaire à 1 élément)
    - par extension, tableau (i,:) retournerait par exemple un nouveau tableau cellulaire contenant la i-ème ligne de tableau
    - tandis que tableau {i,j} (usage d'accolades) retourne le contenu (c-à-d. la valeur) de la cellule d'indice i,j

C) Pour supprimer une ligne ou une colonne d'un tableau cellulaire, on utilise la syntaxe habituelle :

D) Pour récupérer sur un vecteur numérique tous les nombres d'une colonne ou d'une ligne d'un tableau cellulaire :
    - soit le tableau cellulaire suivant: TC={'aa' 'bb' 123 ; 'cc' 'dd' 120 ; 'ee' 'ff' 130}

E) Et l'on peut même utiliser l'indexation logique pour extraire des parties de tableau cellulaire !

Voici un exemple parlant :
- soit le tableau cellulaire de personnes et âges : personnes={'Dupond' 25; 'Durand' 30; 'Muller' 60}
- l'instruction personnes( ([ personnes{:,2} ] > 27)' ,1) retourne alors, sous forme de tableau cellulaire,
  les noms des personnes âgées de plus de 27 ans (Durand et Muller) ;
- pour ce faire, on a ici "indexé logiquement" la première colonne de personnes (contenant les noms)
  par le vecteur logique [ personnes{:,2} ] > 27 (que l'on transpose pour qu'il soit en colonne),
  et on n'extrait de ce tableau personnes que la 1ère colonne (les noms)


Il est intéressant de noter que les tableaux cellulaires peuvent être utilisés comme paramètres d'entrée et de sortie à toutes les fonctions MATLAB/Octave (un tableau cellulaire pouvant, par exemple, remplacer une liste de paramètres d'entrée).

Il est finalement utile de savoir, en matière d'échanges, qu'Octave permet de sauvegarder des tableaux cellulaires sous forme texte (avec save -text ...), ce que ne sait pas faire MATLAB.

4.10.2 Fonctions spécifiques relatives aux tableaux cellulaires

Nous présentons dans le tableau ci-dessous les fonctions les plus importantes spécifiques aux tableaux cellulaires.

On utilisera en outre avec profit, dans des tableaux cellulaires contenant des chaînes de caractères, les fonctions de tri et de recherche sort/sortrows, unique, intersect/setdiff/union et ismember présentées plus haut.

Fonction Description
cell(n)
cell(n,m)
cell(n,m,o,p...)
Crée un objet de type tableau cellulaire carré de dimension n x n,
respectivement de n lignes x m colonnes, dont tous les éléments sont vides.
Avec plus que 2 paramètres, crée un tableau cellulaire multidomensionnel.

Mais, comme l'a démontré l'exemple ci-dessus, un tableau cellulaire peut être créé, sans cette fonction, par une simple affectation de type tableau={ valeur } ou tableau{1,1}=valeur, puis sa dimension peut être étendue dynamiquement

iscell(var)

iscellstr(var)

Test si var est un objet de type tableau cellulaire : retourne 1 si c'est le cas, 0 sinon.

Test si var est un tableau cellulaire de chaînes.

[n m]=size(tab_cel) Retourne la taille (nombre n de lignes et m de colonnes) du tableau cellulaire tab_cel
mat = cell2mat(tab_cel) Convertit le tableau cellulaire tab_cel en une matrice mat en concaténant ses éléments
Ex: cell2mat( { 11 22 ; 33 44 } ) retourne [11 22 ; 33 44]
tab_cel_string = cellstr(mat_string) Conversion de la "matrice de chaînes" mat_string en un tableau cellulaire de chaînes tab_cel_string. Chaque ligne de mat_string est automatiquement "nettoyée" des caractères espace de remplissage (trailing blanks) avant d'être placée dans une cellule. Le tableau cellulaire résultant aura 1 colonne et autant de lignes que mat_string.
mat_string = char(tab_cel_string) Conversion du tableau cellulaire de chaînes tab_cel_string en une matrice de chaînes mat_string. Chaque chaîne de tab_cel_string est automatiquement complétée par des caractères espace de remplissage (trailing blanks) de façon que toutes les lignes de mat_string aient le même nombre de caractères.
celldisp(tab_cel) Affiche récursivement le contenu du tableau cellulaire tab_cel. Utile sous MATLAB où, contrairement à Octave, le fait de frapper simplement tab_cel n'affiche pas le contenu de tab_cel mais le type des objets qu'il contient.
cellplot(tab_cel) Affiche une figure représentant graphiquement le contenu du tableau cellulaire tab_cel
num2cell Conversion d'un tableau numérique en tableau cellulaire
struct2cell, cell2struct Conversion d'un tableau de structures en tableau cellulaire, et vice-versa
namedargs2cell(struct) Conversion d'une structure en un tableau cellulaire
Ex: si pers.nom='Martin'; pers.prenom='Jules'; pers.age=25; alors namedargs2cell(pers) retourne {'nom','Martin', 'prenom','Jules', 'age',25}
cellfun(function,tab_cel {,dim}) Applique la fonction function (qui peut être: 'isreal', 'isempty', 'islogical', 'length', 'ndims' ou 'prodofsize') à tous les éléments du tableau cellulaire tab_cell, et retourne un tableau numérique

4.10.3 Listes Octave

Le type d'objet "liste" était propre à Octave. Conceptuellement proches des "tableaux cellulaires", les listes n'ont plus vraiment de sens aujourd'hui et disparaissent de Octave depuis la version 3.4. On trouve sous ce lien des explications relatives à cet ancien type d'objet.

4.11 Maps

Maps


08:18 min
Cette vidéo termine le passage en revue des principaux types de données offerts par MATLAB/Octave, avec la présentation du type "maps". On retrouve ce type assez classique sous d'autres dénominations dans différents langages :
• les dictionnaires sous Python
• les tableaux associatifs sous PHP
• les hash (tables de hachage) sous Perl
Il permet de créer des tableaux qui sont indexés non pas par des indices de type nombres entiers (comme les tableaux de nombre ou les tableaux cellulaires vus jusqu'ici), mais par des "clés" qui peuvent être textuelles ou numériques.

4.11.1 Création et manipulation de maps

Un objet de type "map" est un tableau orienté clé/valeur. Les valeurs sont référencées par des clés plutôt que, comme c'est le cas dans les tableaux classiques, par leur position (indice entier). L'ordre des éléments clé/valeur dans un map n'est donc pas significatif. Notez que les clés elles-mêmes sont stockées dans le tableau, et que chacune des clés doit être unique. Par ailleurs, dans un tableau donné, toutes les clés doivent être de type identique (à choix 'char' (défaut), 'double', 'single', 'int32', 'uint32', 'int64' ou 'uint64'). Par contre les valeurs peuvent être de n'importe quel type.

Le type Map existe sous MATLAB depuis la version R2008 et apparaît sous Octave avec la version 4.4. Il correspond, dans d'autres langages, aux dictionnaires sous Python, aux tableaux associatifs (hash's) sous Perl...

Illustrons l'usage des maps par 2 exemples :

Ex 1

A) Nous allons construire un map population illustré ci-contre stockant le nombre d'habitants des différents cantons suisses. Il contiendra donc :
  - les clés seront les noms des cantons (chaînes de caractère)
  - les valeurs seront le nombre d'habitants de ceux-ci (p.ex. réels double précision)
Map population
'Vaud' 784000
'Valais' 339000
'Geneve' 495000
'Jura' 73000

B) Pour examiner les propriétés du map :

C) Pour récupérer les éléments (clés ou valeurs) d'un map :

D) Pour détruire des éléments d'un map :

Ex 2
L'exemple ci-dessous illustre ici l'usage de clés numériques et de valeurs non uniformes (i.e. de différents types et dimensions pour chaque élément)





Documentation © CC BY-SA 4.0 / / EPFL / Rév. 16-09-2021       ↵ Table des matières