在 MATLAB 中使用 i 和 j 作为变量

Using i and j as variables in MATLAB

提问人:Shai 提问时间:2/10/2013 最后编辑:Peter MortensenShai 更新时间:3/24/2021 访问量:21435

问:

i并且是非常流行的变量名称(例如,参见此问题此问题)。j

例如,in 循环:

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

作为矩阵中的索引:

mat(i, j) = 4;

为什么它们不应该在MATLAB中用作变量名称?

MATLAB 变量 命名约定

评论

8赞 A. Donda 4/27/2015
当然,我不会这样标记它,但从答案来看,我会说这是“主要基于意见的”。;-)我个人不会放弃 , , 作为通用循环变量名称。ijk
2赞 Shai 4/27/2015
@A.Donda嗯,这是的意见;)

答:

4赞 yo' 2/10/2013 #1

默认情况下,代表虚数单位。因此,从MATLAB的角度来看,用作变量在某种程度上类似于用作变量。iji1

评论

5赞 thang 2/10/2013
我不认为是那样的。i 是一个合法的变量名称,因此您实际上可以使用 i 和 j 作为变量名称。正如前面的答案所提到的,它将掩盖虚构的意义。1 不是合法的变量名称。如果你从不使用复数,那完全没问题。
0赞 yo' 2/10/2013
@thang这就是为什么我说“不知何故喜欢”而不是“喜欢”。我知道这是有区别的。OP问为什么不应该使用它们,我试图解释这是因为它们已经表达了一个数字。
2赞 thang 2/10/2013
好吧,对不起,我不知道喜欢是什么意思。对我来说,这显然是不同的,因为好吧,即使你想,你也不能使用 1 作为变量......但我明白你来自哪里。
0赞 Gunther Struyf 2/10/2013
您可以使用它们,因为您也可以将现有的函数名称用于变量(同时损坏这些内置函数/常量以供进一步使用)。你是否真的想要那是另一回事(imo简单的答案:不)
1赞 patrik 11/30/2015
对不起,这个解释没有意义。和实际上是返回虚数单位值的函数。可以使用与作用域中的函数同名的变量。但是,这将遮蔽该函数。ij
177赞 Oliver Charlesworth 2/10/2013 #2

因为 和 都是表示虚部的函数:ij

因此,一个变量调用或将覆盖它们,可能会以静默方式破坏执行复杂数学运算的代码。ij

可能的解决方案包括改用 and 作为循环变量,或者使用 whenever 来表示虚部单位。iijj1ii

评论

42赞 Eitan T 3/5/2013
还值得注意的是,即使您没有破坏任何内容,仍然会牺牲执行时间来解析 和 变量名称。ij
16赞 horchler 6/11/2013
@Eitan:在JIT编译版的Matlab中,您真的能以任何具体的结论性方式支持它吗?我从未发现过这种情况(调用循环 10 亿次的简单测试显示时间没有统计学差异)。据我们所知,有特殊的代码可以准确地处理这个问题,并且使用 and(和?)以外的变量实际上稍微慢一些。在现实生活中,确实存在的差异微乎其微,甚至不存在。根本没有理由不使用 和 作为常规变量 - 它们只需要像任何其他 Matlab 函数一样正确使用。forijkij
5赞 Eitan T 6/11/2013
@horchler 好吧,官方文档在这里指出,覆盖标准 MATLAB 数据类“会对性能产生负面影响”,这里暗示要避免出于速度和鲁棒性的原因覆盖复杂常量。在 R2009b 的旧文档中,明确建议不要覆盖复数常量,因为这可能会阻碍 JIT 加速。变量名称解析可能是微不足道的,但如果重复数百万次,它可能会很重要。
16赞 horchler 6/11/2013
也许在古代版本的 Matlab 中。我曾经亲眼目睹过。但至少在 R2012a+ (OS X) 上不再如此。在调用循环 10 亿次并尝试各种计时方案时,我看不出有什么区别。我看到新的 SO 用户被告知完全有效的代码是错误的,因为他们正在使用和迭代循环。坦率地说,这很愚蠢,人们忽略了这个问题中更重要的一点:如果一个人想编写可读的现代 Matlab 代码,甚至不应该将其用于虚构单元。forijij
12赞 craq 2/18/2014
我节省的主要时间是在搜索 II 时。寻找 i 可能真的很痛苦
66赞 shoelzer 2/14/2013 #3

避免使用变量来防止混淆它们是变量或虚数单位是一种很好的做法。ij

然而,就我个人而言,我经常使用 和 作为变量作为短循环的索引。为了避免在我自己的代码中出现问题,我遵循另一个关于 and 的好做法:不要用它们来表示虚数。事实上,MATLAB 自己的文档指出ijij

