Utilisation de i et j comme variables dans Matlab

142

iet jsont des noms de variables très populaires (voir par exemple cette question et celle-ci ).

Par exemple, en boucles:

for i=1:10,
    % do something...
end

En tant qu'indices dans la matrice:

mat( i, j ) = 4;

Pourquoi ne devraient- ils pas être utilisés comme noms de variables dans Matlab?

Shai
la source
5
Bien sûr, je ne le signalerai pas comme tel, mais à en juger par les réponses, je dirais que c'est "principalement basé sur l'opinion". ;-) Je ne donnerais pas personnellement sur i, j, kcomme les noms de variables génériques en boucle.
A. Donda
1
@ A.Donda eh bien, c'est votre opinion;)
Shai
@Shai, c'est votre dernière phrase dans cette question: "Pourquoi ne devraient-ils pas être utilisés comme noms de variables dans Matlab?" Il est donc très difficile de savoir pourquoi vous rejetez mon édition sur votre question?! J'ai changé votre titre en un titre plus constructif "Pourquoi ne pas utiliser i et j comme variables dans Matlab"
Seyfi

Réponses:

176

Parce que iet jsont les deux fonctions désignant l' unité imaginaire :

Ainsi, une variable appelée iou jles remplacera, cassant potentiellement silencieusement du code qui effectue des calculs complexes.

Les solutions possibles incluent l'utilisation de iiet jjcomme variables de boucle à la place, ou l'utilisation de 1ichaque fois que cela iest nécessaire pour représenter l'unité imaginaire.

Oliver Charlesworth
la source
42
Il est également intéressant de noter que même si vous ne cassez rien, le temps d'exécution est toujours sacrifié pour résoudre les noms de variables iet j.
Eitan T
14
@Eitan: Pouvez-vous réellement confirmer cela de manière concrète et concluante dans une version compilée JIT de Matlab? Je n'ai jamais trouvé que c'était le cas (et de simples tests appelant une forboucle 1 milliard de fois ne montrent aucune différence statistique de timing). Pour tout ce que nous savons, il existe un code spécial pour gérer exactement cela et l'utilisation de variables autres que iet j(et k?) Est en fait légèrement plus lente. Et les différences qui existent sont minuscules voire inexistantes dans la vie réelle. Il n'y a tout simplement aucune raison de NE PAS utiliser iet en jtant que variables régulières, elles doivent simplement être utilisées correctement comme toute autre fonction Matlab.
horchler
5
@horchler Eh bien, la documentation officielle indique ici que le remplacement des classes de données MATLAB standard "peut affecter négativement les performances", et ici il est sous-entendu d'éviter de surcharger des constantes complexes pour des raisons de vitesse, ainsi que de robustesse. Dans les anciens documents de R2009b, il est explicitement recommandé de ne pas surcharger les constantes complexes, car cela peut gêner l'accélération JIT. La résolution de nom de variable est peut-être minuscule, mais elle peut être importante si elle est répétée des millions de fois.
Eitan T du
14
Dans les anciennes versions de Matlab peut-être. J'avais l'habitude de voir ça moi-même. Mais plus avec R2012a + (OS X) du moins. Et je n'ai vu aucune différence en appelant une forboucle 1 milliard de fois et en essayant toutes sortes de schémas de synchronisation. Je vois de nouveaux utilisateurs SO se faire dire qu'un code parfaitement valide est faux parce qu'ils utilisent iet jpour itérer des boucles. Franchement, c'est juste idiot et les gens manquent le point le plus important de cette question: cela iet jne devrait même pas être utilisé pour l'unité imaginaire si l'on veut écrire du code Matlab moderne lisible.
horchler
12
mon gain de temps majeur est lors de la recherche de ii. Recherche de je peux être une vraie douleur
craq
62

Il est recommandé d'éviter les variables iet jd'éviter toute confusion sur le fait qu'elles soient des variables ou l'unité imaginaire.

Personnellement, cependant, j'utilise iet jcomme variables assez souvent comme index des boucles courtes. Pour éviter les problèmes dans mon propre code, je suis une autre bonne pratique concernant iet j: ne les utilisez pas pour désigner des nombres imaginaires. En fait, la propre documentation de Matlab déclare :

Pour une rapidité et une robustesse améliorées, vous pouvez remplacer les complexes iet jpar 1i.

