Verwenden von i und j als Variablen in Matlab

142

iund jsind sehr beliebte Variablennamen (siehe z. B. diese und diese Frage ).

Zum Beispiel in Schleifen:

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

Als Indizes in die Matrix:

mat( i, j ) = 4;

Warum sollten sie in Matlab nicht als Variablennamen verwendet werden?

Shai
quelle
5
Natürlich werde ich es nicht als solches kennzeichnen, aber nach den Antworten zu urteilen, würde ich sagen, dass dies "hauptsächlich meinungsbasiert" ist. ;-) Ich persönlich würde nicht aufgeben i, j, kwie die generischen Schleife Variablennamen.
A. Donda
1
@ A.Donda gut, das ist deine Meinung;)
Shai
@Shai, dies ist Ihr letzter Satz in dieser Frage: "Warum sollten sie in Matlab nicht als Variablennamen verwendet werden?" Es ist also sehr unklar, warum Sie meine Ausgabe zu Ihrer Frage ablehnen?! Ich habe Ihren Titel in einen konstruktiveren Titel geändert "Warum sollten i und j NICHT als Variablen in Matlab verwendet werden"
Seyfi

Antworten:

176

Weil iund jbeide Funktionen die imaginäre Einheit bezeichnen :

Eine Variable, die aufgerufen wird ioder jdiese überschreibt, bricht möglicherweise stillschweigend Code, der komplexe Berechnungen ausführt.

Mögliche Lösungen umfassen die Verwendung von iiund jjals Schleifenvariablen oder die Verwendung, 1iwann iimmer dies zur Darstellung der imaginären Einheit erforderlich ist.

Oliver Charlesworth
quelle
42
Es ist auch erwähnenswert, dass die Ausführungszeit auch dann geopfert wird, wenn Sie nichts kaputt machen, um die Namen iund jVariablen aufzulösen .
Eitan T
14
@Eitan: Können Sie das in einer JIT-kompilierten Version von Matlab tatsächlich konkret und schlüssig belegen? Ich habe nie festgestellt, dass dies der Fall ist (und einfache Tests, die eine forSchleife 1 Milliarde Mal aufrufen, zeigen keinen statistischen Unterschied im Timing). Nach allem, was wir wissen, gibt es speziellen Code, um genau dies zu handhaben, und die Verwendung anderer Variablen als iund j(und k?) Ist tatsächlich etwas langsamer. Und Unterschiede, die existieren, sind im wirklichen Leben winzig bis nicht existent. Es gibt einfach keinen Grund, NICHT zu verwenden, iund jals reguläre Variablen müssen sie wie jede andere Matlab-Funktion ordnungsgemäß verwendet werden.
Horchler
5
@horchler Nun, in den offiziellen Dokumenten heißt es hier, dass das Überschreiben von Standard-MATLAB-Datenklassen "die Leistung negativ beeinflussen kann", und hier wird impliziert, dass das Überschreiben komplexer Konstanten aus Gründen der Geschwindigkeit sowie der Robustheit vermieden wird. In älteren Dokumenten von R2009b wird ausdrücklich empfohlen, komplexe Konstanten nicht zu überschreiben, da dies die JIT-Beschleunigung behindern kann. Die Auflösung variabler Namen ist vielleicht winzig, kann aber von Bedeutung sein, wenn sie millionenfach wiederholt wird.
Eitan T
14
In alten Versionen von Matlab vielleicht. Das habe ich selbst gesehen. Aber zumindest nicht mehr mit R2012a + (OS X). Und ich sah keinen Unterschied, als ich eine forSchleife 1 Milliarde Mal aufrief und alle möglichen Zeitschemata ausprobierte. Ich sehe, wie neuen SO-Benutzern gesagt wird, dass perfekt gültiger Code falsch ist, weil sie Schleifen verwenden iund jiterieren. Ehrlich gesagt ist es einfach albern und den Leuten fehlt der wichtigere Punkt dieser Frage: das iund jsollte nicht einmal für die imaginäre Einheit verwendet werden, wenn man lesbaren modernen Matlab-Code schreiben möchte.
Horchler
12
Meine größte Zeitersparnis ist bei der Suche nach ii. Auf der Suche nach kann ich ein echtes
Problem sein
62

