web-dev-qa-db-ja.com

Matlabで変数としてiとjを使用する

ijは非常に一般的な変数名です(例: this question および this one を参照)。

たとえば、ループ内:

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

行列のインデックスとして:

mat( i, j ) = 4;

なぜMatlabで変数名として使用すべきではないのか

137
Shai

ijは両方とも 虚数単位 を示す関数であるためです。

そのため、iまたはjと呼ばれる変数がそれらをオーバーライドし、複雑な計算を行うコードを静かに破壊する可能性があります。

可能な解決策には、代わりにループ変数としてiijjを使用するか、1i虚数単位を表すためにiが必要な場合はいつでも。

176

i変数とj変数を避けて、変数または虚数単位であるという混乱を防ぐことをお勧めします。

しかし、個人的には、ijを短いループのインデックスとして非常に頻繁に変数として使用します。自分のコードの問題を避けるために、ijに関する別の良い習慣に従います:do n'tuseそれらは虚数を示します。実際、 Matlab自身のドキュメントの状態

速度と堅牢性を向上させるために、複雑なijを_1i_に置き換えることができます。

したがって、潜在的な競合のために非常に一般的に使用される2つの変数名を回避するのではなく、虚数について明示的に説明します。また、コードがより明確になります。 _1i_が表示されるときはいつでも、それがsqrt(-1)を表していることを知っています。変数にできない可能性があるからです。

62
shoelzer

MATLABの古いバージョンでは、変数名としてijの使用を避ける正当な理由がありました-MATLAB JITの初期バージョンは、あなたがそれらを変数または虚数単位として使用するため、多くの場合可能な最適化がオフになります。

したがって、変数としてijが存在するだけでコードは遅くなり、それらを別のものに変更すると速度が向上します。そのため、多くのMathWorksコードを読むと、iijjがループインデックスとしてかなり広く使用されていることがわかります。しばらくの間、MathWorksは自分でそれを行うように非公式に人々にアドバイスすることさえありました(ただし、各バージョンを動かすターゲットであるため、現在のJITが行うものではなく、優雅さ/保守性をプログラムするよう常に人々に公式にアドバイスしています)。

しかし、それはかなり前のことであり、今日では多くの人がまだ考えているよりもはるかに重要ではないが、死ぬことを拒否する「ゾンビ」の問題です。

最近のバージョンでは、ijを変数名として使用するかどうかは個人的に好みです。複雑な数で多くの作業を行う場合、混乱の小さな潜在的なリスクを避けるために、変数としてijを避けることができます(ただし、/つかいます 1iまたは1j混乱を減らし、パフォーマンスを少し向上させます)。

一方、私の典型的な作業では、複素数を扱うことはありません。ループインデックスとしてijを自由に使用できると、コードが読みやすくなります。


ここに推奨されません...と言う答えがたくさんあります。 iの現在のリリースドキュメントから、MathWorksの実際の推奨範囲を以下に示します。

Iは関数なので、オーバーライドして変数として使用できます。ただし、複雑な算術演算で使用する場合は、変数名にiとjを使用しないようにすることをお勧めします。 [...]速度と堅牢性を向上させるために、複雑なiとjを1iに置き換えることができます。

27
Sam Roberts

他の回答で説明したように、一般的なコードでiを使用することは、次の2つの理由で推奨されません。

  • 虚数を使用する場合は、インデックスと混同したり、インデックスによって上書きされたりする可能性があります
  • インデックスとして使用すると、上書きしたり、虚数と混同したりする可能性があります

提案どおり:1iおよびiiが推奨されます。ただし、これらは両方ともiからの微妙な違いですが、これらの選択肢の両方を一緒に使用するのはあまり良いことではありません。

以下に(個人的に)気に入らない理由の例を示します。

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

2つまたは3つを間違えることは簡単ではありませんが、2つと3つは互いに似ています。