Donc, plutôt que d'éviter deux noms de variables très couramment utilisés en raison d'un conflit potentiel, je suis explicite sur les nombres imaginaires. Cela rend également mon code plus clair. Chaque fois que je vois 1i, je sais que cela représente sqrt(-1)parce qu'il ne pourrait pas être une variable.

shoelzer
la source
2
C'est en effet une bonne pratique à utiliser 1i. Cependant, changer la signification de iet jpeut entraîner des erreurs difficiles à déboguer comme celle-ci .
Shai
1
@Shai Bon point. J'ai peaufiné ma réponse pour reconnaître qu'éviter iet jc'est mieux, mais j'ai expliqué comment mon style de codage personnel ne suit pas cette règle.
shoelzer le
2
A noter que la vitesse évoquée ne semble pas très significative: stackoverflow.com/questions/18163454/...
Dennis Jaheruddin
Entièrement d'accord! La bonne pratique est de TOUJOURS utiliser 1iet non ipour des mathématiques complexes. Pensons au nombre imaginaire comme 1iet prenons icomme nombre imaginaire une mauvaise pratique. Pas l'inverse. L' utilisation i, ii, iiiest une pratique courante dans Matlab et il n'y a pas de problème quand les gens tiennent à 1iet 1jpour nombre complexe. Matlab respecte également cela et celui-ci ne diminue pas les performances (dans la mesure où j'ai testé) comme indiqué dans la réponse précédente.
SdidS
i et j ne devraient pas être utilisés de toute façon - ces nombres signifient quelque chose - utilisez un nom qui décrit le but (row_n, elementNo, listItemIndex, etc.). Tellement plus facile pour quelqu'un de comprendre ce que vous faites, de déboguer, etc. Le temps supplémentaire passé vaut plus que le gain en maintenabilité à long terme pour autre chose qu'un script jetable - même avec l'éditeur Matlab étant bien en retard la plupart des autres IDE modernes.
LightCC
27

Dans les anciennes versions de MATLAB, il y avait une bonne raison d'éviter l'utilisation de iet jcomme noms de variables - les premières versions de MATLAB JIT n'étaient pas assez intelligentes pour dire si vous les utilisiez comme variables ou comme unités imaginaires, et désactiver de nombreuses optimisations autrement possibles.

Votre code deviendrait donc plus lent simplement par la présence même de iet en jtant que variables, et accélérerait si vous les changiez en autre chose. C'est pourquoi, si vous lisez beaucoup de code MathWorks, vous verrez iiet vous l' jjutiliserez assez largement comme indices de boucle. Pendant un certain temps, MathWorks pourrait même avoir officieusement conseillé aux gens de le faire eux-mêmes (bien qu'ils conseillent toujours officiellement aux gens de programmer pour l'élégance / la maintenabilité plutôt que pour tout ce que fait le JIT actuel, car c'est une cible mobile à chaque version).

Mais c'était il y a assez longtemps, et de nos jours c'est un peu un problème de «zombie» qui est vraiment beaucoup moins important que beaucoup de gens ne le pensent encore, mais qui refuse de mourir.

Dans n'importe quelle version récente, c'est vraiment une préférence personnelle d'utiliser iet jcomme noms de variables ou non. Si vous travaillez beaucoup avec des nombres complexes, vous voudrez peut-être éviter iet en jtant que variables, pour éviter tout petit risque potentiel de confusion (bien que vous puissiez également / plutôt vouloir utiliser uniquement 1iou 1jpour encore moins de confusion, et un peu mieux les performances ).

D'un autre côté, dans mon travail typique, je ne m'occupe jamais de nombres complexes, et je trouve mon code plus lisible si je me sens libre d'utiliser iet jcomme index de boucle.


Je vois beaucoup de réponses ici qui disent que ce n'est pas recommandé ... sans dire qui fait cela en recommandant. Voici l'étendue des recommandations réelles de MathWorks, tirées de la documentation de la version actuelle pour i:

Puisque i est une fonction, elle peut être remplacée et utilisée comme variable. Cependant, il est préférable d'éviter d'utiliser i et j pour les noms de variables si vous avez l'intention de les utiliser en arithmétique complexe. [...] Pour plus de rapidité et une meilleure robustesse, vous pouvez remplacer les complexes i et j par 1i.

Sam Roberts
la source
15

Comme décrit dans d'autres réponses, l'utilisation du icode en général n'est pas recommandée pour deux raisons:

  • Si vous souhaitez utiliser le nombre imaginaire, il peut être confondu ou écrasé par un index
  • Si vous l'utilisez comme index, il peut être superposé ou confondu avec le nombre imaginaire

Comme suggéré: 1iet iisont recommandés. Cependant, bien qu'il s'agisse de très bons écarts par rapport à i, il n'est pas très agréable d'utiliser ces deux alternatives ensemble.

Voici un exemple pourquoi (personnellement) je ne l'aime pas:

val2 = val + i  % 1
val2 = val + ii % 2
val2 = val + 1i % 3

Un ne sera pas facilement mal lu pendant deux ou trois, mais deux et trois se ressemblent.

Par conséquent, ma recommandation personnelle serait: au cas où vous travaillez parfois avec du code complexe, utilisez toujours 1icombiné avec une variable de boucle différente.

Exemples d'indices à une lettre que pour si vous n'utilisez pas beaucoup de variables de boucle et lettres suffisent: t, u, ketp

Exemple d'indices plus: i_loop, step, walkett_now

Bien sûr, c'est aussi une question de goût personnel, mais il ne devrait pas être difficile de trouver des indices à utiliser qui ont une signification claire sans devenir trop longs.

Dennis Jaheruddin
la source
1
1i désigne l'unité imaginaire (les noms des variables Matlab ne peuvent pas non plus commencer par un nombre)
lib
2
@DennisJaheruddin: plug sans vergogne: utilisez ma syntaxe MATLAB pour mettre en évidence le script utilisateur pour Stack Overflow. Dans le dernier exemple, 1isera coloré différemment sous forme de nombre :)
Amro
2
Directement à partir de doc iet doc j: "Pour plus de rapidité et une meilleure robustesse, vous pouvez remplacer les complexes i et j par 1i." IMO, dans Matlab actuel, il n'y a aucune raison de ne pas utiliser iet jen boucles, etc., ou d'utiliser autre chose que 1ipour désigner l'unité imaginaire ( 1jfonctionne aussi). La seule exception concerne le passage de chaînes au moteur Symbolic toujours légèrement incompatible. Cela est étrange help 1iet doc 1ine fonctionne pas.
horchler
11

Il a été souligné que 1ic'est une manière d'écrire acceptable et sans ambiguïté sqrt(-1)et qu'en tant que telle, il n'est pas nécessaire d'éviter d'utiliser i. Là encore, comme Dennis l'a souligné ( https://stackoverflow.com/a/14893729/1967396 ), il peut être difficile de voir la différence entre 1iet ii. Ma suggestion: utiliser 1jcomme constante imaginaire si possible. Il est le même tour que les ingénieurs électriciens emploient - ils utilisent jpour sqrt(-1)cause iest déjà pris pour courant .

Personnellement, je n'utilise jamais iet j; J'utilise iiet jjcomme variables d'indexation abrégées, (et kk, ll, mm, ...) et 1jlorsque j'ai besoin d'utiliser des nombres complexes.

Floris
la source
2
"il peut être difficile de voir la différence entre 1iet ii" Et encore plus la différence entre 1et let entre Oet 0. C'est pourquoi la première étape que je fais dans une nouvelle installation de MATALB est de changer la taille de police par défaut.
glglgl
6

La confusion avec l'unité imaginaire a été bien couverte ici, mais il y a d'autres raisons plus prosaïques pour lesquelles ces noms de variables à une seule lettre sont parfois découragés.

  1. MATLAB spécifiquement: si vous utilisez un codeur pour générer une source C ++ à partir de votre code MATLAB (ne le faites pas, c'est horrible), vous êtes explicitement averti de ne pas réutiliser les variables en raison de conflits de frappe potentiels.

  2. En général, et en fonction de votre IDE, un nom de variable à une seule lettre peut causer des ravages avec les surligneurs et la recherche / remplacement. MATLAB n'en souffre pas et je pense que Visual Studio n'a pas eu de problème depuis un certain temps, mais les normes de codage C / C ++ comme MISRA etc. ont tendance à les déconseiller.

Pour ma part, j'évite toutes les variables à une seule lettre, malgré les avantages évidents à implémenter directement des sources mathématiques. Cela demande un peu d'effort supplémentaire les premières centaines de fois que vous le faites, mais après cela, vous arrêtez de le remarquer, et les avantages lorsque vous ou une autre pauvre âme venez lire votre code sont légion.

xénoclaste
la source
4

Tout code non trivial contient plusieurs forboucles, et les meilleures pratiques vous recommandent d'utiliser un nom descriptif indiquant son objectif et sa portée. Pour des temps immémoriaux (et à moins que son script 5-10 lignes que je ne vais pas sauver), je l' ai toujours été en utilisant des noms de variables comme idxTask, idxAnotherTasket idxSubTasketc.

Ou au moins doubler la première lettre du tableau qu'il indexe, par exemple sspour indexer subjectList, ttindexer taskList, mais pas iiou jjqui ne m'aide pas à identifier sans effort le tableau qu'ils indexent parmi mes multiples boucles for.

Pradeep Reddy Raamana
la source
3

Par défaut iet jreprésente l'unité imaginaire. Donc, du point de vue de MATLAB, utiliser icomme variable équivaut en quelque sorte à utiliser 1comme variable.

yo '
la source
5
je ne pense pas que ce soit tout à fait comme ça. i est un nom de variable légitime, vous pouvez donc utiliser i et j comme noms de variable. il masquera, comme le mentionne une réponse précédente, le sens imaginaire. 1 n'est pas un nom de variable légitime. c'est très bien si vous n'utilisez jamais de nombres complexes.
thang
@thang c'est pourquoi j'ai dit "en quelque sorte comme" et non "comme". Je sais qu'il y a une différence. OP a demandé pourquoi ils ne devraient pas être utilisés, j'ai essayé d'expliquer que c'est parce qu'ils expriment déjà un nombre.
le
2
ok, désolé, je ne sais pas ce que signifie en quelque sorte . pour moi c'est clairement différent car bon, vous ne pouvez pas utiliser 1 comme variable même si vous le vouliez ... mais je vois d'où vous venez.
thang
vous pouvez les utiliser, car vous pouvez également utiliser des noms de fonction existants pour les variables (et en même temps corrompre ces fonctions / constantes intégrées pour une utilisation ultérieure). Que vous vouliez vraiment cela, c'est autre chose (réponse simple imo: non)
Gunther Struyf
1
Désolé, mais cette explication n'a aucun sens. Les fonctions iet jsont en fait des fonctions retournant la valeur de l'unité imaginaire. Il est possible d'utiliser une variable avec le même nom qu'une fonction dans une portée. Cela masquera cependant la fonction.
patrik
2

Sauf si vous êtes un utilisateur très confus, je pense qu'il y a très peu de risque à utiliser les noms de variables i et j et je les utilise régulièrement. Je n'ai vu aucune indication officielle selon laquelle cette pratique devrait être évitée.

S'il est vrai que l'observation de l'unité imaginaire pourrait causer une certaine confusion dans certains contextes, comme mentionné dans d'autres articles, dans l'ensemble, je ne le vois tout simplement pas comme un problème majeur. Il y a des choses beaucoup plus déroutantes que vous pouvez faire dans MATLAB, prenez par exemple la définitionfalse=true

À mon avis, le seul moment où vous devriez probablement les éviter est si votre code traite spécifiquement des nombres imaginaires.

Gregswiss
la source
Pouvez-vous s'il vous plaît commenter lors du vote à la baisse. Par exemple avec un lien Mathworks indiquant que la pratique n'est pas recommandée (ce qui a été indiqué par plusieurs affiches sans faire référence à aucune directive officielle). En fait, l'utilisation de «i» dans les boucles est utilisée dans les exemples officiels par Mathworks. D'après mon expérience, cela rend le code clair et concis et c'est une pratique très courante.
gregswiss
1
Citant la documentation "Comme iest une fonction, elle peut être remplacée et utilisée comme variable. Cependant, il est préférable d'éviter d'utiliser iet jpour les noms de variables si vous avez l'intention de les utiliser en arithmétique complexe." Cela, en conjonction avec le commentaire d'Eitan T sur la réponse d'Oliver (je suppose qu'il a chronométré) semble une preuve suffisante.
Adriaan
1
Notez également qu'il y a déjà une réponse de 2013 avec le commentaire mentionné par @Adriaan.
Andras Deak
1
donc la documentation indique SI vous avez l'intention d'utiliser en arithmétique complexe, sinon cela ne s'applique pas - je ne sais pas pourquoi tout le monde est si difficile à ce sujet ici! J'offrais juste un autre point de vue.
gregswiss