Es ist eine gute Praxis, dies zu vermeiden i und jVariablen zu verhindern Verwirrung über sie Variablen oder die imaginäre Einheit ist.

Persönlich verwende ich jedoch iund jals Variablen ziemlich oft als Index für kurze Schleifen. Um Probleme in meinem eigenen Code zu vermeiden, folge ich eine weitere gute Praxis in Bezug auf iund j: nicht verwende sie imaginäre Zahlen zu bezeichnen. In der Tat heißt es in Matlabs eigener Dokumentation :

Für Geschwindigkeit und verbesserte Robustheit können Sie komplexe iund jdurch ersetzen1i .

Anstatt zwei sehr häufig verwendete Variablennamen aufgrund eines möglichen Konflikts zu vermeiden, gehe ich explizit auf imaginäre Zahlen ein. Es macht auch meinen Code klarer. Immer 1iwenn ich sehe , weiß ich, dass es darstellt, sqrt(-1)weil es unmöglich eine Variable sein könnte.

Schuhmacher
quelle
2
Es ist in der Tat eine gute Praxis zu verwenden 1i. Das Ändern der Bedeutung von iund jkann jedoch zu schwer zu debuggenden Fehlern wie diesem führen .
Shai
1
@Shai Guter Punkt. Ich habe meine Antwort optimiert, um anzuerkennen, dass das Vermeiden iund jam besten ist, aber erklärt, dass mein persönlicher Codierungsstil dieser Regel nicht folgt.
Shoelzer
2
Beachten Sie, dass die erwähnte Geschwindigkeit nicht sehr signifikant zu sein scheint: stackoverflow.com/questions/18163454/…
Dennis Jaheruddin
Stimme voll und ganz zu! Die gute Praxis ist, IMMER zu verwenden 1iund nicht ifür komplexe Mathematik. Stellen wir uns eine imaginäre Zahl als eine schlechte Praxis vor 1iund nehmen sie ials imaginäre Zahl. Nicht umgekehrt. Mit i, ii, iiiist gängige Praxis in Matlab und es gibt kein Problem , wenn die Leute zu halten 1iund 1jfür komplexe Zahl. Auch Matlab respektiert dies und dieses verringert nicht die Leistung (soweit ich getestet habe), wie in der vorherigen Antwort angegeben.
SdidS
i und j sollten sowieso nicht verwendet werden - diese Zahlen bedeuten etwas - verwenden Sie einen Namen, der den Zweck beschreibt (row_n, elementNo, listItemIndex usw.). So viel einfacher für jemanden zu verstehen, was Sie tun, zu debuggen usw. Die zusätzliche Zeit ist mehr als den Gewinn an langfristiger Wartbarkeit für mehr als ein Wegwerf-Skript wert - selbst wenn der Matlab-Editor weit hinterherhinkt die meisten anderen modernen IDEs.
LightCC
27

In alten Versionen von MATLAB gab es früher einen guten Grund, die Verwendung von iund zu vermeidenj als Variablennamen Frühere Versionen von MATLAB JIT waren nicht klug genug, um festzustellen, ob Sie sie als Variablen oder als imaginäre Einheiten verwendeten, und würden dies daher tun Deaktivieren Sie viele ansonsten mögliche Optimierungen.

Ihr Code würde daher nur durch das Vorhandensein von iund jals Variablen langsamer werden und sich beschleunigen, wenn Sie sie in etwas anderes ändern. Wenn Sie viel MathWorks-Code lesen, werden Sie ihn daher ziemlich häufig als Schleifenindizes sehen iiund jjverwenden. Für eine Weile hat MathWorks den Leuten möglicherweise sogar inoffiziell geraten, dies selbst zu tun (obwohl sie den Leuten offiziell immer raten, auf Eleganz / Wartbarkeit zu programmieren, anstatt auf das, was die aktuelle JIT tut, da es sich bei jeder Version um ein bewegliches Ziel handelt).

