FAQ MATLABConsultez toutes les FAQ

Nombre d'auteurs : 10, nombre de questions : 166, dernière mise à jour : 30 mars 2017 

 
OuvrirSommaireProgrammation

Avec l'éditeur de MATLAB il est très simple et très rapide d'indenter proprement son code avec le raccourci : CTRL+A (sélection de tout le code) puis CTRL+I (indentation automatique). Il est évidemment aussi possible de le faire par les menus mais cette méthode est la plus rapide.

C'est quoi indenter son code ?

Indenter c'est mettre en forme le code selon certains critères pré-établis. Par exemple, entre un FOR et son END, le code sera décalé d'une tabulation.

A quoi cela peut-il bien me servir ?

Cela permet une meilleure lisibilité du code et par exemple de se rendre assez vite compte qu'il manque un end quelque part. C'est très pratique en particulier depuis l'arrivée des fonctions imbriquées (nested functions) qui nécessitent de bien fermer chaque fonction.

Par exemple, entre ce code (faux) non indenté :

 
Sélectionnez
for i = 1:n
for j = 2:m
a(i,j) = i*j;
end

Et le même avec indentation :

 
Sélectionnez
for i = 1:n
    for j = 2:m
        a(i,j) = i*j;
    end

L'erreur saute beaucoup plus aux yeux dans le 2ème code.

L'indentation est donc une aide précieuse surtout lorsque l'on arrive à des codes assez importants avec des boucles et des fonctions imbriquées.

