Archives du mot-clé tableau

Quand MATLAB et fprintf ne regardent pas dans la même direction…

La fonction fprintf de MATLAB est très utile pour contrôler l’écriture de données dans un fichier texte. Sa syntaxe est la suivante :

fprintf(fileid, format, A)

Le premier argument fileid est l’identifiant du fichier renvoyé par la fonction fopen. Le deuxième argument format gère le formatage de l’écriture. C’est l’argument le plus compliqué à maitriser et il faudra souvent se référer à la documentation pour savoir quel formatage utiliser. Le dernier argument A est le tableau de données à écrire dans le fichier.

Il y a une subtilité à connaitre, même pour des cas d’utilisation de fprintf relativement simple. C’est ce que je vais vous présenter maintenant.

Le problème

Ecrire dans un fichier texte le tableau suivant :

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

Soit :

M =

     1     2
     3     4
     5     6

Le contenu du fichier doit donc être le suivant :

1 2
3 4
5 6

Comme un fichier texte s’écrit ligne après ligne (en séparant chaque ligne avec un retour à la ligne), on serait tenté d’écrire le code suivant :

fid = fopen('test.txt', 'wt');
fprintf(fid, '%d %d\n', M);
fclose(fid);

concise-writer-calvin

%d signifie que la valeur à écrire sera un entier. On met deux fois ce format car le tableau a deux colonnes. Puis on demande à fprintf de passer à la ligne avec \n. fprintf répète ensuite ce motif tant qu’il y a des valeurs à écrire. En faisant cela, on ne tient pas compte du nombre de lignes du tableau. Ce qui est très pratique si ce nombre n’est pas constant entre deux appels à fprintf.

En exécutant le code ci-dessus, le fichier texte contient :

1 3
5 2
4 6

Aïe ! Cela ne correspond pas du tout au tableau initial. Les valeurs semblent mélangées.

Les raisons

Le code précédent est faux car il y a une différence fondamentale entre MATLAB et la fonction fprintf.

Le stockage en mémoire des tableaux par MATLAB est particulier. Les valeurs sont stockées dans un vecteur où elles sont toutes contiguës (il n’y a pas d’élément vide entre elles). MATLAB les stocke colonne par colonne (1ère colonne, 2ème colonne, 3ème colonne…). Lire à ce sujet : Stockage des matrices en mémoire.

Le tableau suivant :

M =

     1     2
     3     4
     5     6

est donc stocké comme ceci en mémoire :

     1 3 5 2 4 6

Pourquoi ce choix me direz-vous ? Eh bien parce que MATLAB était initialement écrit en Fortran. Et que les tableaux sont définis colonne par colonne dans ce langage. Donc fprintf prend ces valeurs dans cet ordre et il est alors normal de trouver le 1 et le 3 sur la première ligne du fichier, suivi du 5 et du 2 sur la deuxième ligne et pour finir, du 4 et du 6 sur la dernière.

D’accord, mais les concepteurs de MATLAB auraient facilement pu prendre ceci en compte et, sans tenir compte de l’ordre de stockage par MATLAB, créer une fonction fprintf respectant un passage du tableau sous sa forme naturelle.

Oui mais voila, en 1984, MATLAB a été réécris en langage C. La fonction fprintf de MATLAB repose donc directement sur la fonction homonyme en C (voir les références en bas de la documentation).

Et alors, pourquoi vous parler de Fortran et de C ? Eh bien parce que, en langage C, les tableaux sont définis ligne par ligne.

Si MATLAB utilisait la convention de stockage du C, le code suivant fonctionnerait donc :

fprintf(fid, '%d %d\n', M);

Or ce n’est pas le cas. La fonction fprintf n’a donc pas un comportement naturel pour l’écriture des tableaux de MATLAB.

Les solutions

La première solution consiste à prendre en compte ce problème dès la conception du code et à créer le tableau suivant :

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

Soit :

M =

     1     3     5
     2     4     6

Il n’est malheureusement pas toujours envisageable de créer le tableau de cette manière.

La deuxième solution consiste alors à transposer le tableau passé à fprintf. C’est à dire à permuter les lignes et les colonnes du tableau :

M = [1 2 ; 3 4 ; 5 6];
M = M.';

Le tableau devient donc :

M =

     1     3     5
     2     4     6

