下标索引必须是真正的正整数或逻辑,通用解决方案

Posted

技术标签:

【中文标题】下标索引必须是真正的正整数或逻辑,通用解决方案【英文标题】:Subscript indices must either be real positive integers or logicals, generic solution 【发布时间】:2013-12-01 23:20:48 【问题描述】:

以下错误经常出现:

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

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

【问题讨论】:

我建议用另外两个非常相关的错误来扩展这个 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. 首先是“索引超出矩阵维度”错误,当意外将变量命名为内置函数然后尝试将内置函数用作函数时。第二个是一个奇怪的变体,它只是提供了同一错误的更多细节。 @chappjc 虽然这些错误是相关的,但这篇文章的主要目的是帮助收到此特定错误消息的人。当然,为每个常见错误消息查找/创建一个好的参考问题和答案可能是一个好主意。 好点。最好保持专注,尽管解决方案大致相同(下面的第 2 点)。 【参考方案1】:

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

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

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

1。某处使用了无效索引来访问变量

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

variableName(index,index)
variableNameindex,index
variableNameindices(indices)

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

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

2。函数名称已被用户定义的变量所掩盖

MATLAB 函数通常具有非常直观的名称。这很方便,但有时会导致意外重载(内置)函数,即创建一个与函数同名的变量,例如您可以使用max = 9,而对于其余的脚本/函数,Matlab 将考虑使用max是一个变量而不是函数max,所以如果你尝试类似max([1 8 0 3 7]),你会得到这个错误,因为不是返回那个向量的最大值,Matlab现在假设你试图索引变量max和@ 987654332@ 是无效索引。

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

对于后跟括号() 且在步骤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)))

我建议由内而外地工作。所以首先评估被索引的最内部变量:d。事实证明,cell2mat(b):c 可以很好地计算为整数。然后评估b+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.

【讨论】:

很好的答案。您可能需要针对 ij 作为循环变量的用法添加一个特定的警告,因为它们在分配它们之前已经是虚数单位。 (这并不是反对使用 ij 作为变量名,只是作为一种观察,因为我经常看到其中一个是这个错误的罪魁祸首。)【参考方案2】:

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

>> a=0

a =

     0

>> a*(a+a)

ans =

     0

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

【讨论】:

虽然我的回答的第 1 点隐含了这种情况,但我喜欢它如何发生的附加示例。在此处添加注释以帮助搜索下标索引在进行乘法运算时必须是真正的正整数或逻辑【参考方案3】:

到目前为止,这个问题的答案都集中在这个错误的来源上,这很好。但重要的是要了解 Matlab 中矩阵索引的强大而非常直观的特性。因此索引是如何工作的什么是有效索引将首先通过使用有效索引来帮助避免这个错误。

在其核心,给定一个长度为n 的数组A,有两种方法对其进行索引。

    线性索引:使用来自1 : n 的整数子集(允许重复)。 0 是不允许的,因为 Matlab 数组是从 1 开始的,除非你使用下面的方法。对于高维数组,多个下标在内部是converted into a linear index,尽管是以一种高效且透明的方式。 逻辑索引:您使用一个由 0 和 1 组成的 n 长度数组来选择那些索引为真的元素。在这种情况下,unique(index) 必须只有 0 和 1。

所以一个有效的索引数组到另一个具有 n 个元素的数组可以是:

    完全符合逻辑,大小相同,或 与 1:n 的整数子集成线性关系

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

网上有大量资料可供学习,其中包括: http://www.mathworks.com/company/newsletters/articles/matrix-indexing-in-matlab.html

【讨论】:

总的来说,这是一个很好的解释,我不想让您气馁,但您实际回答特定问题的部分似乎已经涵盖了。因此,我认为这实际上应该是评论而不是答案。 (我没有标记它,因为它太长而无法转移到评论中,但在以后的帖子中请记住这一点)。 谢谢丹尼斯。我考虑了你的观点我是否应该浪费我的时间(如果不增加太多可能会浪费其他人的时间),并决定这将提高人们未来的能力。如果有的话,也许你可以将它移到一些元位置以获取 matlab 的教程/提示,因为这种解释是一个重要特性的核心。

以上是关于下标索引必须是真正的正整数或逻辑,通用解决方案的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB 错误:下标索引必须是实数正整数或逻辑数

Matlab错误:下标索引必须是实数正整数或逻辑数

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

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

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

“数组索引必须是正整数或逻辑值”