MATLAB Language
Erreurs communes et erreurs
Recherche…
Ne nommez pas de variable avec un nom de fonction existant
Il existe déjà une fonction sum()
. Par conséquent, si nous nommons une variable du même nom
sum = 1+3;
et si nous essayons d'utiliser la fonction alors que la variable existe toujours dans l'espace de travail
A = rand(2);
sum(A,1)
nous aurons l' erreur cryptique:
Subscript indices must either be real positive integers or logicals.
clear()
abord la variable clear()
puis utiliser la fonction
clear sum
sum(A,1)
ans =
1.0826 1.0279
Comment pouvons-nous vérifier si une fonction existe déjà pour éviter ce conflit?
Utilisez which()
avec le drapeau -all
:
which sum -all
sum is a variable.
built-in (C:\Program Files\MATLAB\R2016a\toolbox\matlab\datafun\@double\sum) % Shadowed double method
...
Cette sortie nous indique que sum
est d'abord une variable et que les méthodes (fonctions) suivantes sont masquées, c'est-à-dire que MATLAB essaiera d'abord d'appliquer notre syntaxe à la variable, plutôt que d'utiliser la méthode.
Ce que vous voyez n'est pas ce que vous obtenez: char vs cellstring dans la fenêtre de commande
Ceci est un exemple de base destiné aux nouveaux utilisateurs. Il ne se concentre pas sur l'explication de la différence entre le char
et les cellstring
.
Il se peut que vous vouliez vous débarrasser du '
dans vos chaînes", bien que vous ne les ayez jamais ajoutées. En fait, ce sont des artefacts que la fenêtre de commande utilise pour distinguer certains types.
Une chaîne imprimera
s = 'dsadasd'
s =
dsadasd
Une chaîne de caractères s'imprimera
c = {'dsadasd'};
c =
'dsadasd'
Notez comment les guillemets simples et l'empreinte sont des artefacts pour nous signaler que c
est un cellstring
plutôt que d' un char
. La chaîne est en fait contenue dans la cellule, c.-à-d.
c{1}
ans =
dsadasd
Les opérateurs de transposition
-
.'
est la manière correcte de transposer un vecteur ou une matrice dans MATLAB. -
'
est la manière correcte de prendre la transposée complexe conjuguée (alias conjugué Hermitien) d'un vecteur ou d'une matrice dans MATLAB.
Notez que pour la transposition .'
, il y a une période devant l'apostrophe. Ceci est conforme à la syntaxe des autres opérations élémentaires dans MATLAB: *
multiplie les matrices,. .*
Multiplie les éléments des matrices ensemble. Les deux commandes sont très similaires, mais conceptuellement très distinctes. Comme les autres commandes MATLAB, ces opérateurs sont des "sucres syntaxiques" qui sont transformés en un appel de fonction "correct" à l'exécution. Tout comme ==
devient une évaluation de la fonction eq , pensez à .'
comme raccourci pour transpose
. Si vous ne vouliez écrire que '
(sans le point), vous utilisez en fait la commande ctranspose
, qui calcule la transposition complexe conjuguée , également connue sous le nom de conjugué hermitien , souvent utilisée en physique. Tant que le vecteur ou la matrice transposés ont une valeur réelle, les deux opérateurs produisent le même résultat. Mais dès que nous traitons des nombres complexes , nous rencontrerons inévitablement des problèmes si nous n'utilisons pas le raccourci "correct". Ce qui est "correct" dépend de votre application.
Prenons l'exemple suivant d'une matrice C
contenant des nombres complexes:
>> C = [1i, 2; 3*1i, 4]
C =
0.0000 + 1.0000i 2.0000 + 0.0000i
0.0000 + 3.0000i 4.0000 + 0.0000i
Prenons la transposition en utilisant la sténographie .'
(avec la période). La sortie est comme prévu, la forme transposée de C
>> C.'
ans =
0.0000 + 1.0000i 0.0000 + 3.0000i
2.0000 + 0.0000i 4.0000 + 0.0000i
Maintenant, utilisons '
(sans le point). Nous voyons que, outre la transposition, les valeurs complexes ont également été transformées en leurs conjugués complexes .
>> C'
ans =
0.0000 - 1.0000i 0.0000 - 3.0000i
2.0000 + 0.0000i 4.0000 + 0.0000i
En résumé, si vous souhaitez calculer le conjugué hermitien, le conjugué complexe transpose, puis utilisez '
(sans le point). Si vous voulez simplement calculer la transposition sans conjuguer les valeurs, utilisez .'
(avec la période).
Fonction ou méthode non définie pour les arguments d'entrée de type Y
Il s’agit de la manière très longue de MATLAB de dire qu’il ne peut pas trouver la fonction que vous essayez d’appeler. Vous pouvez obtenir cette erreur pour plusieurs raisons:
Cette fonction a été introduite après votre version actuelle de MATLAB
La documentation en ligne MATLAB fournit une fonctionnalité très intéressante qui vous permet de déterminer dans quelle version une fonction donnée a été introduite. Il se trouve en bas à gauche de chaque page de la documentation:
Comparez cette version avec votre propre version actuelle ( ver
) pour déterminer si cette fonction est disponible dans votre version particulière. Si ce n'est pas le cas, essayez de rechercher les versions archivées de la documentation pour trouver une alternative appropriée dans votre version.
Vous n'avez pas cette boîte à outils!
L'installation de base MATLAB a un grand nombre de fonctions; Cependant, des fonctionnalités plus spécialisées sont regroupées dans des boîtes à outils et vendues séparément par Mathworks. La documentation de toutes les boîtes à outils est visible, que vous ayez ou non la boîte à outils. Assurez-vous de vérifier si vous avez la boîte à outils appropriée.
Pour vérifier à quelle boîte à outils appartient une fonction donnée, regardez en haut à gauche de la documentation en ligne pour voir si une boîte à outils spécifique est mentionnée.
Vous pouvez ensuite déterminer les boîtes à outils que votre version de MATLAB a installées en émettant la commande ver
qui affichera une liste de toutes les boîtes à outils installées.
Si vous ne disposez pas de cette boîte à outils et que vous souhaitez utiliser cette fonction, vous devrez acheter une licence pour cette boîte à outils particulière dans The Mathworks.
MATLAB ne peut pas localiser la fonction
Si MATLAB ne trouve toujours pas votre fonction, alors il doit s'agir d'une fonction définie par l'utilisateur. Il est possible qu'il réside dans un autre répertoire et que ce répertoire soit ajouté au chemin de recherche de votre code à exécuter. Vous pouvez vérifier si MATLAB peut localiser votre fonction en utilisant which
qui devrait renvoyer le chemin vers le fichier source.
Soyez conscient de l'imprécision en virgule flottante
Les nombres à virgule flottante ne peuvent pas représenter tous les nombres réels. C'est ce qu'on appelle l'imprécision en virgule flottante.
Il y a une infinité de nombres en virgule flottante et ils peuvent être infiniment longs (par exemple, π
), donc pouvoir les représenter parfaitement exigerait une quantité infinie de mémoire. Voyant que c'était un problème, une représentation spéciale pour le stockage "réel" dans l'ordinateur a été conçue, la norme IEEE 754 . En bref, il décrit comment les ordinateurs stockent ce type de nombres, avec un exposant et une mantisse, comme,
floatnum = sign * 2^exponent * mantissa
Avec une quantité limitée de bits pour chacun de ces éléments, seule une précision finie peut être obtenue. Plus le nombre est petit, plus l'écart entre les nombres possibles est faible (et vice versa!). Vous pouvez essayer vos vrais chiffres dans cette démonstration en ligne .
Soyez conscient de ce comportement et essayez d'éviter toute comparaison de points flottants et leur utilisation comme conditions d'arrêt dans les boucles. Voir ci-dessous deux exemples:
Exemples: comparaison de points flottants effectuée WRONG:
>> 0.1 + 0.1 + 0.1 == 0.3
ans =
logical
0
Il est peu pratique d'utiliser la comparaison en virgule flottante, comme le montre l'exemple précédent. Vous pouvez le surmonter en prenant la valeur absolue de leur différence et en la comparant à un niveau de tolérance (faible).
Vous trouverez ci-dessous un autre exemple où un nombre à virgule flottante est utilisé comme condition d'arrêt dans une boucle while: **
k = 0.1;
while k <= 0.3
disp(num2str(k));
k = k + 0.1;
end
% --- Output: ---
0.1
0.2
Il manque la dernière boucle attendue ( 0.3 <= 0.3
).
Exemple: comparaison de virgule flottante effectuée à DROITE:
x = 0.1 + 0.1 + 0.1;
y = 0.3;
tolerance = 1e-10; % A "good enough" tolerance for this case.
if ( abs( x - y ) <= tolerance )
disp('x == y');
else
disp('x ~= y');
end
% --- Output: ---
x == y
Plusieurs choses à noter:
- Comme prévu,
x
ety
sont maintenant traités comme des équivalents. - Dans l'exemple ci-dessus, le choix de la tolérance a été fait arbitrairement. Ainsi, la valeur choisie peut ne pas convenir à tous les cas (en particulier lorsque vous travaillez avec des nombres beaucoup plus faibles). Le choix intelligent de la limite peut être fait en utilisant la fonction
eps
, c'est-à-direN*eps(max(x,y))
, oùN
est un nombre spécifique au problème. Un choix raisonnable pourN
, qui est également assez permissif, est1E2
(même si, dans le problème ci-dessus,N=1
suffirait également).
Lectures complémentaires:
Voir ces questions pour plus d'informations sur l'imprécision en virgule flottante:
- Pourquoi 24.0000 n'est-il pas égal à 24.0000 dans MATLAB?
- Le calcul en virgule flottante est-il cassé?
Pas assez d'arguments en entrée
Souvent, les développeurs MATLAB débutants utiliseront l'éditeur de MATLAB pour écrire et éditer du code, en particulier des fonctions personnalisées avec des entrées et des sorties. Un bouton Exécuter en haut est disponible dans les versions récentes de MATLAB:
Une fois que le développeur a fini avec le code, ils sont souvent tentés d'appuyer sur le bouton Exécuter . Pour certaines fonctions, cela fonctionnera correctement, mais pour d'autres, ils recevront une erreur " Not enough input arguments
et seront perplexes quant à la raison de l'erreur.
La raison pour laquelle cette erreur peut ne pas se produire est que vous avez écrit un script MATLAB ou une fonction qui n'accepte aucun argument d'entrée. L'utilisation du bouton Exécuter permet d'exécuter un script de test ou d'exécuter une fonction en supposant qu'aucun argument d'entrée ne soit utilisé. Si votre fonction nécessite des arguments d'entrée, l'erreur Not enough input arguments
se produira lorsque vous aurez écrit une fonction qui attend que des entrées entrent dans la fonction. Par conséquent, vous ne pouvez pas vous attendre à ce que la fonction s'exécute en appuyant simplement sur le bouton Exécuter .
Pour démontrer ce problème, supposons que nous ayons une fonction mult
qui multiplie simplement deux matrices ensemble:
function C = mult(A, B)
C = A * B;
end
Dans les versions récentes de MATLAB, si vous avez écrit cette fonction et que vous avez appuyé sur le bouton Exécuter , cela vous donnera l'erreur attendue:
>> mult
Not enough input arguments.
Error in mult (line 2)
C = A * B;
Il existe deux manières de résoudre ce problème:
Méthode n ° 1 - via l'invite de commande
Créez simplement les entrées dont vous avez besoin dans l'invite de commandes, puis exécutez la fonction en utilisant les entrées que vous avez créées:
A = rand(5,5);
B = rand(5,5);
C = mult(A,B);
Méthode n ° 2 - Interactif via l'éditeur
Sous le bouton Exécuter , il y a une flèche noire foncée. Si vous cliquez sur cette flèche, vous pouvez spécifier les variables que vous souhaitez obtenir dans l'espace de travail MATLAB en saisissant la manière dont vous souhaitez appeler la fonction exactement comme vous l'avez vu dans la méthode n ° 1. Assurez-vous que les variables que vous spécifiez dans la fonction existent dans l'espace de travail MATLAB:
Attention aux changements de taille de tableau
Certaines opérations courantes dans MATLAB, telles que la différenciation ou l' intégration , produisent des résultats dont la quantité d'éléments est différente de celle des données d'entrée. Ce fait peut facilement être ignoré, ce qui entraînerait généralement des erreurs, comme les Matrix dimensions must agree
. Prenons l'exemple suivant:
t = 0:0.1:10; % Declaring a time vector
y = sin(t); % Declaring a function
dy_dt = diff(y); % calculates dy/dt for y = sin(t)
Disons que nous voulons tracer ces résultats. Nous examinons les tailles de tableau et voyons:
size(y) is 1x101
size(t) is 1x101
Mais:
size(dy_dt) is 1x100
Le tableau est un élément plus court!
Maintenant, imaginez que vous avez des données de mesure de positions dans le temps et que vous voulez calculer jerk (t) , vous obtiendrez un tableau 3 éléments de moins que le tableau de temps (parce que le jerk est la position différenciée 3 fois).
vel = diff(y); % calculates velocity vel=dy/dt for y = sin(t) size(vel)=1x100
acc = diff(vel); % calculates acceleration acc=d(vel)/dt size(acc)=1x99
jerk = diff(acc); % calculates jerk jerk=d(acc)/dt size(jerk)=1x98
Et puis les opérations comme:
x = jerk .* t; % multiplies jerk and t element wise
les erreurs de retour, car les dimensions de la matrice ne sont pas d'accord.
Pour calculer les opérations comme ci-dessus, vous devez ajuster la plus grande taille de tableau pour l'adapter à la plus petite. Vous pouvez également exécuter une régression ( polyfit
) avec vos données pour obtenir un polynôme pour vos données.
Erreurs d'incompatibilité de dimension
Les erreurs d' incompatibilité de dimension apparaissent généralement lorsque:
- Ne pas prêter attention à la forme des variables renvoyées par les appels de fonction / méthode. Dans de nombreuses fonctions MATLAB intégrées, les matrices sont converties en vecteurs pour accélérer les calculs, et la variable renvoyée peut toujours être un vecteur plutôt que la matrice attendue. Ceci est également un scénario courant lorsque le masquage logique est impliqué.
- Utilisation de tailles de tableau incompatibles lors de l'appel d' une extension de tableau implicite .
L'utilisation de "i" ou "j" comme unité imaginaire, index de boucle ou variable commune.
Recommandation
Comme les symboles i
et j
peuvent représenter des choses significativement différentes dans MATLAB, leur utilisation en tant qu'indices de boucle a divisé la communauté d'utilisateurs MATLAB depuis des âges. Bien que certaines raisons de performance historique puissent aider à équilibrer l'équilibre, ce n'est plus le cas et maintenant, le choix repose entièrement sur vous et sur les pratiques de codage que vous choisissez de suivre.
Les recommandations officielles actuelles de Mathworks sont les suivantes:
- Puisque
i
est une fonction, il peut être remplacé et utilisé comme variable. Cependant, il est préférable d'éviter d'utiliseri
etj
pour les noms de variables si vous avez l'intention de les utiliser en arithmétique complexe.- Pour la rapidité et la robustesse améliorée de l'arithmétique complexe, utilisez
1i
et1j
au lieu dei
etj
.
Défaut
Dans MATLAB, par défaut, les lettres i
et j
sont function
noms de function
intégrés, qui font tous deux référence à l'unité imaginaire dans le domaine complexe.
Donc, par défaut, i = j = sqrt(-1)
.
>> i
ans =
0.0000 + 1.0000i
>> j
ans =
0.0000 + 1.0000i
et comme vous devez vous attendre:
>> i^2
ans =
-1
Les utiliser comme une variable (pour les indices de boucle ou autre variable)
MATLAB permet d'utiliser le nom de la fonction intégrée en tant que variable standard. Dans ce cas, le symbole utilisé ne pointera plus vers la fonction intégrée mais vers votre propre variable définie par l'utilisateur. Cependant, cette pratique n'est généralement pas recommandée car elle peut entraîner de la confusion, un débogage difficile et une maintenance ( voir un autre exemple: do-not-name-a-variable-with-an-existing-function-name ).
Si vous êtes très pédant dans le respect des conventions et des meilleures pratiques, vous éviterez de les utiliser comme index de boucle dans ce langage. Cependant, il est autorisé par le compilateur et parfaitement fonctionnel. Vous pouvez donc choisir de conserver les anciennes habitudes et de les utiliser comme itérateurs de boucle.
>> A = nan(2,3);
>> for i=1:2 % perfectly legal loop construction
for j = 1:3
A(i, j) = 10 * i + j;
end
end
Notez que les indices de boucle ne sortent pas de la portée à la fin de la boucle, ils conservent donc leur nouvelle valeur.
>> [ i ; j ]
ans =
2
3
Si vous les utilisez comme variables, assurez-vous qu'elles sont initialisées avant leur utilisation. Dans la boucle ci-dessus, MATLAB les initialise automatiquement lorsqu'il prépare la boucle, mais s'il n'est pas initialisé correctement, vous pouvez rapidement voir que vous pouvez introduire par inadvertance complex
nombres complex
dans votre résultat.
Si plus tard, vous devez annuler l'observation de la fonction intégrée (= par exemple, si vous voulez que i
et j
représentent à nouveau l'unité imaginaire), vous pouvez clear
les variables:
>> clear i j
Vous comprenez maintenant la réservation Mathworks à propos de leur utilisation en tant qu'indices de boucle si vous souhaitez les utiliser en arithmétique complexe . Votre code serait truffé d'initialisations variables et de commandes clear
, le meilleur moyen de confondre le programmeur le plus sérieux ( oui vous êtes là! ... ) et les accidents de programme en attente.
Si aucune arithmétique complexe n'est attendue, l'utilisation de i
et j
est parfaitement fonctionnelle et il n'y a pas de pénalité de performance.
En les utilisant comme unité imaginaire:
Si votre code doit traiter complex
nombres complex
, alors i
et j
seront certainement utiles. Cependant, pour des raisons de désambiguïsation et même pour les performances, il est recommandé d’utiliser la forme complète au lieu de la syntaxe abrégée. La forme complète est 1i
(ou 1j
).
>> [ i ; j ; 1i ; 1j]
ans =
0.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 1.0000i
0.0000 + 1.0000i
Ils représentent la même valeur sqrt(-1)
, mais la dernière forme:
- est plus explicite, de manière sémantique.
- est plus maintenable (quelqu'un qui regarde votre code plus tard n'aura pas à lire le code pour savoir si
i
ouj
était une variable ou l'unité imaginaire). - est plus rapide (source: Mathworks).
Notez que la syntaxe complète 1i
est valide avec tout nombre précédant le symbole:
>> a = 3 + 7.8j
a =
3.0000 + 7.8000i
C'est la seule fonction avec laquelle vous pouvez coller un numéro sans opérateur entre eux.
Pièges
Bien que leur utilisation comme unité imaginaire OU variable soit parfaitement légale, voici juste un petit exemple de la façon dont cela pourrait être déroutant si les deux usages étaient mélangés:
Surpassons i
et en faisons une variable:
>> i=3
i =
3
Maintenant, i
est une variable (contenant la valeur 3
), mais nous ne remplaçons que la notation abrégée de l'unité imaginaire, la forme complète est toujours interprétée correctement:
>> 3i
ans =
0.0000 + 3.0000i
Ce qui nous permet maintenant de construire les formulations les plus obscures. Je vous laisse évaluer la lisibilité de toutes les constructions suivantes:
>> [ i ; 3i ; 3*i ; i+3i ; i+3*i ]
ans =
3.0000 + 0.0000i
0.0000 + 3.0000i
9.0000 + 0.0000i
3.0000 + 3.0000i
12.0000 + 0.0000i
Comme vous pouvez le voir, chaque valeur du tableau ci-dessus renvoie un résultat différent. Bien que chaque résultat soit valide (à condition que ce soit l'intention initiale), la plupart d'entre vous admettront qu'il serait bon de lire un code contenant de telles constructions.
Utiliser `length` pour les tableaux multidimensionnels
Une erreur courante des codeurs MATLAB consiste à utiliser la fonction length
pour les matrices (par opposition aux vecteurs auxquels elle est destinée). La fonction length
, mentionnée dans sa documentation , " renvoie la longueur de la plus grande dimension du tableau " de l'entrée.
Pour les vecteurs, la valeur de retour de length
a deux significations différentes:
- Le nombre total d'éléments dans le vecteur.
- La plus grande dimension du vecteur.
Contrairement aux vecteurs, les valeurs ci-dessus ne seraient pas égales pour les tableaux de plus d'une dimension non-singleton (c'est-à-dire dont la taille est supérieure à 1
). C'est pourquoi l'utilisation de la length
pour les matrices est ambiguë. Au lieu de cela, l'utilisation de l'une des fonctions suivantes est encouragée, même lorsque vous travaillez avec des vecteurs, pour que l'intention du code soit parfaitement claire:
-
size(A)
- renvoie un vecteur de ligne dont les éléments contiennent la quantité d'éléments le long de la dimension correspondante deA
-
numel(A)
- renvoie le nombre d'éléments dansA
Équivalent àprod(size(A))
. -
ndims(A)
- renvoie le nombre de dimensions du tableauA
Équivalent ànumel(size(A))
.
Ceci est particulièrement important lors de l'écriture de fonctions de bibliothèque vectorisées "à l'épreuve du futur", dont les entrées ne sont pas connues à l'avance et peuvent avoir différentes tailles et formes.