为了提高速度和提高鲁棒性,您可以用 .ij1i

因此,我没有因为潜在的冲突而避免使用两个非常常用的变量名称,而是明确使用虚数。这也使我的代码更加清晰。每当我看到 时,我就知道它代表了,因为它不可能是一个变量。1isqrt(-1)

评论

3赞 Shai 2/14/2013
使用确实是很好的做法。但是,更改 和 的含义可能会导致难以调试的错误,例如此类错误。1iij
1赞 shoelzer 2/14/2013
@Shai 好点子。我调整了我的答案,承认避免和是最好的,但解释了我的个人编码风格如何不遵循该规则。ij
2赞 Dennis Jaheruddin 8/14/2013
请注意,提到的速度似乎不是很重要:stackoverflow.com/questions/18163454/......
1赞 SddS 7/3/2017
完全同意!好的做法是始终使用而不是用于复杂的数学。让我们把虚数看作是虚数,并把它看作是一种不好的做法。反之则不然。使用 , 是 Matlab 中的常见做法,当人们坚持使用复数 和 时没有问题。此外,Matlab 尊重这一点,并且正如之前的答案中所述,这不会降低性能(就我测试而言)。1ii1iiiiiiii1i1j
0赞 LightCC 8/13/2019
无论如何都不应该使用 i 和 j - 这些数字意味着什么 - 使用描述目的的名称(row_n、elementNo、listItemIndex 等)。让别人更容易理解你在做什么,调试等。花费的额外时间比一次性脚本更值得长期可维护性 - 即使 Matlab 编辑器远远落后于大多数其他现代 IDE。
16赞 Dennis Jaheruddin 2/15/2013 #4

如其他答案中所述,不建议在常规代码中使用,原因有二:i

  • 如果要使用虚数,它可能会与索引混淆或被索引覆盖
  • 如果将其用作索引,它可能会覆盖或与虚数混淆

如建议:和推荐。然而,尽管这些都是细微的偏差,但同时使用这两种替代方案并不是很好。1iiii

这是一个例子,为什么(个人)我不喜欢它:

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

一个不会轻易被误读为两个或三个,但两个和三个彼此相似。

因此,我个人的建议是:如果您有时使用复杂的代码,请始终与不同的循环变量结合使用。1i

如果您不使用很多循环变量和字母,则单字母索引示例就足够了:、和tukp

较长指数示例:,,, 和i_loopstepwalkt_now

当然,这也是个人品味的问题,但应该不难找到具有明确含义的指数,而不会增长太长。

评论

1赞 lib 2/21/2013
1i 表示虚数单位(Matlab 变量名称也不能以数字开头)
2赞 Amro 4/22/2013
@DennisJaheruddin:无耻插件:使用我的 MATLAB 语法突出显示 Stack Overflow 的用户脚本。在最后一个示例中,将以不同的颜色作为数字:)1i
2赞 horchler 6/3/2013
直接来自 和 :“为了提高速度和提高鲁棒性,您可以将复数 i 和 j 替换为 1i。IMO,在当前的 Matlab 中,没有理由不使用 和 in 循环等,或者使用除表示虚数单位以外的任何东西(也有效)。唯一的例外是将字符串传递给总是略微不兼容的符号引擎。奇怪的是,虽然不起作用。doc idoc jij1i1jhelp 1idoc 1i
12赞 Floris 6/21/2013 #5

有人指出,这是一种可接受且明确的书写方式,因此没有必要避免使用.话又说回来,正如丹尼斯所指出的,很难看出 和 之间的区别。我的建议:尽可能用作虚常数。这与电气工程师使用的技巧相同 - 他们用于因为已经用于电流1isqrt(-1)i1iii1jjsqrt(-1)i

就我个人而言,我从不使用和;我使用 and 作为速记索引变量,(和 kk、ll、mm、...)以及当我需要使用复数时。ijiijj1j

评论

2赞 glglgl 2/20/2014
“很难看出 和 之间的区别” 和 之间的区别更甚。这就是为什么我在全新 MATALB 安装中做的第一步是更改默认字体大小。1iii1lO0
33赞 Sam Roberts 7/18/2013 #6

在旧版本的 MATLAB 中,过去有充分的理由避免使用 and 作为变量名称 - 早期版本的 MATLAB JIT 不够聪明,无法判断它们是将它们用作变量还是虚构单位,因此会关闭许多其他可能的优化。ij