そのため、私の個人的な推奨事項は次のとおりです。複雑なコードで作業することがある場合は、常に1iを別のループ変数と組み合わせます。

ループ変数と文字をあまり使用しない場合に十分な単一文字インデックスの例:tukおよびp

長いインデックスの例:i_loopstepwalk、およびt_now

もちろん、これは個人的な好みの問題でもありますが、長くなりすぎずに明確な意味を持つ使用するインデックスを見つけるのは難しくありません。

15

1isqrt(-1)を記述するための許容できる明確な方法であり、iの使用を避ける必要はないことが指摘されました。それから、デニスが指摘したように( https://stackoverflow.com/a/14893729/1967396 )、1iiiの違いを見分けるのは難しいかもしれません。私の提案:可能な限り虚数定数として1jを使用してください。これは、電気技術者が採用しているのと同じトリックです。jはすでに current に使用されているため、sqrt(-1)にはiを使用します。

個人的にはijを使用しません。複素数を使用する必要がある場合は、iijjを略式のインデックス変数(およびkk、ll、mm、...)および1jとして使用します。

11
Floris

架空のユニットとの混乱はここで十分にカバーされていますが、これらおよび他の1文字の変数名がときどき推奨されない他のより平凡な理由がいくつかあります。

  1. 特にMATLAB:コーダーを使用してMATLABコードからC++ソースを生成している場合(恐ろしいことではありません)、タイプ衝突の可能性があるため、変数を再利用しないように明示的に警告されます。

  2. 通常、IDEによっては、1文字の変数名が蛍光ペンと検索/置換で大混乱を引き起こす可能性があります。 MATLABはこれに悩まされておらず、Visual Studioにはしばらくの間問題がなかったと思いますが、MISRAなどのC/C++コーディング標準はそれらを再度アドバイスする傾向があります。

私の側では、数学的なソースを直接実装することの明らかな利点にもかかわらず、すべての1文字の変数を避けています。最初の数百回は少し手間がかかりますが、その後は気づかないようになり、コードを読むためにあなたや他の貧しい人々が来るときの利点はたくさんあります。

6
xenoclast

自明でないコードには複数のforループが含まれます。ベストプラクティスでは、その目的と範囲を示すわかりやすい名前を使用することをお勧めします。太古の時代(そして、保存しない5〜10行のスクリプトでない限り)、常にidxTaskidxAnotherTaskidxSubTaskなどの変数名を使用していました。 。

または、少なくとも配列の最初の文字を2倍にして、インデックスを作成しています。 ssはインデックスにsubjectListに、ttはインデックスtaskListに、ただしiiまたはjjは無効複数のforループからインデックス付けされている配列を簡単に識別できます。

デフォルトでは、ijは虚数単位を表します。そのため、MATLABの観点からは、変数としてiを使用することは、変数として1を使用することに似ています。

2
yo'

あなたが非常に混乱したユーザーでない限り、変数名iおよびjそして、私はそれらを定期的に使用しています。私は、この慣行を避けるべきであるという公式の兆候を見たことはありません。

想像上のユニットをシャドウイングすることは、他の投稿で言及されているように、いくつかのコンテキストで混乱を引き起こす可能性があるのは事実ですが、全体的に私はそれを大きな問題とは考えていません。 MATLABでできることははるかに複雑です。たとえば、false=true

私の意見では、おそらくあなたのコードが虚数を扱う場合のみ、それらを避けるべきです。

2
gregswiss

なぜなら、iとjはデフォルトでは虚数単位だからです。 iおよびjに他の値を割り当てると、デフォルト値が上書きされます。これにより混乱が生じる可能性があります。ただし、これを回避する良い方法は、1iと1jを虚数単位として使用することです。一般に、niとnjを使用して虚数を表すことができます。

例えば:

>> i

ans =

   0.0000 + 1.0000i

>> i=2

i =

     2

>> 1i

ans =

   0.0000 + 1.0000i
0
Greenmarch zzZ