Matrices et vecteurs

Informatique — MATLAB, chapitre 2

Voici le cœur du logiciel. Pour MATLAB, un nombre isolé n’est pas un objet particulier : c’est une matrice de taille 1×1. Toutes les opérations du chapitre précédent étaient donc déjà des opérations matricielles, sans que cela se voie.

À partir d’ici, cela se voit.

2.1 Créer une matrice

2.1.1 Les crochets, l’espace et le point-virgule

A = [1 2 3; 4 5 6]
A =

   1   2   3
   4   5   6

Trois symboles suffisent : les crochets délimitent, l’espace (ou la virgule) sépare les colonnes, le point-virgule change de ligne.

AvertissementLe point-virgule a deux rôles

À l’intérieur des crochets, il sépare les lignes d’une matrice.

À la fin d’une instruction, il empêche l’affichage — c’est l’usage du chapitre 1.

A = [1 2; 3 4]; combine les deux : une matrice de deux lignes, créée sans rien afficher.

2.1.2 Les vecteurs

Un vecteur n’est qu’une matrice à une seule ligne ou une seule colonne.

ligne = [1 2 3 4]
colonne = [1; 2; 3; 4]
ligne =

   1   2   3   4

colonne =

   1
   2
   3
   4

La distinction n’est pas décorative : elle détermine si un produit matriciel est possible. Le chapitre 4 y reviendra longuement.

2.1.3 Les suites régulières

a = 1:5
b = 0:0.25:1
c = 10:-2:0
d = linspace(0, 1, 5)
a =

   1   2   3   4   5

b =

        0   0.2500   0.5000   0.7500   1.0000

c =

   10    8    6    4    2    0

d =

        0   0.2500   0.5000   0.7500   1.0000

Le deux-points construit une suite : debut:pas:fin. Sans pas indiqué, il vaut 1.

Écriture Signification
1:5 de 1 à 5, par pas de 1
0:0.25:1 de 0 à 1, par pas de 0,25
10:-2:0 à rebours
linspace(0, 1, 5) cinq valeurs régulières entre 0 et 1
Astucelinspace sur des nombres à virgule

0:0.1:1 devrait donner onze valeurs. Les arrondis binaires en donnent parfois dix, sans prévenir.

linspace(0, 1, 11) garantit le nombre de points et les deux bornes exactes. Dès qu’un pas n’est pas entier, préférez-la.

2.2 Mesurer une matrice

A = [1 2 3; 4 5 6];

size(A)
[nl, nc] = size(A)
numel(A)
length(A)
ans =

   2   3

nl = 2
nc = 3
ans = 6
ans = 3
Fonction Renvoie
size(A) le couple (lignes, colonnes)
size(A, 1) / size(A, 2) le nombre de lignes / de colonnes
numel(A) le nombre total d’éléments
length(A) la plus grande des deux dimensions
Avertissementlength n’est pas le nombre d’éléments

Sur une matrice 2×3, length renvoie 3 — la plus grande dimension —, pas 6.

length n’est sans ambiguïté que sur un vecteur. Sur une matrice, employez size ou numel. Beaucoup de programmes contiennent un bug latent qui n’apparaît que le jour où la matrice cesse d’être un vecteur.

Notez aussi [nl, nc] = size(A) : une fonction MATLAB peut renvoyer plusieurs sorties, récupérées entre crochets. Le chapitre 11 y reviendra.

2.3 Extraire

2.3.1 Un élément

A = [1 2 3; 4 5 6];

A(2, 3)
A(1, 1)
ans = 6
ans = 1

A(ligne, colonne), dans cet ordre, et on compte à partir de 1.

ImportantParenthèses, pas crochets

L’extraction s’écrit avec des parenthèses : A(2, 3). Les crochets ne servent qu’à la construction.

Et la numérotation commence à 1, comme en R, à l’inverse de Python. A(0, 1) déclenche une erreur d’indice, ce qui vaut mieux qu’un silence.

2.3.2 Une ligne, une colonne, un bloc

Le deux-points employé seul signifie « tout ».

A = [1 2 3; 4 5 6; 7 8 9];

A(2, :)
A(:, 3)
A(1:2, 2:3)
A(end, :)
ans =

   4   5   6

ans =

   3
   6
   9

ans =

   2   3
   5   6

ans =

   7   8   9

Le mot-clé end désigne le dernier indice. A(end, end) est l’élément du coin inférieur droit, quelle que soit la taille — bien plus robuste que d’écrire les nombres à la main.

2.3.3 L’indexation linéaire

A = [1 2 3; 4 5 6];

A(4)
A(:)'
ans = 5
ans =

   1   4   2   5   3   6
ImportantMATLAB parcourt les colonnes, pas les lignes

Un seul indice parcourt la matrice colonne par colonne : A(4) est le quatrième élément dans cet ordre, soit 5 — et non 3, comme un parcours par lignes le donnerait.

