下标索引必须是实数正整数或逻辑,通用解

Subscript indices must either be real positive integers or logicals, generic solution

提问人:Dennis Jaheruddin 提问时间:11/19/2013 最后编辑:ShaiDennis Jaheruddin 更新时间:1/1/2016 访问量:93694

问:

以下错误经常发生:

下标索引必须是实数正整数或逻辑

我发现了很多关于这个问题的问题,但没有一个真正通用的答案。因此,我希望有处理此问题的一般解决方案。

MATLAB 调试

评论

0赞 chappjc 12/10/2013
我建议用另外两个非常密切相关的错误来扩展这个 QA。考虑一下:首先是“索引超出矩阵维度”错误,当意外地将变量命名为内置变量,然后尝试将内置变量用作函数时。第二个是一个奇怪的变体,它只是提供了关于同一错误的更多细节。>> mean=1:4; >> mean(12) Index exceeds matrix dimensions. >> mean(12); Attempted to access mean(12); index out of bounds because numel(mean)=4.
0赞 Dennis Jaheruddin 12/10/2013
@chappjc 尽管这些错误是相关的,但这篇文章的主要目标是帮助收到此特定错误消息的人。当然,为每个常见错误消息查找/创建一个好的参考问题和答案可能是个好主意。
2赞 chappjc 12/10/2013
好点子。最好保持专注,尽管解决方案大致相同(下面的第 2 点)。

答:

62赞 Dennis Jaheruddin 11/19/2013 #1

下标索引必须是实数正整数或逻辑

在几乎所有情况下,此错误都是由以下两个原因之一引起的。幸运的是,有一个简单的检查方法。

首先,请确保您位于发生错误的行,这通常可以通过在运行函数或脚本之前使用来实现。现在我们可以检查第一个问题:dbstop if error

1. 在某个地方使用无效索引来访问变量

查找每个变量,并查看它们是如何被索引的。被索引的变量通常采用以下形式之一:

variableName(index,index)
variableName{index,index}
variableName{indices}(indices)

现在只需查看括号之间的内容,然后选择每个索引。然后点击以评估结果并检查它是实数正整数还是逻辑整数。目视检查通常就足够了(请记住,可接受的值为 true、false 或 1、2、3,...但不是 0),但对于大型矩阵,您可以使用类似 的东西,或者更准确地说,来检查真正的正整数。要检查可以使用的类,如果值全部为“true”或“false”,则应返回“logical”。f9isequal(index, round(index))isequal(x, max(1,round(abs(x))))class(index)

确保检查评估每个指数,即使是那些看起来不寻常的指数,如下例所示。如果所有索引都检出,您可能面临第二个问题:

2. 函数名称已被用户定义的变量遮盖

MATLAB 函数通常具有非常直观的名称。这很方便,但有时会导致意外重载(内置)函数,即创建一个与函数同名的变量,例如,您可以去,对于其余的脚本/函数,Matlab 将被视为变量而不是函数,因此如果您尝试类似的东西,您将收到此错误,因为而不是返回该向量的最大值, Matlab 现在假定您正在尝试索引该变量,并且该变量是无效索引。max = 9maxmaxmax([1 8 0 3 7])max0

为了检查你有哪些变量,你可以查看工作区。但是,如果您正在寻找一种系统的方法,这里有一个:

对于后跟括号且尚未在步骤 1 中确认具有正确索引的每个字母或单词。检查它是否实际上是一个变量。这可以通过使用 .()which


例子

简单出现无效索引

a = 1;
b = 2;
c = 3;
a(b/c)

在这里,我们将评估并发现它不是一个很好的四舍五入的数字。b/c

复杂出现无效索引

a = 1;
b = 2;
c = 3;
d = 1:10;
a(b+mean(d(cell2mat({b}):c)))

我建议由内而外地工作。因此,首先要计算要索引的最内部变量:.事实证明,,很好地计算为整数。然后评估并发现我们没有整数或逻辑作为索引。dcell2mat({b}):cb+mean(d(cell2mat({b}):c))a

在这里,我们将评估并发现它不是一个很好的四舍五入的数字。b/c

重载函数

which mean 
% some directory\filename.m

您应该看到这样的东西,以实际确认某些东西是一个函数。

a = 1:4;
b=0:0.1:1;
mean(a) = 2.5;
mean(b);

在这里,我们看到已经意外地被分配了。现在我们得到:mean

which mean
% mean is a variable.

评论

1赞 Adriaan 3/17/2017
很好的答案。您可能希望为 和 作为循环变量的使用添加特定警告,因为它们在赋值之前已经是虚数单位。(这并不是要反对使用 and 作为变量名称,而只是作为一种观察,因为我经常看到其中一个是这个错误的罪魁祸首。ijij
5赞 Daniel 12/14/2015 #2

在 Matlab(和大多数其他编程语言)中,必须始终写乘法符号。在数学课上,您可能了解到可以写 write 而不是 ,这在 matlab 中是不一样的。第一个是索引或函数调用,而第二个是乘法。a(a+a)a*(a+a)

>> a=0

a =

     0

>> a*(a+a)

ans =

     0

>> a(a+a)
Subscript indices must either be real
positive integers or logicals.

评论

0赞 Dennis Jaheruddin 12/15/2015
虽然这种情况隐含在我答案的第 1 点中,但我喜欢它如何发生的额外例子。在此处添加注释以帮助搜索下标索引的人在进行乘法时必须是实数正整数或逻辑
4赞 Pradeep Reddy Raamana 1/1/2016 #3

到目前为止,这个问题的答案集中在这个错误的根源上,这很好。但是,了解Matlab中矩阵索引的强大而非常直观的功能非常重要。因此,索引的工作原理以及什么是有效索引将有助于通过使用有效索引首先避免此错误。

在它的核心,给定一个长度数组,有两种方法可以索引它。An

  1. 线性索引:包含整数的子集(允许重复)。不允许使用 0,因为 Matlab 数组是从 1 开始的,除非您使用以下方法。对于更高维的数组,多个下标在内部转换为线性索引,尽管是以高效和透明的方式进行的。1 : n
  2. 逻辑索引:其中,您使用 0 和 1 的 n 长度数组来选择索引为 true 的元素。在这种情况下,unique(index) 必须只有 0 和 1。

因此,将一个有效的索引数组添加到另一个具有 n 个元素的数组中 ca 是:

  1. 完全合乎逻辑的相同大小,或
  2. 线性,具有 1:n 的整数子集

请记住,当您混合两种类型的索引时,会发生无效的索引错误:线性索引数组中出现一个或多个零,或者将 0 和 1 与 0 和 1 以外的任何内容混合:)

网上有大量的材料可以学习这一点,包括这个: http://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html

评论

0赞 Dennis Jaheruddin 1/4/2016
总的来说,这是一个很好的解释,我不想让你气馁,但似乎你实际回答具体问题的部分已经涵盖了。因此,我认为这实际上应该是一个评论而不是答案。(我没有标记它,因为它太长了,无法转移到评论中,但在以后的帖子中请记住这一点)。
0赞 Pradeep Reddy Raamana 1/5/2016
谢谢丹尼斯。我想了想你的观点,我是否应该浪费我的时间(如果不增加太多,可能会浪费别人的时间),并决定这将在未来提高人们的能力。如果有的话,也许你可以把它移到某个元的地方,以获取MATLAB的教程/技巧,因为这个解释是一个重要功能的核心。