Matlab是否接受非整数索引?

jc3wubiy  于 2023-03-18  发布在  Matlab
关注(0)|答案(1)|浏览(208)

当然没有!......是吗?我们来做些测试。
定义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而不是0。当然,如果从四舍五入得到的整数是负的,则发生错误。

类似的行为在最近版本的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中的结果相同,并发出警告(* 非整数范围用作索引 *)。
警告和Octave与Matlab类似的工作方式表明这是故意的行为。它是否在某个地方记录?任何人都可以给予更多信息或对此进行说明?

vql8enpb

vql8enpb1#

其他观察:

  • x(1.2:3)理论上应解释为:subsref(x, substruct('()',1.2:3))。然而,正如问题中提到的,“* 当索引数组是标准数组时,不会发生舍入 *”,这会导致显式下标引用失败。这表明发生了类似于logical short-circuitingmultithreaded partitioning的机制(其中中间变量“没有真正创建”)。
  • 发出的警告的标识符是MATLAB:colon:nonIntegerIndex

理论:

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

官方评论:

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

相关问题