A(:) empile toute la matrice en une colonne, dans le même ordre.

Cette convention, dite column-major, est celle de MATLAB, de R et de Fortran. NumPy fait l’inverse. Elle compte dès qu’on redimensionne une matrice ou qu’on la relit depuis un fichier.

2.4 Modifier

A = [1 2 3; 4 5 6];

A(1, 1) = 100
A(2, :) = [7 8 9]
A(:, 2) = 0
A =

   100     2     3
     4     5     6

A =

   100     2     3
     7     8     9

A =

   100     0     3
     7     0     9

A(:, 2) = 0 remplit toute la deuxième colonne d’un seul zéro : MATLAB l’étend automatiquement à la bonne taille.

2.4.1 Supprimer

A = [1 2 3; 4 5 6; 7 8 9];

A(2, :) = []
A(:, 1) = []
A =

   1   2   3
   7   8   9

A =

   2   3
   8   9

Affecter la matrice vide [] à une ligne ou une colonne la supprime. On ne peut pas supprimer un élément isolé d’une matrice : cela laisserait un trou incompatible avec la forme rectangulaire.

2.4.2 La croissance automatique

v = [1 2 3];
v(6) = 99
v =

    1    2    3    0    0   99
AvertissementCommode, mais lent — et parfois révélateur d’un bug

Écrire au-delà de la taille actuelle agrandit la matrice et comble de zéros. Aucune erreur n’est signalée.

C’est commode, mais coûteux : MATLAB réalloue toute la mémoire à chaque agrandissement. Dans une boucle, cela peut multiplier le temps de calcul par cent — le chapitre 10 montrera comment préallouer.

Et surtout, ces zéros silencieux masquent souvent une erreur d’indice.

2.5 Assembler

A = [1 2; 3 4];
B = [5 6; 7 8];

C = [A B]
D = [A; B]
C =

   1   2   5   6
   3   4   7   8

D =

   1   2
   3   4
   5   6
   7   8

Les mêmes symboles qu’à la création : l’espace juxtapose horizontalement, le point-virgule empile verticalement. Les fonctions horzcat et vertcat font la même chose sous forme nommée.

Les dimensions doivent concorder : même nombre de lignes pour juxtaposer, même nombre de colonnes pour empiler. Sinon, horizontal dimensions mismatch.

2.6 Réorganiser

v = 1:6;

A = reshape(v, 2, 3)
B = reshape(v, 3, 2)
A'
A =

   1   3   5
   2   4   6

B =

   1   4
   2   5
   3   6

ans =

   1   2
   3   4
   5   6

reshape remplit colonne par colonne, conformément à la convention de 2.3.3. L’apostrophe ' transpose — l’opérateur le plus employé de tout MATLAB.

Astucereshape ne perd jamais d’élément

Le produit des nouvelles dimensions doit égaler le nombre d’éléments : reshape(v, 2, 3) sur six valeurs fonctionne, reshape(v, 2, 4) échoue.

Écrivez reshape(v, 2, []) pour laisser MATLAB calculer la seconde dimension. C’est plus sûr, et le code survit à un changement de taille des données.

À vous

Créez la matrice 3×4 contenant les nombres de 1 à 12 rangés par lignes. Extrayez sa deuxième ligne, sa dernière colonne, le bloc formé des deux premières lignes et deux dernières colonnes, puis supprimez la troisième ligne.

% a completer
A = reshape(1:12, 4, 3)'      % attention : on transpose

A(2, :)
A(:, end)
A(1:2, 3:4)

A(3, :) = []
A =

    1    2    3    4
    5    6    7    8
    9   10   11   12

ans =

   5   6   7   8

ans =

    4
    8
   12

ans =

   3   4
   7   8

A =

   1   2   3   4
   5   6   7   8

Le reshape(1:12, 4, 3)' mérite une explication : reshape remplissant par colonnes, on construit d’abord une matrice 4×3 puis on la transpose. Écrire directement reshape(1:12, 3, 4) donnerait les nombres rangés par colonnes, pas par lignes.

Ce qu’il faut retenir

Écriture Effet
[1 2; 3 4] créer — espace sépare, ; change de ligne
1:5, 0:0.25:1 suite régulière
linspace(a, b, n) n valeurs, bornes comprises
size, numel, length mesurer — length donne la plus grande dimension
A(2, 3) extraire — parenthèses, indices à partir de 1
A(2, :), A(:, 3) une ligne, une colonne
end le dernier indice
A(4) indexation linéaire — parcours par colonnes
A(1,1) = 100 modifier
A(2, :) = [] supprimer une ligne
[A B], [A; B] juxtaposer, empiler
reshape(v, m, n), A' réorganiser, transposer

Le chapitre suivant présente les matrices que MATLAB sait construire seul : nulle, identité, diagonale, triangulaire, aléatoire.