因此,仅仅因为 和 作为变量的存在,你的代码就会变慢,如果你把它们改成其他东西,代码就会变慢。因此,如果您通读了大量 MathWorks 代码,就会看到并广泛地用作循环索引。有一段时间,MathWorks 甚至可能非正式地建议人们自己这样做(尽管他们总是正式建议人们进行编程以追求优雅/可维护性,而不是当前 JIT 所做的任何事情,因为它是每个版本的移动目标)。ijiijj

但那是很久以前的事了,现在它有点像一个“僵尸”问题,实际上远没有许多人认为的那么重要,但拒绝死亡。

在任何最新版本中,是否使用 and 作为变量名称实际上是个人偏好。如果你对复数做了大量工作,你可能希望避免 和 作为变量,以避免任何小的潜在混淆风险(尽管你可能也/相反只想使用 or 来减少混淆,以及更好的性能)。ijij1i1j

另一方面,在我的典型工作中,我从不处理复数,如果我觉得随意使用和作为循环索引,我发现我的代码更具可读性。ij


我在这里看到很多答案说:不推荐......没有说谁在做那个推荐。以下是 MathWorks 在当前版本文档中提出的实际建议的范围:i

由于 i 是一个函数,因此可以将其覆盖并用作变量。但是,如果您打算在复杂的算术中使用 i 和 j 作为变量名称,最好避免使用它们。[...]为了提高速度和鲁棒性,您可以将复数 i 和 j 替换为 1i。

6赞 xenoclast 4/29/2015 #7

这里已经很好地讨论了与虚数单位的混淆,但还有一些其他更平淡无奇的原因,为什么有时不鼓励使用这些和其他单字母变量名称。

  1. 特别是MATLAB:如果您使用编码器从MATLAB代码生成C++源代码(不要,这太可怕了),那么系统会明确警告您不要重用变量,因为潜在的类型冲突。

  2. 通常,根据您的 IDE,单字母变量名称可能会对荧光笔和搜索/替换造成严重破坏。MATLAB不会受到这种情况的影响,我相信Visual Studio已经有一段时间没有问题了,但是像MISRA等C/C++编码标准倾向于反对它们。

就我而言,我避免使用所有单字母变量,尽管直接实现数学源具有明显的优势。前几百次你这样做需要一点额外的努力,但在那之后你就不再注意到了,当你或其他一些可怜的灵魂来阅读你的代码时,好处是巨大的。

3赞 gregswiss 9/14/2015 #8

除非您是一个非常困惑的用户,否则我认为使用变量名称 ij 的风险很小,并且我经常使用它们。我还没有看到任何官方迹象表明应该避免这种做法。

虽然确实,正如其他帖子中提到的,在某些上下文中,隐藏虚构单元可能会造成一些混乱,但总的来说,我根本不认为这是一个主要问题。在MATLAB中,您可以做更多令人困惑的事情,例如定义false=true

在我看来,唯一应该避免它们的情况是,如果您的代码专门处理虚数。

评论

0赞 gregswiss 10/13/2015
你能在投反对票时发表评论吗?例如,带有一个 Mathworks 链接,表明不推荐这种做法(多张海报已声明,但未引用任何官方指南)。事实上,Mathworks 在官方示例中使用了 'i' 循环。根据我的经验,它使代码清晰简洁,是非常常见的做法。
1赞 Adriaan 10/13/2015
引用文档“由于是一个函数,它可以被覆盖并用作变量。但是,如果您打算在复杂的算术中使用变量名称,最好避免使用 and。结合 Eitan T 对 Oliver 回答的评论(我猜他安排了时间)似乎足以证明这一点。iij
1赞 Andras Deak -- Слава Україні 10/13/2015
另请注意,2013 年已经有了 @Adriaan 提到的评论的答案。
1赞 gregswiss 10/13/2015
所以文档指出,如果您打算在复杂的算术中使用,否则这不适用 - 不知道为什么每个人都在这里如此挑剔!我只是提供另一种观点。
4赞 Pradeep Reddy Raamana 12/31/2015 #9

任何重要的代码都包含多个循环,最佳做法建议使用指示其用途和范围的描述性名称。自古以来(除非我不打算保存它的 5-10 行脚本),我一直使用变量名称,如 等。foridxTaskidxAnotherTaskidxSubTask

或者至少将它所索引的数组的第一个字母加倍,例如 索引 ,索引 ,但不是 ,或者哪个不能帮助我毫不费力地识别它们从我的多个 for 循环中索引的数组。sssubjectListtttaskListiijj

评论

0赞 Peter Mortensen 3/24/2021
最好避免在MATLAB中出现显式循环(因为它非常慢)。许多东西可以表示为矩阵和向量运算。