MATLAB Language
Meilleures pratiques MATLAB
Recherche…
Remarques
Cette rubrique affiche les meilleures pratiques que la communauté a apprises au fil du temps.
Gardez les lignes courtes
Utilisez le caractère de continuation (points de suspension) ...
pour continuer la longue déclaration.
Exemple:
MyFunc( parameter1,parameter2,parameter3,parameter4, parameter5, parameter6,parameter7, parameter8, parameter9)
peut être remplacé par:
MyFunc( parameter1, ...
parameter2, ...
parameter3, ...
parameter4, ...
parameter5, ...
parameter6, ...
parameter7, ...
parameter8, ...
parameter9)
Indentez le code correctement
Une indentation correcte donne non seulement un aspect esthétique, mais augmente également la lisibilité du code.
Par exemple, considérez le code suivant:
%no need to understand the code, just give it a look
n = 2;
bf = false;
while n>1
for ii = 1:n
for jj = 1:n
if ii+jj>30
bf = true;
break
end
end
if bf
break
end
end
if bf
break
end
n = n + 1;
end
Comme vous pouvez le voir, vous devez regarder attentivement pour voir quelle boucle et if
instructions se terminent où.
Avec l'indentation intelligente, vous aurez ce look:
n = 2;
bf = false;
while n>1
for ii = 1:n
for jj = 1:n
if ii+jj>30
bf = true;
break
end
end
if bf
break
end
end
if bf
break
end
n = n + 1;
end
Cela indique clairement le début et la fin de l'instruction loop / if
.
Vous pouvez faire une mise en retrait intelligente en:
• sélectionner tout votre code ( Ctrl + A )
• puis en appuyant sur Ctrl + I ou en cliquant à partir de la barre d'édition.
Utiliser assert
Matlab permet à certaines erreurs très triviales de passer inaperçues, ce qui peut entraîner une erreur beaucoup plus tard dans la course, rendant le débogage difficile. Si vous assumez quelque chose à propos de vos variables, validez- le.
function out1 = get_cell_value_at_index(scalar1,cell2)
assert(isscalar(scalar1),'1st input must be a scalar')
assert(iscell(cell2),'2nd input must be a cell array')
assert(numel(cell2) >= scalar1),'2nd input must have more elements than the value of the 1st input')
assert(~isempty(cell2{scalar1}),'2nd input at location is empty')
out1 = cell2{scalar1};
Éviter les boucles
La plupart du temps, les boucles coûtent cher avec Matlab. Votre code sera plus rapide si vous utilisez la vectorisation. Cela rend souvent votre code plus modulaire, facilement modifiable et plus facile à déboguer. L'inconvénient majeur est que vous devez prendre le temps de planifier les structures de données et que les erreurs de dimension sont plus faciles à trouver.
Exemples
N'écris pas
for t=0:0.1:2*pi
R(end+1)=cos(t);
end
mais
t=0:0.1:2*pi;
R=cos(t)
N'écris pas
for i=1:n
for j=1:m
c(i,j)=a(i)+2*b(j);
end
end
Mais quelque chose de similaire à
c=repmat(a.',1,m)+2*repmat(b,n,1)
Pour plus de détails, voir vectorisation
Créer un nom unique pour un fichier temporaire
Lors du codage d'un script ou d'une fonction, il peut arriver qu'un ou plusieurs fichiers temporaires soient nécessaires pour, par exemple, stocker des données.
Afin d'éviter d'écraser un fichier existant ou d'occulter une fonction MATLAB, la fonction tempname peut être utilisée pour générer un nom unique pour un fichier temporaire dans le dossier temporaire du système.
my_temp_file=tempname
Le nom de fichier est généré sans l'extension; il peut être ajouté en concaténant l'extension souhaitée au nom généré par tempname
my_temp_file_with_ext=[tempname '.txt']
La localisation du dossier temporaire du système peut être récupérée en calant la fonction tempdir .
Si, pendant l'exécution de la fonction / script, le fichier temporaire n'est plus nécessaire, il peut être supprimé en utilisant la fonction delete
Depuis delete
ne demande pas de confirmation, il pourrait être utile de mettre on
la possibilité de déplacer le fichier à supprimer dans le recycle
dossier.
Cela peut être fait en utilisant la fonction recycle de cette façon:
recycle('on')
Dans l'exemple suivant, une utilisation possible des fonctions tempname
, delete
et recycle
est proposée.
%
% Create some example data
%
theta=0:.1:2*pi;
x=cos(theta);
y=sin(theta);
%
% Generate the temporary filename
%
my_temp_file=[tempname '.mat'];
%
% Split the filename (path, name, extension) and display them in a message box
[tmp_file_path,tmp_file_name, tmp_file_ext]=fileparts(my_temp_file)
uiwait(msgbox(sprintf('Path= %s\nName= %s\nExt= %s', ...
tmp_file_path,tmp_file_name,tmp_file_ext),'TEMPORARY FILE'))
%
% Save the varaibles in a temporary file
%
save(my_temp_file,'x','y','theta')
%
% Load the varaibles from the temporary file
%
load(my_temp_file)
%
% Set the reclycle option on
%
recycle('on')
%
% Delete the temporary file
%
delete(my_temp_file)
Caveat
Le nom de fichier temporaire est généré à l'aide de la méthode java.util.UUID.randomUUID
( randomUUID ).
Si MATLAB est exécuté sans JVM, le nom de fichier temporaire est généré en utilisant
matlab.internal.timing.timing
basé sur le compteur et l'heure du processeur. Dans ce cas, le nom de fichier temporaire n'est pas garanti unique.
Utiliser les attributs valides
La fonction validateattributes peut être utilisée pour valider un tableau par rapport à un ensemble de spécifications
Il peut donc être utilisé pour valider l'entrée fournie à une fonction.
Dans l'exemple suivant, la fonction test_validateattributes
requiert trois entrées
function test_validateattributes(input_1,input_2,input_3)
Les spécifications d'entrée sont les suivantes:
array_1:
- classe: double
- taille: [3,2]
- valeurs: les éléments ne doivent pas être NaN
char_array:
- classe: char
- value: la chaîne ne doit pas être vide
tableau_3
- classe: double
- taille: [5 1]
- valeurs: les éléments doivent être réels
Pour valider les trois entrées, la fonction validateattributes
peut être appelée avec la syntaxe suivante:
validateattributes(A,classes,attributes,funcName,varName,argIndex)
où:
-
A
est le tableau à vider -
classes
: est letype
du tableau (par exemple,single
,double
,logical
) -
attributes
: sont lesattributes
auxquels le tableau en entrée doit correspondre (par exemple,[3,2], size
pour spécifier la taille du tableau,nonnan
pour spécifier que le tableau ne doit pas avoir de valeurs NaN) -
funcName
: est le nom de la fonction dans laquelle la validation a lieu. Cet argument est utilisé dans la génération du message d'erreur (le cas échéant) -
varName
: est le nom du tableau en cours de validation. Cet argument est utilisé dans la génération du message d'erreur (le cas échéant) -
argIndex
: est la position du tableau inpurt dans la liste des entrées. Cet argument est utilisé dans la génération du message d'erreur (le cas échéant)
Si une ou plusieurs entrées ne correspondent pas à la spécification, un message d'erreur est généré.
En cas de plusieurs entrées non valides, la validation s'arrête lorsque la première incompatibilité est trouvée.
C'est la function test_validateattributes
dans laquelle la validation d'entrée a été implémentée.
Étant donné que la fonction nécessite trois entrées, une première vérification du nombre d'entrées fournies est effectuée à l'aide de la fonction nargin .
function test_validateattributes(array_1,char_array_1,array_3)
%
% Check for the number of expected input: if the number of input is less
% than the require, the function exits with an error message
%
if(nargin ~= 3)
error('Error: TEST_VALIDATEATTRIBUTES requires 3 input, found %d',nargin)
end
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the first input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #1 name (only used in the generation of the error message)
%
input_1_name='array_1';
%
% INPUT #1 position (only used in the generation of the error message)
%
input_1_position=1;
%
% Expected CLASS of the first input MUST BE "double"
%
input_1_class={'double'};
%
% Expected ATTRIBUTES of the first input
% SIZE: MUST BE [3,2]
%
input_1_size_attribute='size';
input_1_size=[3,2];
%
% VALUE CHECK: the element MUST BE NOT NaN
%
input_1_value_type='nonnan';
%
% Build the INPUT 1 attributes
%
input_1_attributes={input_1_size_attribute,input_1_size, ...
input_1_value_type};
%
% CHECK THE VALIDITY OF THE FIRST INPUT
%
validateattributes(array_1, ...
input_1_class,input_1_attributes,'', ...
input_1_name,input_1_position);
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the second input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #1 name (only used in the generation of the error message)
%
input_2_name='char_array_1';
%
% INPUT #2 position (only used in the generation of the error message)
%
input_2_position=2;
%
% Expected CLASS of the first input MUST BE "string"
%
input_2_class={'char'};
%
% VALUE CHECK: the element must be not NaN
%
input_2_size_attribute='nonempty';
%
% Build the INPUT 2 attributes
%
input_2_attributes={input_2_size_attribute};
%
% CHECK THE VALIDITY OF THE SECOND INPUT
%
validateattributes(char_array_1, ...
input_2_class,input_2_attributes,'', ...
input_2_name,input_2_position);
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Definition of the expected characteristics of the third input %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% INPUT #3 name (only used in the generation of the error message)
%
input_3_name='array_3';
%
% INPUT #3 position (only used in the generation of the error message)
%
input_3_position=3;
%
% Expected CLASS of the first input MUST BE "double"
%
input_3_class={'double'};
%
% Expected ATTRIBUTES of the first input
% SIZE: must be [5]
input_3_size_attribute='size';
input_3_size=[5 1];
% VALUE CHECK: the elements must be real
input_3_value_type='real';
%
% Build the INPUT 3 attributes
%
input_3_attributes={input_3_size_attribute,input_3_size, ...
input_3_value_type};
%
% CHECK THE VALIDITY OF THE FIRST INPUT
%
validateattributes(array_3, ...
input_3_class,input_3_attributes,'', ...
input_3_name,input_3_position);
disp('All the three input are OK')
Le script suivant peut être utilisé pour tester l'implémentation de la procédure de validation.
Il génère les trois entrées requises et, au hasard, les rend non valides.
%
% Generate the first input
%
n_rows=randi([2 3],1);
n_cols=2;
input_1=randi([20 30],n_rows,n_cols);
%
% Generate the second input
%
if(rand > 0.5)
input_2='This is a string';
else
input_2='';
end
%
% Generate the third input
%
input_3=acos(rand(5,1)*1.2);
%
% Call the test_validateattributes function with the above generated input
%
input_1
input_2
input_3
%
test_validateattributes(input_1,input_2,input_3)
Voici quelques exemples de mauvaises entrées détectées par la fonction validateattributes
:
Mauvaise entrée
input_1 =
23 22
26 28
input_2 =
''
input_3 =
0.0000 + 0.4455i
1.2420 + 0.0000i
0.4063 + 0.0000i
1.3424 + 0.0000i
1.2186 + 0.0000i
Error using test_validateattributes (line 44)
Expected input number 1, array_1, to be of size 3x2 when it is actually
size 2x2.
Mauvaise entrée
input_1 =
22 24
21 25
26 27
input_2 =
This is a string
input_3 =
1.1371 + 0.0000i
0.6528 + 0.0000i
1.0479 + 0.0000i
0.0000 + 0.1435i
0.0316 + 0.0000i
Error using test_validateattributes (line 109)
Expected input number 3, array_3, to be real.
Entrée valide
input_1 =
20 25
25 28
24 23
input_2 =
This is a string
input_3 =
0.9696
1.5279
1.3581
0.5234
0.9665
All the three input are OK
Opérateur de commentaire de bloc
Il est recommandé d'ajouter des commentaires décrivant le code. Il est utile pour les autres et même pour le codeur lorsqu'il est renvoyé plus tard. Une seule ligne peut être commentée en utilisant le symbole %
ou en utilisant le Ctrl+R
clavier Ctrl+R
Pour supprimer le commentaire d'une ligne précédemment commentée, supprimez le symbole %
ou utilisez le raccourci Crtl+T
Bien que le commentaire d'un bloc de code puisse être effectué en ajoutant un symbole %
au début de chaque ligne, les nouvelles versions de MATLAB (après 2015a) vous permettent d'utiliser l' opérateur de commentaire par bloc %{ code %}
. Cet opérateur augmente la lisibilité du code. Il peut être utilisé à la fois pour les commentaires sur le code et pour la documentation d'aide sur les fonctions. Le bloc peut être plié et déplié pour améliorer la lisibilité du code.
Comme on peut le voir, les opérateurs %{
et %}
doivent apparaître seuls sur les lignes. N'incluez aucun autre texte sur ces lignes.
function y = myFunction(x)
%{
myFunction Binary Singleton Expansion Function
y = myFunction(x) applies the element-by-element binary operation
specified by the function handle FUNC to arrays A and B, with implicit
expansion enabled.
%}
%% Compute z(x, y) = x.*sin(y) on a grid:
% x = 1:10;
y = x.';
%{
z = zeros(numel(x),numel(y));
for ii=1:numel(x)
for jj=1:numel(y)
z(ii,jj) = x(ii)*sin(y(jj));
end
end
%}
z = bsxfun(@(x, y) x.*sin(y), x, y);
y = y + z;
end