Aber das ist schon lange her und heutzutage ist es ein bisschen ein "Zombie" -Problem, das wirklich viel weniger wichtig ist, als viele Leute immer noch denken, aber sich weigert zu sterben.

In jeder neueren Version ist es wirklich eine persönliche Präferenz, ob iund jals Variablennamen verwendet werden sollen oder nicht. Wenn Sie viel mit komplexen Zahlen arbeiten, möchten Sie möglicherweise iund jals Variablen vermeiden, um ein geringes potenzielles Verwechslungsrisiko zu vermeiden (obwohl Sie möglicherweise auch / stattdessen nur 1ioder 1jfür noch weniger Verwirrung und eine etwas bessere Leistung verwenden möchten ).

Auf der anderen Seite, in meiner typischen Arbeit mit komplexen Zahlen , die ich nie beschäftigen und ich meinen Code besser lesbar , wenn ich frei fühlen zu bedienen iund jals Loop - Indizes.


Ich sehe hier viele Antworten, die besagen, dass es nicht empfohlen wird ... ohne zu sagen, wer diese Empfehlung tut. Hier ist der Umfang der tatsächlichen Empfehlungen von MathWorks aus der aktuellen Release-Dokumentation für i:

Da i eine Funktion ist, kann sie überschrieben und als Variable verwendet werden. Es ist jedoch am besten, i und j für Variablennamen nicht zu verwenden, wenn Sie sie in komplexer Arithmetik verwenden möchten. [...] Für Geschwindigkeit und verbesserte Robustheit können Sie die Komplexe i und j durch 1i ersetzen.

Sam Roberts
quelle
15

Wie in anderen Antworten beschrieben, wird die Verwendung von iallgemeinem Code aus zwei Gründen nicht empfohlen:

  • Wenn Sie die imaginäre Zahl verwenden möchten, kann sie mit einem Index verwechselt oder von diesem überschrieben werden
  • Wenn Sie es als Index verwenden, kann es überschrieben oder mit der imaginären Zahl verwechselt werden

Wie vorgeschlagen: 1iund iiwerden empfohlen. Obwohl dies beide feine Abweichungen sind i, ist es nicht sehr schön, beide Alternativen zusammen zu verwenden.

Hier ist ein Beispiel, warum es mir (persönlich) nicht gefällt:

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

Man wird nicht leicht für zwei oder drei falsch verstanden, aber zwei und drei ähneln sich.

Daher wäre meine persönliche Empfehlung: Wenn Sie manchmal mit komplexem Code arbeiten, verwenden Sie immer eine 1iKombination mit einer anderen Schleifenvariablen.

Beispiele für einzelne Buchstaben - Indizes , dass für , wenn Sie nicht viele Schleifenvariablen und Buchstaben genügen verwenden Sie: t, u, kundp

Beispiel für mehr Indizes: i_loop, step, walk, undt_now

Natürlich ist dies auch eine Frage des persönlichen Geschmacks, aber es sollte nicht schwer sein, Indizes zu finden, die eine klare Bedeutung haben, ohne zu lang zu werden.

Dennis Jaheruddin
quelle
1
1i bezeichnet die imaginäre Einheit (auch Matlab-Variablennamen können nicht mit einer Zahl beginnen)
lib
2
@ TennisJaheruddin: Schamloser Plug: Verwenden Sie meine MATLAB-Syntax, um das Userscript für Stack Overflow hervorzuheben . Im letzten Beispiel 1iwird als Zahl anders gefärbt :)
Amro
2
Direkt von doc iund doc j: "Für Geschwindigkeit und verbesserte Robustheit können Sie die komplexen i und j durch 1i ersetzen." IMO, im aktuellen Matlab gibt es keinen Grund, nicht iund jin Schleifen usw. zu verwenden oder etwas anderes zu verwenden, als 1idie imaginäre Einheit zu bezeichnen ( 1jfunktioniert auch). Die einzige Ausnahme ist die Übergabe von Zeichenfolgen an die immer leicht inkompatible Symbolic-Engine. Seltsam , dass help 1iund doc 1inicht Arbeit though.
Horchler
11

