【问题标题】:Does Matlab accept non-integer indices?Matlab 是否接受非整数索引?
【发布时间】:2016-11-06 22:31:46
【问题描述】:

当然不是! ...或者是吗?让我们做一些测试。

定义x = [10 20 30 40 50]。然后,正如预期的那样,以下任何语句都会在 Matlab 中给出错误(下标索引必须是实数正整数或逻辑数):

>> x(1.2)
>> x(-0.3)
>> x([1.4 2 3])
>> x([1.4 2.4 3.4])
>> x([1.4:4])
>> x(end/2)

但是,冒号索引可以接受非整数值。在最近的 Matlab 版本中,以下所有功能都有效,尽管有一个警告(在用作索引时,冒号运算符需要整数操作数)。

>> x(1.2:3)
ans =
    10    20

>> x(0.4:3)
ans =
    10    10    20

>> x(0.6:3)
ans =
    10    20    30

>> x(1.2:0.7:5)
ans =
    10    20    30    30    40    50

>> x(-0.4:3)
ans =
    10    10    20    30

如果冒号表达式包含end,它也有效:

>> x(1.5:end-2)
ans =
    20    30

>> x(1.5:end/6:end-1)
ans =
    20    20    30    40

另一方面,以下不起作用,并给出与上述相同的错误:

>> x(-0.6:2)
>> x(-0.5:2)

观察到的行为可以总结如下:

  • 当使用 冒号索引 时,会出现一些 内部舍入。冒号索引是a:b 或a:b:c 形式的表达式。当索引数组是标准数组(例如 [a b c] 甚至 [a:b] 或 [a:b:c])时,不会进行舍入。
  • 舍入到最近的整数,除了-0.5和0.5之间的数字是特殊情况:它们被舍入到1而不是到0。当然,如果四舍五入的整数为负数,则会发生错误。

在 Octave 的最新版本中可以看到类似的行为,除了:

  • 显然,正常舍入到最接近的整数已经完成,没有将-0.5 和0.5 之间的数字视为特殊情况;所以这些给出了一个错误:

    >> x(0.4:3)
    >> x(-0.4:3)
    
  • 当非整数范围包含单个值时发出错误:x(2.4:4) 有效,但 x(3.4:4) 无效(当然,x([2.4 3.4]) 和 x(3.4) 也无效) .

除此之外,结果与Matlab中相同,同时也发出警告(Non-integer range used as index)。

警告以及 Octave 与 Matlab 的工作方式相似的事实表明这是有意行为。它是否在某处记录?谁能提供更多信息或对此有所了解?

【问题讨论】:

  • 您使用的是什么版本的 matlab/octave?使用 R2009a 它不起作用...任何人都可以检查其他版本吗?
  • 我的 R2014b 就像@Luis 描述的 Octave 行为一样。它接受除x(0.4:3) 和x(-0.4:3) 之外的所有内容。
  • @Shai 这很有趣。我已经编辑了我的问题,提到它只发生在最近的版本中。查看更多测试here
  • 等待... 什么?
  • @LuisMendo 关于 Octave,见this page的结尾

标签: arrays matlab octave matrix-indexing


【解决方案1】:

补充意见:

  • x(1.2:3)理论上应该解释为:subsref(x, substruct('()',1.2:3))。但是,正如问题中提到的,“当索引数组是标准数组时不会发生舍入”,这会导致显式下标引用失败。这表明发生了类似于logical short-circuiting 或multithreaded partitioning(中间变量“未真正创建”)的机制。

  • 发出的警告标识符是MATLAB:colon:nonIntegerIndex。

理论:

  • 也许存在下标引用的重载版本,其中存在检测下标本身是否为整数的初始步骤。如果不是,MATLAB 会将其“重定向”到其他一些类系列 (example)。

官方cmets:

  • 这是Steve Eddins of TMW 在这个问题上不得不说的:

    ... 在最初的日子里,MATLAB 实现者倾向于在输入验证方面尽可能地宽容。随着时间的推移,我们意识到这种理念并不总是最适合用户,我们开始让一些语言规则更严格、更规范。一个例子是引入了关于无效索引(非整数、非正数等)的错误消息。然而,我们不能总是像我们喜欢的那样收紧行为。有时这是因为我们发现太多的用户代码正在利用原始行为。这就是您在某些地方继续看到这种行为变化的原因之一。 ...我会建议用户只使用整数值索引。用户可以显式调用 round 或 floor 或任何其他方法将冒号运算符的输出转换为整数值。

【讨论】:

    猜你喜欢
    • 2018-08-22
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多