On peut ensuite faire :

fprintf(fid, '%d %d\n', M);

Ou directement avec le tableau d’origine :

fprintf(fid, '%d %d\n', M.');

La fonction fprintf écrira donc d’abord les valeurs 1 et 2 sur une ligne du fichier, puis 3 et 4 sur une autre, pour finir avec 5 et 6 sur la dernière.

Conclusion

Vous savez maintenant comment écrire correctement un tableau dans un fichier texte avec un seul appel à fprintf depuis MATLAB.

fprintf reste une fonction difficile à manipuler. N’hésitez pas à me poser des questions ou à me soumettre des suggestions à propos de cette fonction en commentaire. Je pourrai toujours faire d’autres billets au sujet de cette fonction.

Matrice ou tableau dans MATLAB ?

Les termes « matrice » et « tableau » sont souvent employés pour désigner des variables MATLAB, malheureusement avec une certaine confusion.

Je vais donc tenter de convaincre les utilisateurs qui ne sont comme moi, ni mathématicien ni informaticien de formation, d’utiliser à l’avenir le terme adéquat.

Ce billet est inspiré par les remarques faites par Jean-Marc Blanc sur les forums MATLAB depuis plusieurs années. ;)

Tableau

Qu’est-ce qu’un tableau ? Un outil d’informaticien !

En informatique, un tableau est une structure qui permet de stocker des données. On peut se la représenter comme une grille régulière de dimension quelconque. Les dimensions les plus courantes sont 1D, 2D, 3D voire 4D.

Prenons par exemple un tableau 2D contenant des valeurs numériques entières :

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

M =

     1     2     3
     4     5     6
     7     8     9

>> whos M
  Name      Size            Bytes  Class     Attributes

  M         3x3                72  double

Un tableau peut avoir plus de deux dimensions dans MATLAB. Par exemple, voici un tableau à six dimensions :

>> M = rand(5,2,7,4,5,8);
>> whos M
  Name      Size            Bytes  Class     Attributes

  M         6-D             89600  double

Avec MATLAB, on se sert des tableaux pour stocker par exemple les valeurs des pixels d’une image. Un tableau 2D sera utilisé pour les images en couleurs indexées alors qu’un tableau 3D sera utilisé pour les images en couleurs vraies (RGB). Plus d’informations à ce sujet dans le tutoriel Gestion des couleurs.

Par exemple :

>> I = imread('lena.jpg');
>> whos I
  Name        Size                Bytes  Class    Attributes

  I         512x512x3            786432  uint8

Matrice

Qu’est-ce qu’une matrice ? Un outil de mathématicien !

En mathématiques (calcul numérique), une matrice peut être considérée comme un tableau à deux dimensions (2D) et… rien d’autre. Une matrice possède des propriétés particulières et doit respecter les règles du calcul matriciel.

Le tableau suivant peut donc être considéré comme une matrice :

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

M =

     1     2     3
     4     5     6
     7     8     9

>> whos M
  Name      Size            Bytes  Class     Attributes

  M         3x3                72  double

Avec MATLAB, on se sert des matrices pour, par exemple, résoudre des systèmes d’équations linéaires. Lire à ce sujet le tutoriel Résolution des systèmes linéaires de Jean-Marc Blanc.

Par exemple, on peut utiliser des matrices pour résoudre le système d’équations suivant :

4x + 2y = 5
x – 5y = 4

Dans MATLAB :

>> A = [4 2 ; 1 -5];
>> B = [5 ; 4];
>> A\B

ans =

    1.5000
   -0.5000

A et B sont donc des matrices dans ce cas.

Conclusion

Tout est tableau dans MATLAB, vous pouvez donc toujours employer ce terme.

Les matrices sont des tableaux 2D, que l’on utilise uniquement dans le cadre des mathématiques (algèbre linéaire).

Voila, j’espère vous avoir éclairé.

Ma première résolution pour l’année 2014 consistera à prêter un maximum d’attention à l’emploi de ces deux termes. :)

Pour résumer

Avec MATLAB :

  • Tableau : tableau de dimension quelconque ;
  • Matrice : tableau à deux dimensions (2D) utilisé pour en mathématiques (calculs numériques).

Note : en anglais, « tableau » se dit « array », et « matrice » se dit « matrix ».