Es wurde darauf hingewiesen, dass dies 1ieine akzeptable und eindeutige Schreibweise sqrt(-1)ist und dass es als solche nicht notwendig ist, die Verwendung zu vermeiden i. Andererseits kann es, wie Dennis betonte ( https://stackoverflow.com/a/14893729/1967396 ), schwierig sein, den Unterschied zwischen 1iund zu erkennen ii. Mein Vorschlag: Verwenden Sie 1jnach Möglichkeit als imaginäre Konstante. Es ist der gleiche Trick , dass Elektroingenieure beschäftigen - sie verwenden jfür , sqrt(-1)weil ibereits für genommen Strom .

Persönlich benutze ich nie iund j; Ich verwende iiund jjals Kurzindexierungsvariablen (und kk, ll, mm, ...) und 1jwenn ich komplexe Zahlen verwenden muss.

Floris
quelle
2
"Es kann schwierig sein, den Unterschied zwischen 1iund zu erkennen. ii" Und noch mehr den Unterschied zwischen 1und lund zwischen Ound 0. Deshalb ist der erste Schritt, den ich in einer neuen MATALB-Installation mache, das Ändern der Standardschriftgröße.
glglgl
6

Die Verwechslung mit der imaginären Einheit wurde hier gut behandelt, aber es gibt einige andere prosaischere Gründe, warum diese und andere Ein-Buchstaben-Variablennamen manchmal nicht empfohlen werden.

  1. MATLAB speziell: Wenn Sie einen Codierer verwenden, um eine C ++ - Quelle aus Ihrem MATLAB-Code zu generieren (nicht, es ist schrecklich), werden Sie ausdrücklich gewarnt, Variablen wegen möglicher Tippkonflikte nicht wiederzuverwenden.

  2. Im Allgemeinen und abhängig von Ihrer IDE kann ein aus einem Buchstaben bestehender Variablenname Chaos mit Textmarkern und Suchen / Ersetzen verursachen. MATLAB leidet nicht darunter und ich glaube, dass Visual Studio seit einiger Zeit kein Problem mehr hat, aber die C / C ++ - Codierungsstandards wie MISRA usw. raten dazu.

Ich für meinen Teil vermeide alle Einbuchstabenvariablen, trotz der offensichtlichen Vorteile für die direkte Implementierung mathematischer Quellen. Es erfordert ein wenig zusätzliche Anstrengung, wenn Sie es die ersten paar hundert Male tun, aber danach hören Sie auf, es zu bemerken, und die Vorteile, wenn Sie oder eine andere arme Seele kommen, um Ihren Code zu lesen, sind Legion.

Xenoklast
quelle
4

Jeder nicht triviale Code enthält mehrere forSchleifen. In den Best Practices wird empfohlen, einen beschreibenden Namen zu verwenden, der den Zweck und den Umfang angibt. Für undenkliche Zeiten (und es sei denn , seine 5-10 Zeilen Skript , dass ich nicht gehen zu retten bin), habe ich immer wie Variablennamen benutzen idxTask, idxAnotherTaskund idxSubTaskusw.

Oder zumindest den ersten Buchstaben des Arrays zu verdoppeln, das indiziert wird, z. B. um sszu indizieren subjectList, um ttzu indizieren taskList, aber nicht iioder jjwas mir nicht hilft, mühelos zu identifizieren, welches Array sie aus meinen multiplen for-Schleifen indizieren.

Pradeep Reddy Raamana
quelle
3

Standardmäßig iund jstehen für die imaginäre Einheit. Aus Sicht von MATLAB ist die Verwendung ials Variable also irgendwie wie die Verwendung 1als Variable.

yo '
quelle
5
Ich denke nicht, dass es so ist. i ist ein legitimer Variablenname, daher können Sie i und j tatsächlich als Variablennamen verwenden. es wird, wie in einer früheren Antwort erwähnt, die imaginäre Bedeutung maskieren. 1 ist kein legitimer Variablenname. Es ist völlig in Ordnung, wenn Sie niemals komplexe Zahlen verwenden.
Thang
@thang deshalb habe ich "irgendwie wie" und nicht "wie" gesagt. Ich weiß, dass es einen Unterschied gibt. OP fragte, warum sie nicht verwendet werden sollten, ich versuchte zu erklären, dass es daran liegt, dass sie bereits eine Nummer ausdrücken.
Yo '
2
ok, sorry, ich weiß nicht was irgendwie bedeutet. Für mich ist das eindeutig anders, denn Sie können 1 nicht als Variable verwenden, selbst wenn Sie wollten ... aber ich sehe, woher Sie kommen.
Thang
Sie können sie verwenden, da Sie auch vorhandene Funktionsnamen für Variablen verwenden können (und gleichzeitig diese integrierten Funktionen / Konstanten für die weitere Verwendung beschädigen können). Ob Sie das wirklich wollen, ist eine andere Sache (imo einfache Antwort: nein)
Gunther Struyf
1
Entschuldigung, aber diese Erklärung macht keinen Sinn. Die iund jsind tatsächlich Funktionen, die den Wert der imaginären Einheit zurückgeben. Es ist möglich, eine Variable mit demselben Namen als Funktion in einem Bereich zu verwenden. Dies wird jedoch die Funktion beschatten.
Patrik
2

Wenn Sie kein sehr verwirrter Benutzer sind, besteht meines Erachtens nur ein sehr geringes Risiko bei der Verwendung der Variablennamen i und j, und ich verwende sie regelmäßig. Ich habe keinen offiziellen Hinweis darauf gesehen, dass diese Praxis vermieden werden sollte.

Zwar kann das Abschatten der imaginären Einheit in einem bestimmten Kontext zu Verwirrung führen, wie in anderen Beiträgen erwähnt, aber insgesamt sehe ich es einfach nicht als großes Problem an. Es gibt weitaus verwirrendere Dinge, die Sie in MATLAB tun können, zum Beispiel das Definierenfalse=true

Meiner Meinung nach sollten Sie sie wahrscheinlich nur vermeiden, wenn sich Ihr Code speziell mit imaginären Zahlen befasst.

gregswiss
quelle
Können Sie bitte einen Kommentar abgeben, wenn Sie abstimmen? Zum Beispiel mit einem Mathworks-Link, der angibt, dass die Praxis nicht empfohlen wird (was von mehreren Postern angegeben wurde, ohne auf eine offizielle Richtlinie zu verweisen). Tatsächlich wird die Verwendung von 'i' in Schleifen in offiziellen Beispielen von Mathworks verwendet. Nach meiner Erfahrung macht es den Code klar und prägnant und ist sehr üblich.
Gregswiss
1
Zitieren der Dokumentation "Da ies sich um eine Funktion handelt, kann sie überschrieben und als Variable verwendet werden. Es ist jedoch am besten, die Verwendung von iund jfür Variablennamen zu vermeiden, wenn Sie diese in komplexer Arithmetik verwenden möchten." Dies scheint in Verbindung mit dem Kommentar von Eitan T zu Olivers Antwort (ich denke, er hat es zeitlich festgelegt) ein ausreichender Beweis zu sein.
Adriaan
1
Beachten Sie auch, dass es bereits eine Antwort aus dem Jahr 2013 mit dem von @Adriaan erwähnten Kommentar gibt.
Andras Deak
1
In der Dokumentation heißt es also, WENN Sie beabsichtigen, komplexe Arithmetik zu verwenden, andernfalls trifft dies nicht zu - ich weiß nicht, warum hier alle so pingelig sind! Ich habe nur einen alternativen Standpunkt angeboten.
Gregswiss