De plus, une fois que vous avez pris l'habitude d'indenter proprement votre code (sachant que l'éditeur le fait quasiment seul) vous verrez que vous aurez beaucoup plus de mal à lire du code non indenté.

Créé le 6 février 2011  par Caro-Line

La plupart des algorithmes utilisés dans les fonctions sont décrits ou référencés dans la documentation MATLAB (voir le paragraphe Algorithm sur la page de la fonction étudiée).

Cette documentation est disponible sous MATLAB :

  • soit en tapant doc dans le Command Window ;
  • soit à partir du menu Help > Product Help.

La totalité de la documentation (MATLAB/Simulink + toutes les Toolbox) est également disponible en ligne (voir Où trouver la documentation des différentes version de MATLAB en ligne ?).

Mis à jour le 28 octobre 2012  par Jérôme Briot

Les messages d'erreurs de MATLAB se lisent toujours du bas vers le haut (de la dernière ligne vers la première).

Trois cas de figure sont possibles :

1) L'erreur s'est produite en tapant une commande dans le Command Window.

 
Sélectionnez
>> a = sprintf('%f',rand(1,2)
??? a = sprintf('%f',rand(1,2)
                              |
Error: Expression or statement is incorrect--possibly unbalanced (, {, or [.

MATLAB écrit la ligne où l'erreur s'est produite et ajoute un curseur donnant graphiquement la position de l'erreur dans la ligne (ici la place de la parenthèse manquante).

2) L'erreur se produit dans une fonction

Exemple : soit func_A.m

 
Sélectionnez
function func_A

a = sprintf('%f',rand(1,2)

Dans le Command Window :

 
Sélectionnez
>> func_A
??? Error: File: func_A.m Line: 3 Column: 27
This statement is incomplete.

MATLAB renvoie le nom du fichier où l'erreur s'est produite, le numéro de la ligne dans le fichier et la colonne (approximative) sur cette ligne (équivalent du curseur dans le cas précédent).

3) L'erreur se produit dans des fonctions différentes (plusieurs fichiers m) appelées par la fonction principale.

Exemple : soient trois fonctions func_A.m,func_B.m et func_C.m

 
Sélectionnez
function func_A

func_B
 
Sélectionnez
function func_B

func_C
 
Sélectionnez
function func_C

a = sprintf('%f',rand(1,2)

Dans le Command Window :

 
Sélectionnez
>> func_A
??? Error: File: func_C.m Line: 3 Column: 27
Expression or statement is incorrect--possibly unbalanced (, {, or [.

Error in ==> func_B at 3
func_C

Error in ==> func_A at 3
func_B

La fonction où l'erreur s'est produite est localisée (en lisant le message de bas en haut) func_A.m => func_B.m => func_C.m. L'analyse de l'erreur s'effectue ensuite comme dans le cas précédent.

Note : lorsqu'un nom de fichier est souligné dans un message d'erreur, il est possible de cliquer dessus dans le Command Window pour l'ouvrir automatiquement à la ligne erronée dans l'éditeur de fichier.

Mis à jour le 28 octobre 2012  par Jérôme Briot

MATLAB ne nécessitant pas la déclaration des variables, l'allocation dynamique de mémoire est donc supportée. Il est alors possible de faire évoluer dynamiquement la taille d'une matrice.

Par exemple :

 
Sélectionnez
for n = 1:5
    X(n) = rand;
end
X

Le code ci-dessus renvoie un vecteur X contenant 5 valeurs aléatoires.

Il est également possible de concaténer dynamiquement des valeurs dans une matrice. Pour ce faire, il faut déclarer un matrice vide [] avant la première concaténation.

Par exemple :

 
Sélectionnez
X = [];
for n = 1:5
    X = [X rand(1,n)];
end
X

Si, dans le cas de la concaténation, la matrice n'est pas définie vide avant, MATLAB renvoie ce message d'erreur :

 
Sélectionnez
??? Undefined function or variable 'X'.

L'allocation dynamique de mémoire est très flexible mais peut rapidement pénaliser la vitesse d'exécution du code (surtout dans le cas de la concaténation). Dans ce cas, on cherchera à optimiser le code en utilisant la préallocation de mémoire.

Créé le 17 juin 2007  par Jérôme Briot

Lien : Qu'est-ce que la préallocation de mémoire ?

Sous MATLAB, une matrice ne peut occuper qu'un bloc de mémoire contiguë (non fragmentée).
Lorsque sa taille augmente, MATLAB doit trouver des blocs de mémoire suffisamment grands pour la stocker.
La préallocation de mémoire consiste donc à créer, dès le départ, une matrice à sa taille définitive afin d'accélérer son remplissage en évitant à MATLAB de rechercher ultérieurement des blocs de mémoire disponibles de taille suffisante.

La préallocation s'effectue généralement en utilisant les fonctions zerosDocumentation de la fonction zeros ou onesDocumentation de la fonction ones.

L'exemple suivant est très simple et très théorique. D'autres paramètres doivent bien sûr être pris en compte (complexité du programme, MATLAB JIT, activité des autres programmes). Malgré tout, il met en évidence la nécessité de comprendre la gestion de la mémoire par MATLAB afin d'optimiser ses programmes.

Prenons un exemple simple :

Lors d'une session MATLAB, il ne reste plus en mémoire que trois blocs de mémoire contiguë de taille respective 1Mo, 2Mo et 5Mo. Le code à exécuter crée un vecteur X de taille 1x655360 éléments (655360*8/1024/1024 = 5Mo) à l'intérieur d'une boucle FOR-END comme ceci :

 
Sélectionnez
for n = 1:655360
    X(n) = rand;
end
% Ou 
x = [];
for n = 1:655360
    X = [X rand];
end

On peut affirmer que ce code s'exécutera jusqu'à sa fin sans erreur et que X sera bien un vecteur de taille 1x655360.

Regardons la gestion de la mémoire.

Tant que n sera inférieur à 131072 (131072*8/1024/1024 = 1Mo), MATLAB stockera X dans le bloc de 1Mo.

A l'itération suivante, le bloc de 1Mo sera trop petit. MATLAB copiera donc l'intégralité de X dans le bloc de 2Mo avant de poursuivre les itérations.

Ensuite, tant que n sera inférieur à 262144 (262144*8/1024/1024 = 2Mo), MATLAB stockera maintenant X dans le bloc de 2Mo. A l'itération suivante, le bloc de 2Mo sera trop petit. MATLAB déplacera encore une fois l'intégralité de X dans le bloc de 5Mo avant de poursuivre les itérations jusqu'à la fin du programme.

Prenons le même exemple, en effectuant la préallocation de X à sa taille définitive avant la boucle FOR-END

 
Sélectionnez
X = zeros(1,655360);
for n = 1:655360
    X(n) = rand;
end

Regardons la gestion de la mémoire.

Dès le début du programme, MATLAB cherchera le bloc de mémoire pouvant contenir X=zeros(1,655360); soit le bloc de 5Mo. On se rend bien compte que MATLAB n'aura plus besoin de déplacer l'intégralité de X durant l'exécution du code. Le code s'exécutera plus rapidement.

Encore une fois, l'exemple précédent est très simple et très théorique. D'autres paramètres doivent bien sur être pris en compte (complexité du programme, MATLAB JIT, activité des autres programmes). Malgré tout, il met en évidence la nécessité de comprendre la gestion de la mémoire par MATLAB afin d'optimiser ses programmes.

Voici un exemple simple chronométré où l'on remarque que la préallocation réduit le temps d'exécution du code :

 
Sélectionnez
>> clear X; tic; for n = 1:75000, X(n) = rand; end; toc % Sans préallocation

elapsed_time =

   11.3590

>> clear X; X = zeros(1,75000); tic; for n = 1:75000, X(n) = rand; end; toc % Avec préallocation

elapsed_time =

     0.1880
Créé le 27 mai 2007  par Jérôme Briot

Lien : 1106 - Memory Management Guide
Lien : How do I pre-allocate memory when using MATLAB?

La pré-allocation de mémoire n'est efficace que sur des matrices de tailles suffisantes. Utilisée avec des matrices de petites tailles, sa mise en place peut être plus longue que l'ensemble des affectations des éléments de la matrice.

Créé le 27 mai 2007  par Jérôme Briot
  • Un fichier fonction est un fichier d'extension .m contenant la définition d'une fonction. Celui-ci doit impérativement commencer par le mot-clé function suivi par une liste des paramètres facultatifs encadrant le nom de la fonction, à laquelle on donnera le même nom que le fichier :

     
    Sélectionnez
    function [sortie1, sortie2, ...] = nomFonction(entree1, entree2, ...)

    Exemples :

    • fichier fonction sans argument d'entrée ni de sortie :

       
      Sélectionnez
      function nomFonction
    • fichier fonction sans argument de sortie :

       
      Sélectionnez
      function nomFonction(entree1, entree2, ...)
    • fichier fonction sans argument d'entrée :

       
      Sélectionnez
      function [sortie1, sortie2, ...] = nomFonction

    Il est possible de définir plusieurs fonctions au sein d'un même fichier, mais seule la première (principale, du même nom que le fichier) pourra être utilisée extérieurement. Les autres fonctions ne serviront qu'à son bon fonctionnement.

  • Un fichier script, de même extension .m, est un fichier contenant du code MATLAB, mais aucune définition de fonction.
    Il est simplement appelé par le nom du fichier comme une fonction sans argument d'entré/sortie, et les éventuelles variables créées le sont dans le workspace dans lequel il est appelé.

Vous ne pouvez pas mélanger les deux, dans le cas contraire vous obtiendrez l'erreur Function definitions are not permitted at the prompt or in scripts.

Dans la pratique on parle de script et de fonction et non pas de fichier script ou fichier fonction.

Créé le 26 juin 2013  par Jérôme Marsaguet, Jérôme Briot

Il existe deux façons d'appeler une fonction :

  1. La syntaxe « ligne de commande » : le nom de la fonction est suivi par les arguments séparés par des espaces :

     
    Sélectionnez
    nomFonction arg1 arg2 ... argn

    Les arguments sont traités comme chaînes de caractères :

     
    Sélectionnez
    fileName = 'monFichier.mat';
    nomFonction fileName
    % passera la chaîne 'fileName' à la fonction et non 'monFichier.mat'
  2. La syntaxe « fonction » : le nom de la fonction est suivi par les arguments mis entre parenthèses et séparés par des virgules :

     
    Sélectionnez
    nomFonction(arg1, arg2, ..., argn)

    Cette deuxième syntaxe, contrairement à la première, permet de rentrer des paramètres variables et de récupérer les sorties de la fonction.

Exemples d'utilisation avec des fonctions utilisant souvent la première syntaxe :

 
Sélectionnez
save monFichier.mat X Y
% équivalant à
save('monFichier.mat', 'X', 'Y')
% équivalant à
fileName = 'monFichier.mat';
variables = {'X', 'Y'};
save(fileName, variables{:})
 
Sélectionnez
load monFichier.mat X Y
% équivalant à
load('monFichier.mat', 'X', 'Y')
% presque équivalant à
S = load('monFichier.mat', 'X', 'Y')
S.X
S.Y

Attention avec l'utilisation de la première syntaxe avec des chemins comportant des espaces :

 
Sélectionnez
>> cd C:\mon chemin % équivaut à passer deux arguments 'C:\mon' et 'chemin'
??? Error using ==> cd
Too many input arguments.
>> cd 'C:\mon chemin' % Il faut rajouter les simples quote
% Ou simplement la deuxième syntaxe :
cd('C:\mon chemin')
 
Sélectionnez
fileName = 'monFichier.jpg';
eval(['print -djpeg ' fileName]); 
% l'emploi d'eval à éviter devient inutile en utilisant la deuxième syntaxe :
print('-djpeg', fileName)
Créé le 2 mai 2013  par Jérôme Marsaguet

Lien : syntax - Two ways to call MATLAB functions

  • vararginDocumentation de la fonction varargin : utilisé en dernier paramètre d'entrée d'une fonction, il se présente sous forme d'un tableau de cellules et permet d'avoir un nombre variable d'arguments en entrée. Chaque entrée sera alors contenue dans une cellule de ce tableau.
  • narginDocumentation de la fonction nargin : permet de déterminer le nombre d'entrées d'une fonction :

    • utilisé sans argument au sein d'une fonction, il retourne le nombre de paramètres d'entrée passés à cette fonction,
    • utilisé avec le nom ou le handle d'une fonction en argument, il retourne le nombre d'entrées que la fonction prend (attention ce nombre est négatif si varargin figure parmi les entrées).

    Pour la fonction exemple définie ci-après :

     
    Sélectionnez
    function exemple(a, b, varargin)
    nb_entrees = nargin
    varargin

    les appels suivants donneront :

     
    Sélectionnez
    >> exemple(1,2,3,4)
    
    nb_entrees =
    
         4
    
    varargin = 
    
        [3]    [4]
    
    >> exemple(1,2)
    
    nb_entrees =
    
         2
    
    varargin = 
    
         {}
    
    >> nargin(@exemple) % ou nargin('exemple')
    
    ans =
    
        -3
nargin pourra entre autre servir à fournir des valeurs par défaut si le paramètre n'est pas rentré. Exemple :
 
Sélectionnez
function exemple(a)

if nargin < 1
    a = 0;
end

% Reste du code

Lorsque la fonction exemple sera appelée sans aucun argument : exemple(), la variable a aura ici la valeur 0 par défaut.


Symétriquement en sortie nous avons :

  • varargoutDocumentation de la fonction varargout : utilisé en dernier argument de sortie, il permet d'avoir un nombre variable de paramètre de sortie. Il est utilisé dans la fonction comme un tableau de cellules, chaque cellule représentant une sortie ;
  • nargoutDocumentation de la fonction nargout : permet de déterminer le nombre de sorties d'une fonction :

    • utilisé sans argument au sein d'une fonction, il retourne le nombre de paramètres de sortie demandés par l'appel de cette fonction,
    • utilisé avec le nom ou le handle d'une fonction en argument, il retourne le nombre de sorties que la fonction retourne (attention ce nombre est négatif si varargout figure parmi les sorties).

    Pour la fonction exemple définie ci-après :

     
    Sélectionnez
    function [s1, s2, varargout] = exemple
    nb_sorties = nargout
    s1 = 1;
    s2 = 2;
    if nb_sorties > 2
        varargout{1} = 3;
    end
    if nb_sorties > 3
        varargout{2} = 4;
    end

    les appels suivants donneront :

     
    Sélectionnez
    >> nargout(@exemple) % ou nargout('exemple')
    
    ans =
    
        -3
    
    >> [a, b, c] = exemple
    
    nb_sorties =
    
         3
    
    
    a =
    
         1
    
    
    b =
    
         2
    
    
    c =
    
         3
    
    >> [a, b, d{1:2}] = exemple
    
    nb_sorties =
    
         4
    
    
    a =
    
         1
    
    
    b =
    
         2
    
    
    d = 
    
        [3]    [4]
Créé le 13 août 2014  par Jérôme Marsaguet

Disponible uniquement à partir de la version R14 7.0.

Une fonction imbriquée (nested function en anglais) est une fonction contenue à l'intérieur d'une autre (mère). Elle offre la possibilité de manipuler les variables déclarées dans la fonction mère, et d'appeler les mêmes fonctions qu'elle. On peut avoir autant de niveaux d'imbrication que l'on souhaite.

Une fonction imbriquée peut être appelée depuis
  • la fonction du niveau directement supérieur dans laquelle elle se trouve ;
  • une autre fonction imbriquée du même niveau ;
  • n'importe quelle fonction imbriquée à l'intérieur de celle-ci.

À moins de faire passer son handle, elle ne sera pas utilisable par une fonction extérieure.

Exemple :

 
Sélectionnez
function fonction_mere

a = 1;
fonction_imbriquee1
fonction_imbriquee2
sous_fonction
% Ne peut pas appeler fonction_imbriquee2_2
 
    function fonction_imbriquee1
        % a peut être lu
        b = a + 1;
        % Peut utiliser fonction_imbriquee2 de même niveau
        fonction_imbriquee2
        % Ne peut pas appeler fonction_imbriquee2_2
    end
    function fonction_imbriquee2
        % Ne peut pas utiliser b contenue dans fonction_imbriquee1
        % a peut être changé
        a = 2;
        fonction_imbriquee2_2
        % Peut appeler toute fonction accessible par la fonction mère
        sous_fonction

        function fonction_imbriquee2_2
            % Peut utiliser a
        end
    end % <= end de la fonction_imbriquee2


end	% <= end de la fonction mère

function sous_fonction
    % Ne peut utiliser ni a, ni b
    % Ne peut appeler ni fonction_imbriquee1 ni fonction_imbriquee2 ni fonction_imbriquee2_2 
end

Vous trouverez un exemple d'utilisation de fonctions imbriquées pour la création d'une interface graphique dans ce tutoriel Développement efficace des interfaces graphiques.

Mis à jour le 28 octobre 2012  par Jérôme Marsaguet

Lien : Nested Functions

Dans MATLAB, une variable peut être :

  • locale ;
  • globale ;
  • persistante.

Variable locale

Ces variables sont uniquement utilisables dans l'espace de travail où elles ont été définies.

L'espace de travail de base (MATLAB workspace) contient les variables locales créées à partir de l'invite de commandes (MATLAB command prompt) ainsi que celles définies dans les fichiers Script. Les fonctions possèdent leurs propres espaces de travail. Les variables locales créées dans une fonction ne sont visibles que dans cette fonction. Inversement, les variables de l'espace de travail de base (MATLAB workspace) ne sont pas directement visibles dans une fonction.

Aucune syntaxe particulière de définition n'est nécessaire pour les variables locales.

Variable globale

Ces variables sont communes à tous les espaces de travail où elles sont définies.

Il existe deux raisons fondamentales pour éviter d'utiliser ces variables :

  1. Plusieurs programmes indépendants peuvent utiliser le même nom pour une variable globale. Un programme indépendant peut donc modifier cette variable et entraîner des dysfonctionnements dans les autres programmes. Pour pallier ce problème, on peut préconiser de nommer les variables avec des noms longs suffisamment explicites et d'utiliser une casse en lettres majuscules ;
  2. La modification du nom de la variable a posteriori, du fait de la déclaration dans chaque programme, peut être très difficile et très périlleuse.

L'utilisation des variables globales doit être évitée. On cherchera plutôt à utiliser les arguments d'entrée/sortie des fonctions ou des variables persistantes si nécessaire.

La définition d'une variable globale doit être précédée du terme globalDocumentation mot clé global dans chacun des espaces de travail où cette variable sera utilisée.

Variable persistante

Les variables persistantes sont des variables locales qui :

  • ne peuvent être définies que dans une fonction ;
  • ne sont pas détruites à la fin de l'exécution de la fonction.

La définition d'une variable persistante doit être précédée du terme persistentDocumentation mot clé persistent

Mis à jour le 27 septembre 2012  par Jérôme Briot

Lien : Share Data Between Workspaces

Les variables créées à partir de l'invite de commandes (MATLAB command prompt) ou dans un fichier Script, existent jusqu'à ce qu'elles soient nettoyées (avec la fonction clearDocumentation de la fonction clear) ou que la session MATLAB soit finie.

Les variables créées à l'intérieur des fonctions existent jusqu'à la fin de l'exécution de la fonction à moins qu'elles ne soient de type persistante ou globale.

Cas particulier : Qu'est-ce qu'une fonction imbriquée (nested function) ? (nested functions - versions R14 7.0 ou supérieures de MATLAB).

Les variables créées dans une fonction sont connues par ses fonctions imbriquées et peuvent donc être modifiées à l'intérieur de celles-ci.

Mis à jour le 27 septembre 2012  par Jérôme Briot

Les opérateurs ' et .' sont tous les deux utilisés pour calculer la transposée d'une matrice.

La différence est que l'opérateur ' calcule la transposée de la matrice conjuguée. Il n'est donc utile qu'avec des matrices à valeurs complexes.

Dans le cas de matrices non complexes, on préférera utiliser l'opérateur .'

 
Sélectionnez
>> A = [1 2 ; 3 4]

A =

     1     2
     3     4

>> A'

ans =

     1     3
     2     4

>> A.'

ans =

     1     3
     2     4

>> A = [1+j 1+2j ; 1+3j 1+4j]

A =

   1.0000 + 1.0000i   1.0000 + 2.0000i
   1.0000 + 3.0000i   1.0000 + 4.0000i

>> A'

ans =

   1.0000 - 1.0000i   1.0000 - 3.0000i
   1.0000 - 2.0000i   1.0000 - 4.0000i

>> A.'

ans =

   1.0000 + 1.0000i   1.0000 + 3.0000i
   1.0000 + 2.0000i   1.0000 + 4.0000i
Créé le 27 mai 2007  par Jérôme Briot

Les opérateurs logiques & et | servent à faire des comparaisons logiques ET et OU.

Les opérateurs logiques && et || sont équivalents aux opérateurs & et |.

Ils sont appelés opérateurs "courts-circuits" car ils permettent d'accélérer le code en diminuant le nombre de tests à effectuer pour valider une combinaison d'opérations logiques.

Prenons le cas d'une opération logique avec deux opérandes.

Avec l'opérateur &, MATLAB détermine la valeur booléenne des deux opérandes avant de faire le ET logique. Alors qu'avec &&, MATLAB commence par déterminer la valeur booléenne du premier opérande et ne teste le second que si le premier a pour valeur VRAI.

L'expression

 
Sélectionnez
A & B

revient à faire :

 
Sélectionnez
SI (A==VRAI) ET  SI (B==VRAI)
    ...
FIN

alors que l'expression

 
Sélectionnez
A && B

revient à faire :

 
Sélectionnez
SI (A==VRAI)
    SI (B==VRAI)
        ...
    FIN
FIN

Avec l'opérateur |, MATLAB détermine la valeur booléenne des deux opérandes avant de faire le OU logique. Alors qu'avec ||, MATLAB commence par déterminer la valeur booléenne du premier opérande et ne teste le second que si le premier a pour valeur FAUX.

L'expression

 
Sélectionnez
A | B

revient à faire :

 
Sélectionnez
SI (A==VRAI) OU  SI (B==VRAI)
    ...
FIN

alors que l'expression

 
Sélectionnez
A || B

revient à faire :

 
Sélectionnez
SI (A==VRAI)
    ...
SINONSI (B==VRAI)
    ...
FIN
Créé le 28 octobre 2012  par Jérôme Briot

Lien : Logical Operators

MATLAB, comme tous les autres langages de programmation est confronté à l'imprécision des calculs avec des nombres à virgule flottante.

On peut aisément mettre en évidence cette limitation sous MATLAB en faisant :

 
Sélectionnez
>> (0.3-0.2-0.1)==0

ans =

     0
     
>> 0.3-0.2-0.1

ans =

 -2.7756e-017

ou encore :

 
Sélectionnez
>> a = 0:0.1:1;
>> sprintf('%.20f\n',a)

ans =

0.00000000000000000000
0.10000000000000001000
0.20000000000000001000
0.30000000000000004000
0.40000000000000002000
0.50000000000000000000
0.59999999999999998000
0.69999999999999996000
0.80000000000000004000
0.90000000000000002000
1.00000000000000000000

Il est nécessaire d'être particulièrement vigilant lorsque des tests logiques d'égalité sont effectués sur ces nombres.

Le code suivant illustre ce problème :

 
Sélectionnez
clc
for k = 0.1:0.1:0.5
    
    if k == 0.1
        fprintf('\nk est égale à %.1f',k);
    elseif k == 0.2
        fprintf('\nk est égale à %.1f',k);
    elseif k == 0.3
        fprintf('\nk est égale à %.1f',k);
    elseif k == 0.4
        fprintf('\nk est égale à %.1f',k);
    elseif k == 0.5
        fprintf('\nk est égale à %.1f',k);  
    else
        fprintf('\n*** k n''est pas égale à %.1f',k);
    end
    
end

MATLAB renvoie :

 
Sélectionnez
k est égale à 0.1
k est égale à 0.2
*** k n'est pas égale à 0.3
k est égale à 0.4
k est égale à 0.5

Le problème apparait également avec certaines fonctions comme par exemple findDocumentation de la fonction find :

 
Sélectionnez
a = 0:0.1:1;

find(a==0.3)

ans =

     []

Une solution dans ce cas consiste à introduire une tolérance dans le test d'égalité. La valeur de cette tolérance est fonction de l'ordre de grandeur des variables et de la précision de calcul recherchée dans votre problème.

Une version corrigée du code précédent pourrait être :

 
Sélectionnez
>> a = 0:0.1:1;
>> tol = 0.01;
>> find(abs(a-0.3)<tol)

ans =

     4
Mis à jour le 2 mai 2013  par Jérôme Briot

Lien : Floating points - IEEE Standard unifies arithmetic model, by Cleve Moler
Lien : Avoiding Common Problems with Floating-Point Arithmetic

Le format uintX (ou unsigned integer X bits) permet de stocker des valeurs entières non signées codées sur X bits. Une variable de ce type ne pourra stocker des valeurs que dans l'intervalle [0 2^X-1] seulement.
Ainsi tout calcul impliquant des variables de ce format visant à sortir de cet intervalle sera faussé.

Exemple pour une simple addition/soustraction :

 
Sélectionnez
>> im = uint8([100 200 ; 50 150])

im =

  100  200
   50  150

>> im(1,1) + im(2,1) % OK : 100 + 50 = 150 compris dans [0 255]

ans =

  150

>> im(1,2) + im(2,2) % 200 + 150 = 350 non compris dans [0 255] => on sature à 255

ans =

  255

>> im(2,2) - im(1,2) % 150 - 200 = -50 non compris dans [0 255] => on sature à 0

ans =

  0

Il faudra le plus souvent caster ces valeurs sous le format single ou double avant d'effectuer les opérations.

 
Sélectionnez
>> double(im(1,2)) + double(im(2,2))

ans =

   350

Note : on prendra pour habitude de ramener les images dans l'intervalle [0 1] lors du cast vers les types single et double afin de satisfaire la majorité des fonctions de l'Image Processing Toolbox et éviter des résultats inattendus du genre Pourquoi imshow affiche une image toute blanche et/ou noire ?.

Créé le 2 mai 2013  par Jérôme Marsaguet

Pour accéder à un élément d'une matrice, on emploie la syntaxe suivante :

 
Sélectionnez
M = magic(4)

M =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1
     
M(4,3)

ans =

     15

En réalité, MATLAB stocke les matrices sous forme de vecteurs colonnes dans la mémoire. Donc dans l'exemple précédent, M sera stockée comme ceci :

 
Sélectionnez
    16
     5
     9
     4
     2
    11
     7
    14
     3
    10
     6
    15
    13
     8
    12
     1

Ceci a pour conséquence de pouvoir accéder à n'importe quel élément d'une matrice en utilisant un seul index.

Pour récupérer la valeur stockée dans M(4,3), il suffit de faire :

 
Sélectionnez
M = magic(4)

M =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

M(12)

ans =

     15

La relation de passage entre l'indexage linéaire et l'indexage classique est :

 
Sélectionnez
M(i,j)
% est équivalent à :        
M(i+(j-1)*size(M,1))

Soit dans l'exemple précédent, M(4,3) <=> M(4+(3-1)*4) <=> M(12)

Cette technique d'indexage est très utile pour vectoriser les codes et ainsi éviter l'utilisation de boucles FOR-END imbriquées. Elle peut être employée avec tous les types de variables : matrices, chaines de caractères, tableaux de cellules, tableaux de structures ; quelque soit leur dimension.

Note : les fonctions sub2indDocumentation de la fonction sub2ind et ind2subDocumentation de la fonction ind2sub permettent de passer d'une méthode d'indexage à une autre.

Mis à jour le 15 juillet 2009  par Jérôme Briot

Lien : Qu'est-ce que l'indexage logique ?
Lien : Gestion des matricesTutoriel Gestion des matrices

L'indexage des matrices sert à accéder aux éléments qui y sont stockés et il s'utilise comme ceci :

 
Sélectionnez
>> X = [4 6 ; 2 3]

X =

     4     6
     2     3

>> X(1,2)

ans =

     6

Il est également possible d'utiliser l'indexage linéaire :

 
Sélectionnez
>> X(3)

ans =

     6

Il existe une troisième forme d'indexage basée sur les conditions logiques. On la désigne par indexage logique et on l'utilise principalement avec les opérateurs relationnels et les opérateurs logiques. Ce type d'indexage permet d'améliorer l'efficacité des codes en évitant l'utilisation de fonctions supplémentaires (principalement findDocumentation de la fonction find). L'indexage logique est souvent utilisé avec les fonctions anyDocumentation de la fonction any et allDocumentation de la fonction all.

Par exemple, dans le cas précédent, on souhaite trouver toutes les valeurs supérieures à 3, soit 4 et 6.

La méthode classique consisterait à utiliser find comme ceci :

 
Sélectionnez
>> X = [4 6 
        2 3];

>> idx = find(X>3) % Indexage linéaire : on récupère les indices i
                   %                     pour lesquels X(i)>3

idx =

   1
   3

>> X(idx)

ans =

   4
   6

L'indexage logique consiste simplement à se passer de find :

 
Sélectionnez
>> X = [4 6 
        2 3];

>> idx = (X>3) % Indexage logique : on récupère un tableau logique de même taille
               %                     une valeur «&#160;true&#160;» (= 1) correspond à un 
               %                    élément vérifiant la condition

idx =

   1   1
   0   0

>> X(idx) % On sélectionne alors les valeurs pour lesquelles idx est «&#160;true&#160;»

ans =

   4
   6

Comparaison en temps d'exécution :

 
Sélectionnez
M = rand(5000);

tic
idx = find(M>0.5);
N = M(idx);
toc

elapsed_time =

    1.7500
 
Sélectionnez
clear idx N

tic
idx = M>0.5;
N = M(idx);
toc

elapsed_time =

    1.0470
Mis à jour le 13 août 2014  par Jérôme Briot

Lien : Qu'est-ce que l'indexage linéaire ?
Lien : Gestion des matricesTutoriel Gestion des matrices

Oubliez tout de suite cette idée, c'est une très mauvaise pratique qui vous donnera inutilement du fil à retordre et réduira considérablement la lisibilité de votre code !

La bonne méthode consiste à ne créer qu'un seul tableau (numérique ou de cellules selon le cas) de N éléments.

Si les variables sont de même type et de même dimension, il est possible de créer une variable de même type les contenant toutes (concaténation).

  • Par exemple, à la place de créer trois vecteurs A1, A2 et A3 de dimension 1x5 :

     
    Sélectionnez
    A1 = [1 2 3 4 5];
    A2 = [1 2 3 4 5];
    A3 = [1 2 3 4 5];

    il est possible de créer une matrice de dimension 3x5 où chaque ligne correspond à un des vecteurs :

     
    Sélectionnez
    A = [ 1 2 3 4 5 ; 
          1 2 3 4 5 ; 
          1 2 3 4 5 ];

Si les variables sont de type et/ou de dimension différents, il faut utiliser un tableau de cellules.

  • Par exemple, à la place de créer trois vecteurs B1, B2 et B3 de tailles différentes :

     
    Sélectionnez
    B1 = [1 2 3];
    B2 = [1 2 3 4];
    B3 = [1 2 3 4 5];

    il faut créer un tableau de cellules de dimension 1x3 :

     
    Sélectionnez
    B{1} = [1 2 3];
    B{2} = [1 2 3 4];
    B{3} = [1 2 3 4 5];

    Exemple au sein d'une boucle :

     
    Sélectionnez
    N = 10;
    A_fixe = zeros(N,4); % préallocation du tableau numérique de taille Nx4
    A_varie = cell(N,1); % préallocation du tableau de cellules de N éléments
    for i = 1:N
        v_fixe = rand(1,4); % exemple de vecteur dont la taille est fixe (4 valeurs)
                            % => Un tableau numérique de taille Nx4 suffit
        A_fixe(i,:) = v_fixe; % Notes les « : » pour sélectionner les 4 éléments de la ligne i
    
        v_varie = 1:i; % exemple de vecteur dont la longueur varie
                       % => Un tableau de cellules est nécessaire
        A_varie{i} = v_varie; % Notez les accolades pour l'indexage
    end

Vous avez aussi la possibilité d'utiliser une structure avec des champs dynamiques.

Si vous vous entêtez tout de même dans cette voie, la solution réside dans l'utilisation de la fonction evalDocumentation de la fonction eval, fonction qui est à éviter au maximum :

  • perte totale de clarté et de lisibilité du code ;
  • perte de performance par la nécessité de réinterpréter à chaque fois la chaîne de caractères argument de eval ;
  • complexité de l'analyse du code (fonction appelée, fonction appelante…) ;
  • incompatibilité de eval avec le MATLAB Compiler dans les anciennes versions de MATLAB ;
  • encombrement du workspace avec un nombre important de variables ;
  • obligation de déclarer chacune des variables lors de l'emploi de fonctions imbriquées.

Exemple précédent avec eval - méthode non recommandée !

 
Sélectionnez
N = 10;
for i = 1:N
    v = ... 
    eval( sprintf('A%d = v;' , i) )
end
Mis à jour le 13 août 2014  par Jérôme Briot, Jérôme Marsaguet

Lien : Qu'est-ce que la préallocation de mémoire ?
Lien : What Is the EVAL Function, When Should I Use It, and How Can I Avoid It?
Lien : Evading eval, by Loren Shure (blog)

Les 2 scenarii possibles :

Créé le 1er juillet 2010  par Aurélien Queffurust

Lien : Qu'est-ce qu'un fichier p (p-code) ?
Lien : How can I distribute my application and hide my code for users who may or may not have MATLAB?
Lien : Can I depend on the MATLAB Compiler 4.0 (R14) to protect my intellectual property?
Lien : "How do I prevent my P-code from being re-distributed?

Le fichier p (pseudocode pré-analysé) est un fichier généré par la fonction pcodeDocumentation de la fonction pcode à partir d'un fichier m.

Il faut partir de l'exécution des fichiers m (script ou fonction, peu importe) pour mieux comprendre.

Lorsque un fichier m est exécuté, MATLAB vérifie d'abord la syntaxe (pour d'éventuelles erreurs) et transforme ensuite le code lisible (la syntaxe MATLAB) en code machine (binaire). C'est ce dernier code qui est réellement exécuté.

On voit bien que toutes ces opérations influent sur le temps d'exécution du code. Or, pour un fichier m, MATLAB ne fait ces opérations qu'une seule fois. À la deuxième exécution, il se sert du code transformé la première fois (qu'il a stocké en mémoire) et non plus du fichier m.

Un fichier p reprend exactement les mêmes opérations que citées précédemment. L'intérêt premier est donc d'accélérer l'exécution d'un code. Mais ce gain de temps ne sera sensible que si le code n'est exécuté qu'une seule fois.

En pratique, avec les nouvelles versions de MATLAB, ce gain de temps est de moins en moins visible.

Il existe un autre avantage à utiliser des fichiers p. Comme ces fichiers contiennent du code binaire, ils sont (presque) illisibles. Donc, contrairement aux fichier m, on peut cacher le source de son code en générant un fichier p.

Note : pour être plus précis, il y a une différence entre l'exécution d'un script et d'une fonction. Alors que la fonction n'est analysée qu'une seule fois (le code binaire est stocké), MATLAB analyse le script à chaque exécution sans stockage du code binaire.

Le format des fichiers p a changé entre les versions R2007a et R2007b de MATLAB.
Il y a donc incompatibilité descendante à partir cette version.

Créé le 30 juin 2008  par Jérôme Briot

NaNDocumentation de la fonction NaN est l'acronyme de « Not a Number » que l'on peut traduire par « pas un nombre ».

Cette valeur est attribuée à une variable lors d'une opération qui n'est pas définie numériquement.
Comme par exemple, pour la division de 0 par 0 :

 
Sélectionnez
>> a = 0/0

a =

   NaN

Le résultat d'une opération arithmétique entre une variable et un NaN donne toujours un NaN :

 
Sélectionnez
>> a = 1+NaN

a =

   NaN

>> b = 1-NaN

b =

   NaN

>> c = 1*NaN

c =

   NaN

>> d = 1/NaN

d =

   NaN

Remarque : deux variables NaN ne sont pas équivalentes (ceci est conforme à la définition IEEE 754) :

 
Sélectionnez
>> a = NaN;
>> b = NaN;
>> a == b

ans =

     0

De même :

 
Sélectionnez
>> a = [3 NaN NaN 6 3 5 NaN 5 1]

a =

     3   NaN   NaN     6     3     5   NaN     5     1

>> ua = unique(a)

ua =

     1     3     5     6   NaN   NaN   NaN

Pour savoir si un élément d'un vecteur est de type NaN, il faut utiliser la fonction isnanDocumentation de la fonction isnan :

 
Sélectionnez
>> a = [3 NaN NaN 6 3 5 NaN 5 1]

a =

     3   NaN   NaN     6     3     5   NaN     5     1

>> a == NaN 

ans =

     0     0     0     0     0     0     0     0     0

>> isnan(a)

ans =

     0     1     1     0     0     0     1     0     0

Note : la syntaxe MATLAB est soit NaN, soit nan :

 
Sélectionnez
>> a = NaN

a =

   NaN

>> a = nan

a =

   NaN

>> a = Nan
??? Undefined function or variable 'Nan'.

>> a = nAn
??? Undefined function or variable 'nAn'.

>> a = NAn
??? Undefined function or variable 'NAn'.

>> a = naN
??? Undefined function or variable 'naN'.

>> a = NAN
??? Undefined function or variable 'NAN'.

Remarque : la fonction NaN peut aussi être utilisée de la même façon que zeros, ones, true, false ou Inf pour obtenir un tableau initial rempli de valeurs NaN :

 
Sélectionnez
>> tab = NaN(3,4)

tab =

   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
   NaN   NaN   NaN   NaN
Mis à jour le 13 août 2014  par Jérôme Briot

ans, ou « most recent ANSwer », est une variable créée de façon automatique lorsqu'une instruction retourne un résultat qui n'est affecté à aucune variable. ans garde alors en mémoire cette dernière valeur calculée.

Note : on évitera d'utiliser ans comme variable « normale » dans le code, elle servira essentiellement à effectuer des calculs manuels dans la Command Window.

Créé le 13 août 2014  par Jérôme Marsaguet

Notes :

  • les formules de calcul données ici sont approximatives. Malgré tout, elles permettent d'obtenir une bonne estimation de la quantité de mémoire nécessaire au stockage des variables sous MATLAB ;
  • ces formules ne concernent pas les matrices creuses (sparse matrix) ;
  • dans le cas des tableaux de cellules ou des structures, les formules peuvent s'appliquer aux contenus des cellules et/ou des champs (néanmoins le résultat obtenu doit être majoré).

Il existe deux unités pour quantifier la mémoire : l'octet (byte en anglais) et le bit (bit en anglais).

Sur la plupart des machines modernes, l'équivalence entre les deux unités est : 1 octet = 8 bits.

Une variable occupe une certaine quantité de mémoire en fonction de ses dimensions (nombre colonne x nombre de ligne pour un tableau par exemple) et en fonction de sa classe.

La classe par défaut sous MATLAB est la classe Double :

 
Sélectionnez
>> x = 1

x =

     1

>> class(x)

ans =

double

Une seule valeur en classe Double occupe 64 bits soit 8 octets en mémoire :

 
Sélectionnez
>> whos x
  Name      Size            Bytes  Class     Attributes

  x         1x1                 8  double

Donc pour déterminer la quantité de mémoire en octets nécessaire au stockage d'une variable de classe Double, il suffit de multiplier ses dimensions par 8.

Par exemple, pour un tableau 100x50x3, la quantité de mémoire nécessaire en classe Double sera :

1000x500x3x8 = 12000000 octets

 
Sélectionnez
>> X = rand(1000,500,3);
>> whos X
  Name         Size                  Bytes  Class     Attributes

  X         1000x500x3            12000000  double

Pour exprimer cette quantité dans les multiples de l'octet que sont le kilo-octet (ko), le mega-octet (Mo) et le giga-octet (Go), il suffit de diviser par 1024 comme ceci :

1000x500x3x8/1024 = 11719 ko (environ)
1000x500x3x8/1024/1024 = 11.4 Mo (environ)
1000x500x3x8/1024/1024/1024 = 0.011 Go (environ)


Il existe bien entendu d'autres classes de variable. Pour connaître l'espace nécessaire à leur stockage en mémoire, il suffit d'utiliser l'une des formules générales suivantes :

  • (dimension1 x dimension2 x dimension3 x ... x dimensionN)xf en octets
  • (dimension1 x dimension2 x dimension3 x ... x dimensionN)xf/1024 en kilo-octets
  • (dimension1 x dimension2 x dimension3 x ... x dimensionN)xf/1024/1024 en mega-octets
  • (dimension1 x dimension2 x dimension3 x ... x dimensionN)xf/1024/1024/1024 en giga-octets

Selon les classes les plus courantes disponibles dans MATLAB, f prendra les valeurs suivantes :

Classe Taille f
uint8, int8, logical 1 octet / 8 bits 1
uint16, int16, char 2 octets / 16 bits 2
uint32, int32, Single 4 octets / 32 bits 4
uint64, int64, Double 8 octets / 64 bits 8


Par exemple, le tableau 1000x500x3 qui nécessitait 11.4 Mo de mémoire en classe Double nécessitera en classe Single :

1000x500x3x4/1024/1024 = 5.7 Mo (environ)

Créé le 10 juillet 2009  par Jérôme Briot

Lien : Out of memory. Type HELP MEMORY for your options.Erreur Out of Memory
Lien : Gestion des matricesTutoriel Gestion des matrices

Il arrive que l'affichage de valeurs ne semble pas correct dans le Command Window de MATLAB. Lorsqu'il existe une grande variation entre les ordres de grandeur des variables, les valeurs faibles sont semble-t-il arrondies.

Par exemple, si on demande à MATLAB d'afficher le vecteur suivant :

 
Sélectionnez
X = [1E-6 1 1E6]

celui-ci affiche :

 
Sélectionnez
X =

  1.0e+006 *

    0.0000    0.0000    1.0000

Les deux premières valeurs sont semble-t-il arrondies à 0.

Il s'agit en fait juste d'un problème d'affichage des valeurs. Celles-ci ne sont en aucun cas arrondies par MATLAB. On peut le vérifier en modifiant la taille des valeurs à afficher avec la fonction formatDocumentation de la fonction format comme ceci :

 
Sélectionnez
format long
X = [1E-6 1 1E6]

Ce qui affiche :

 
Sélectionnez
X =

  1.0e+006 *

   0.000000000001000   0.000001000000000   1.000000000000000

ou encore en affichant uniquement la valeur la plus petite :

 
Sélectionnez
>> X(1)

ans =

  1.0000e-006
Créé le 13 juin 2011  par Jérôme Briot

Particulièrement utilisé pour des problèmes d'optimisation, dans des fonctions telles que cellfunDocumentation de la fonction cellfun, ou les interfaces graphiques pour attribuer les fonctions callback, l'opérateur @ sert à créer ou accéder à l'identifiant (ou handle) d'une fonction.

1) On peut ainsi se servir de ce symbole pour accéder au handle d'une fonction, et l'utiliser de la même façon :

 
Sélectionnez
>> myfun = @sin

myfun = 

    @sin

>> myfun(pi/2)

ans =

     1

2) On peut également s'en servir pour la création de fonctions anonymes :

 
Sélectionnez
>> myfun = @(x,y) x.^2 + y.^2

myfun = 

    @(x,y) x.^2 + y.^2


>> myfun([1 2],[3 4])

ans =

    10    20

Cette syntaxe équivaut à créer une fonction telle que

 
Sélectionnez
function r = maFonction(x,y)

r = x.^2 + y.^2;

et prendre son handle comme dans le 1).

3) Il peut servir à faire passer des arguments supplémentaires d'une fonction utilisée comme argument d'entrée d'une autre fonction (pour entrevoir les différentes méthodes : Passing Extra Parameters) :

 
Sélectionnez
a = ... % paramètre supplémentaire à faire passer
fun = @(x) fonctionAminimiser(x,a);
[x,fval] = fminsearch(fun, x0)

avec

 
Sélectionnez
function f = fonctionAminimiser(x,a)
% f = ...

4) Il est aussi possible de créer un handle de fonction à partir d'une chaine de caractères à l'aide de la fonction str2funcDocumentation de la fonction str2func :

 
Sélectionnez
>> myfun = str2func('sin')

myfun = 

    @sin

>> myfun = str2func('@(x,y) x.^2 + y.^2')

myfun = 

    @(x,y) x.^2 + y.^2
Mis à jour le 28 octobre 2012  par Jérôme Marsaguet

Lien : Anonymous Functions
Lien : Creating a Function Handle

Que ce soit pour générer le nom d'un fichier comportant un nombre ou autre, il est souvent utile de pouvoir effectuer une concaténation entre une chaîne de caractères et des valeurs numériques.
Toutefois cette concaténation ne se fait pas directement avec les habituels crochets [] car les deux parties sont des types différents. Or MATLAB stocke ses tableaux sous un unique type.
Ainsi lorsque l'on voudra concaténer une chaîne de caractères (type char) avec une ou plusieurs valeurs numériques (type double, single, uint8…) en utilisant les crochets, seul le type char sera retenu, et les valeurs numériques seront alors castées en char selon leur valeur dans le tableau ASCII, produisant le plus souvent des caractères non imprimables ou inattendus :

 
Sélectionnez
>> n = 48;
>> ['fichier_' n '.txt']

ans =

fichier_0.txt

Dans cet exemple, on s'attend à avoir '48' et non '0'. Or selon la table ASCII, le caractère '0' a pour valeur correspondante 48.

 
Sélectionnez
>> char(48)

ans =

0

La solution consiste donc à utiliser l'une des fonctions sprintfDocumentation de la fonction sprintf / num2strDocumentation de la fonction num2str :

 
Sélectionnez
>> n = 48;
>> sprintf('fichier_%d.txt',n)

ans =

fichier_48.txt

>> num2str(n,'fichier_%d.txt')

ans =

fichier_48.txt

Note : n étant ici un entier, le format '%d' est utilisé. Référez-vous à la documentation des fonctions pour l'utilisation de formats et types différents.

Créé le 2 mai 2013  par Jérôme Marsaguet

Lien : Comment nommer une suite de fichiers : nom_1.ext, nom_2.ext... nom_N.ext ?

Les chaînes de caractères sont représentées sous MATLAB par des vecteurs lignes de type char :

 
Sélectionnez
'ma chaîne' 
% équivaut à 
['m' , 'a' , ' ' , 'c' , 'h' , 'a' , 'î' , 'n' , 'e']

Par conséquent si l'on souhaite effectuer la comparaison entre deux chaînes, ce n'est pas l'opérateur == (fonction eqDocumentation de la fonction eq ; qui donnera une erreur si les chaînes ne sont pas de la même longueur ou un vecteur logique plutôt qu'une seule valeur true/false dans le cas contraire) qu'il faut utiliser mais la fonction strcmpDocumentation de la fonction strcmp (ou strcmpiDocumentation de la fonction strcmpi, strncmpDocumentation de la fonction strncmp et strncmpiDocumentation de la fonction strncmpi selon le type comparaison que l'on souhaite effectuer).

 
Sélectionnez
>> 'comparer' == 'chaînes'	 % Chaînes de longueurs différentes 
??? Error using ==> eq
Matrix dimensions must agree.

>> strcmp('comparer', 'chaînes') % Chaînes de longueurs différentes 

ans =

     0

>> 'comparer' == 'comparer' % Chaînes de mêmes longueurs 

ans =

     1     1     1     1     1     1     1     1

>> strcmp('comparer', 'comparer') % Chaînes de mêmes longueurs 

ans =

     1

Attention : à la différence de la fonction C du même nom, cette fonction renvoie true lorsque les deux chaînes sont égales, et false sinon.

Remarque : cette fonction accepte aussi des tableaux de cellules contenant des chaînes de caractères.

 
Sélectionnez
>> noms = {'Durand' , 'Dupond' , 'Martin'};
>> strcmp('Dupond', noms)

ans =

     0     1     0
Créé le 2 mai 2013  par Jérôme Marsaguet
  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2007-2013 Developpez LLC Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.