Archives pour la catégorie MATLAB

Peut-on utiliser « i » comme indice de boucle dans MATLAB ?

La question peut sembler bizarre pour la plupart des développeurs, surtout ceux qui ne codent pas avec MATLAB.

« i » comme indice de boucle

La variable « i » est couramment utilisée pour désigner l’indice des boucles en programmation informatique.

En C :

for(i=0;i<10;i++)
   printf("%d\n", i);

En Fortran :

do i=0,9
   print*,i
end do

Avec MATLAB :

for i = 0:9
   fprintf("%d\n", i);

Mais pourquoi utilise-t-on « i » au fait ? Certains y voient un héritage des notations mathématiques, d'autres du Fortran, ou alors un peu des deux, ou encore que « indice » et « index » commencent par i. Il n'y a, semble-t-il, pas de réponse absolue. Lire à ce sujet : Why are variables “i” and “j” used for counters?

« i » pour désigner les nombres complexes avec MATLAB

MATLAB est un outil initialement conçu pour le calcul numérique. A ce titre, il prend en compte les nombres complexes (et les calculs associés) depuis sa première version.

Hobbes explique les nombres imaginaires à Calvin

Pour définir une valeur complexe, on utilise la syntaxe suivante :

>> cmplx = 1 + 3i

cmplx =

   1.0000 + 3.0000i

Le caractère « i » est obligatoirement placé après la valeur numérique de la partie imaginaire, sans aucun espace.

Sinon :

>> cmplx = 1+i3
Undefined function or variable 'i3'.

>> cmplx = 1 + 3 i
 cmplx = 1 + 3 i
              |
Error: Unexpected MATLAB expression.

Nombres complexes et boucle avec MATLAB

Pour mettre en évidence l’ambiguïté entre ces deux utilisations de « i », prenons un exemple simple :

for i = 1:4
    X(1,i) = 1+3*i;      
    Y(1,i) = 1+3i;    
end

Les variables X et Y contiennent-elles toutes les deux des valeurs complexes ?

Affichons leur contenu :

X =

     4     7    10    13


Y =

   1.0000 + 3.0000i   1.0000 + 3.0000i   1.0000 + 3.0000i   1.0000 + 3.0000i

Dans ce cas, X contient donc uniquement des valeurs réelles.

Que ce passe-t-il si on supprime la variable i et que l’on renomme la variable qui incrémente la boucle ?

clear i

for n = 1:4
    X(1,n) = 1+3*i;      
    Y(1,n) = 1+3i;    
end

Voici le contenu de X et Y :

X =

   1.0000 + 3.0000i   1.0000 + 3.0000i   1.0000 + 3.0000i   1.0000 + 3.0000i


Y =

   1.0000 + 3.0000i   1.0000 + 3.0000i   1.0000 + 3.0000i   1.0000 + 3.0000i

Aïe… les deux codes ont quasiment la même syntaxe, mais ne donnent pas du tout le même résultat !

Solution

Certains préconisent de ne jamais employer « i » comme indice de boucle. Oui pourquoi pas. Pour ma part, je ne suis convaincu par aucun dogme (MATLAB c’est mal…)

Pourquoi devrais-je donc impérativement ne pas utiliser « i » comme variable d’incrément dans mes codes ?

Il est vrai que j’utilise souvent « n », mais je ne saurais réellement dire pourquoi, si ce n’est par habitude. En traitement d’images, j’utilise parfois « r » et « c » pour désigner respectivement les lignes (rows) et les colonnes (columns) pour parcourir les pixels d’une image.

Solution robuste

Il y a en fait deux façons de créer un nombre complexe avec MATLAB, celle que l’on a vue précédemment et celle qui consiste à utiliser la fonction complex :

>> cmplx = complex(1,3)

cmplx =

   1.0000 + 3.0000i

Dans ce cas, aucune ambiguïté, ni aucune chance pour que la définition du nombre complexe n’entre en conflit avec une variable i définie préalablement dans le code.

La fonction complex est également utile quand la partie imaginaire du nombre complexe est nulle.

En effet :

>> cmplx = 1+0i

cmplx =

     1

>> isreal(cmplx)

ans =

     1

Alors que :

>> cmplx = complex(1,0)

cmplx =

     1

>> isreal(cmplx)

ans =

     0

La première syntaxe renvoie une variable contenant une valeur réelle alors que la deuxième syntaxe renvoie une valeur complexe.

Conclusion

L’emploi du caractère « i » peut être source de confusion et d’erreur dans la syntaxe et l’exécution de code MATLAB.

Il n’y a pas de solution parfaite, mis à part l’utilisation de la fonction complex.

Dans tous les cas, c’est à vous, développeurs, de déterminer si l’ambiguïté peut apparaitre dans votre code et de la prendre en compte si besoin.

