Matlab 是否接受非整数索引?

Does Matlab accept non-integer indices?

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

定义 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)

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

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

  • 显然,正常四舍五入到最接近的整数,没有将 -0.50.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 类似的警告和事实表明这是有意的行为。它在某处记录吗?任何人都可以提供 更多信息 或阐明这一点吗?

补充观察:

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

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

理论:

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

官方评论:

  • 这是 Steve Eddins of TMW 对这个主题的看法:

    ... in its earliest days, MATLAB implementers had a tendency to be as permissive as possible with respect to input validation. Over time, we realized that this philosophy wasn’t always the best one for users, and we started making some of the language rules tighter and more regular. One example was the introduction of error messages about invalid indices (noninteger, nonpositive, etc.). However, we couldn’t always tighten up the behavior as much as we liked. Sometimes that was because we discovered that too much user code was exploiting the original behavior. That is one of the reasons you continue to see this kind of behavior variation in some places. ... I would advise users to only use integer-valued indices. Users can explicitly call round or floor or whatever to convert the output of the colon operator to be integer-valued.