Matlab是否接受非整数索引?

时间:2016-11-06 22:31:46

标签: arrays matlab octave matrix-indexing

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

定义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:ba:b:c形式的表达式。当索引数组是标准数组时,不会发生舍入,例如[a b c][a:b][a:b:c]
  • 最接近的整数进行舍入,但-0.50.5之间的数字特殊:它们舍入为{ {1}}代替1。当然,如果舍入产生的整数为负,则会发生错误。

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

  • 显然,正常舍入到最接近的整数,而不处理0-0.5之间的数字作为特例;所以这些给出了一个错误:

    0.5
  • 当非整数范围包含单个值时会发出错误:>> x(0.4:3) >> x(-0.4:3) 有效,但x(2.4:4)没有(当然,x(3.4:4)和{{1}也不起作用。)

除此之外,结果与Matlab中的结果相同,并且还发出警告(非整数范围用作索引)。

警告和Octave与Matlab类似的事实表明这是预期的行为。某处是记录吗?任何人都可以提供更多信息或对此有所了解吗?

1 个答案:

答案 0 :(得分:7)

其他观察结果:

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

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

理论:

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

官方评论:

  • 这是Steve Eddins of TMW对此问题的评价:
      

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