使用 i 或 j 作为虚数单位循环索引或公共变量

建议

因为符号 ij 在 MATLAB 中可以代表显着不同的东西,所以它们作为循环索引的使用已经分裂了 MATLAB 用户社区。虽然一些历史性的表现原因可以帮助平衡倾向于一方,但现在不再是这种情况,现在选择完全取决于你和你选择遵循的编码实践。

Mathworks 目前的官方建议如下:

  • 由于 i 是一个函数,它可以被重写并用作变量。但是,如果你打算在复杂的算术中使用它们,最好避免将 ij 用于变量名称。
  • 为了提高复杂算术的速度和稳健性,可以使用 1i1j 代替 ij

默认

在 MATLAB 中,默认情况下,字母 ij 是内置的 function 名称,它们都指复杂域中的虚构单位。

所以默认情况下 i = j = sqrt(-1)

>> i
ans =
   0.0000 + 1.0000i
>> j
ans =
   0.0000 + 1.0000i

正如你所料:

>> i^2
ans =
    -1

将它们用作变量(用于循环索引或其他变量)

MATLAB 允许使用内置函数名作为标准变量。在这种情况下,使用的符号不再指向内置函数,而是指向你自己的用户定义变量。但是,通常不推荐这种做法,因为它可能导致混淆,调试和维护困难( 参见其他示例 do-not-name-a-variable-with-an-existing-name )。

如果你对尊重约定和最佳实践非常迂腐,你将避免在这种语言中将它们用作循环索引。但是,编译器允许它并且功能完备,因此你也可以选择保留旧习惯并将其用作循环迭代器。

>> A = nan(2,3);
>> for i=1:2        % perfectly legal loop construction
       for j = 1:3
        A(i, j) = 10 * i + j;
       end
   end

请注意,循环索引在循环结束时不会超出范围,因此它们保留其新值。

>> [ i ; j ]
ans =
     2
     3

如果你将它们用作变量,请确保在使用它们之前对它们进行初始化。在上面的循环中,MATLAB 在准备循环时自动初始化它们,但如果没有正确初始化,你可以很快发现你可能无意中在结果中引入了 complex 数字。

如果稍后,你需要撤消内置函数的阴影(=例如,你希望 ij 再次表示想象单位),你可以改变变量:

>> clear i j

*如果你打算在复杂算术中使用它们,*你现在可以理解 Mathworks 保留将它们用作循环索引。你的代码将充满变量初始化和 clear 命令,最好的方式来混淆最严重的程序员( 是的,你在那里!…… )和程序事故等待发生。

如果没有预期的复杂算术,ij 的使用是完全正常的,没有性能损失。

将它们用作虚构单位:

如果你的代码必须处理 complex 号码,那么 ij 肯定会派上用场。但是,为了消除歧义甚至是表演,建议使用完整形式而不是速记语法。完整的形式是 1i(或 1j)。

>> [ i ; j ; 1i ; 1j]
ans =
   0.0000 + 1.0000i
   0.0000 + 1.0000i
   0.0000 + 1.0000i
   0.0000 + 1.0000i

它们确实代表了相同的价值 sqrt(-1),但后来的形式:

  • 以语义的方式更明确。
  • 更易于维护(稍后查看代码的人不必阅读代码来查找 ij 是变量还是虚构单位)。
  • 更快(来源:Mathworks)。

请注意,完整语法 1i 对符号前面的任何数字有效:

>> a = 3 + 7.8j
a =
   3.0000 + 7.8000i

这是唯一可以在没有操作符的情况下使用数字的函数。

陷阱

虽然它们作为虚构单位变量使用是完全合法的,但这里只是一个小例子,说明如果这两种用法混合起来会让人感到困惑:

让我们覆盖 i 并将其变为变量:

>> i=3
i =
     3

现在 i 是一个变量 (保持值 3),但我们只覆盖了虚构单位的速记符号,完整形式仍然正确解释:

>> 3i
ans =
   0.0000 + 3.0000i

现在让我们构建最模糊的配方。我让你评估以下所有结构的可读性:

>> [ 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

如你所见,上面数组中的每个值都返回不同的结果。虽然每个结果都是有效的(假设这是最初的意图),但大多数人都会承认阅读充满这种结构的代码将是一场正确的噩梦。