PS : ce billet fait suite à une remarque de tachmou dans la discussion Probleme incrementation boucle for du forum MATLAB.

Ordre des appels à ispc, isunix et ismac avec MATLAB

J’ai récemment déployé une application sur Mac OS X avec le MATLAB Compiler. Elle n’était utilisée jusqu’à présent que sur Windows et Linux.

Cette application contient un outil qui me permet de récupérer certaines caractéristiques de la machine. Je récupère, entres autres, le nom de l’architecture où s’exécute le code, à savoir Windows, Linux ou Mac.

Code initial de récupération de l’architecture

Voici approximativement comment est codé le log :

fid = fopen('bug.log', 'wt');
if ispc
   fprintf(fid, 'OS: Windows\n');
elseif isunix
   fprintf(fid, 'OS: Linux\n');
else
   fprintf(fid, 'OS: Mac\n');
end
fclose(fid);

Or cette façon de procéder est fausse car, avec Mac OS X, le fichier bug.log contient la ligne suivante :

OS: Linux

Bizarre, non ?

D’où vient l’erreur ?

Les fonctions ispc, isunix et ismac utilisent en fait la fonction computer qui renvoi l’architecture de la machine sous forme d’une chaine de caractères qui peut être :

  • ‘PCWIN’ ou ‘PCWIN64′ pour Windows
  • ‘GLNX86′ ou ‘GLNXA64′ pour Linux
  • ‘MACI64′ pour Mac

Les trois architectures devraient donc être bien différenciées.

Pourquoi mon implémentation du log ne fonctionne-t-elle pas correctement ?

Étudions les fonctions ispc, isunix et ismac. Vous pouvez visualiser leur code en ouvrant les fichiers ispc.m, ismac.m et isunix.m dans le MATLAB Editor ou dans n’importe quel éditeur de texte.

ispc

Le fonction ispc compare simplement les deux premiers caractères de la chaine renvoyée par la fonction computer. Si ces deux caractères sont ‘PC’ alors la machine tourne sur Windows.

ismac

Sur le même principe, la fonction ismac teste si les trois premiers caractères de la chaine renvoyée par computer sont ‘MAC’. Tout est normal.

isunix

Surprise, la fonction isunix fait simplement l’inverse de la fonction ispc.

Le code de isunix est équivalent à :

isunix = ~ispc;

Donc pour MATLAB, tout ce qui n’est pas Windows est forcément Linux !

C’est utile à savoir, je corrige donc mon code.

Code corrigé de récupération de l’architecture

La condition ismac doit donc obligatoirement apparaître avant isunix :

fid = fopen('bug.log', 'wt');
if ispc
   fprintf(fid, 'OS: Windows\n');
elseif ismac
   fprintf(fid, 'OS: Mac\n');
else
   fprintf(fid, 'OS: Linux\n');
end
fclose(fid);

Me voila prévenu, et vous aussi !

:)

Dans un prochain billet, je vous expliquerai l’intérêt pour MATLAB d’assimiler Mac à Linux avec isunix (les utilisateurs avertis connaissent déjà sans aucun doute la réponse). ;)

Pour ouvrir « MATLAB », il vous faut un moteur d’exécution Java SE 6

Je ne me suis pas servi de MATLAB sur mon Mac depuis une (récente) mise à jour vers OS X 10.9 (Mavericks).

Et ce matin, surprise : impossible d’ouvrir MATLAB. :sad:

Erreur relative à Java SE 6

Voici le message d’erreur qui apparait :

Pour ouvrir MATLAB, il vous faut un moteur d'execution Java SE 6

Le problème vient semble-t-il du fait que Java n’est plus fournit avec les dernières versions de OS X.

C’est ce que j’ai constaté en ouvrant une console :

Mac-mini-de-Jerome:~ jerome$ java -version
No Java runtime present, requesting install.

J’ai tenté l’installation proposée en cliquant sur « Installer », mais sans succès.

La solution a donc consisté à télécharger Java SE 6 sur cette page : Java for OS X 2013-005

Après installation :

Mac-mini-de-Jerome:~ jerome$ java -version
java version "1.6.0_65"
Java(TM) SE Runtime Environment (build 1.6.0_65-b14-462-11M4609)
Java HotSpot(TM) 64-Bit Server VM (build 20.65-b04-462, mixed mode)

Erreur relative à X11

A la première exécution de MATLAB, j’ai eu droit à un nouveau message d’erreur, cette fois pour X11.

Pour ouvrir MATLAB_maci64, vous devez installer X11.

En cliquant sur « Continuer », on accède à cette page : About X11 and OS X

On peut y lire :

X11 is no longer included with OS X, but X11 server and client libraries for OS X are available from the XQuartz project

Je suis donc allé dans le Launchpad et j’ai ouvert XQuartz.
Ce dernier m’a proposé une mise à jour et j’ai enfin pu ouvrir MATLAB.

:mrgreen: