如this answer by Sam Roberts和this other answer by gnovice中所述,MATLAB的冒号运算符(start:step:stop
)创建值向量的方式与linspace
不同。
冒号运算符将增量加到起始点,并从结束点减去减量以到达中间点。通过这种方式,它确保输出向量尽可能对称。
然而,官方文件有关这一点从数学工作已被删除,从他们的网站。
如果萨姆的描述是正确的,那么步长的误差不是对称的吗?
>> step = 1/3;
>> C = 0:step:5;
>> diff(C) - step
ans =
1.0e-15 *
Columns 1 through 10
0 0 0.0555 -0.0555 -0.0555 0.1665 -0.2776 0.6106 -0.2776 0.1665
Columns 11 through 15
0.1665 -0.2776 -0.2776 0.6106 -0.2776
关于冒号运算符需要注意的有趣事项:
- 其值取决于其长度:
>> step = 1/3;
>> C = 0:step:5;
>> X = 0:step:3;
>> C(1:10) - X
ans =
1.0e-15 *
0 0 0 0 0 -0.2220 0 -0.4441 0.4441 0
- 如果对重复值进行四舍五入,则会生成重复值:
>> E = 1-eps : eps/4 : 1+eps;
>> E-1
ans =
1.0e-15 *
-0.2220 -0.2220 -0.1110 0 0 0 0 0.2220 0.2220
- 最后一个值存在公差,如果步长创建的值刚好高于终点,则仍使用该终点值:
>> A = 0 : step : 5-2*eps(5)
A =
Columns 1 through 10
0 0.3333 0.6667 1.0000 1.3333 1.6667 2.0000 2.3333 2.6667 3.0000
Columns 11 through 16
3.3333 3.6667 4.0000 4.3333 4.6667 5.0000
>> A(end) == 5 - 2*eps(5)
ans =
logical
1
>> step*15 - 5
ans =
0
1条答案
按热度按时间r1zk6ea11#
Sam's answer引用的被删除的页面仍然是archived by the Way Back Machine,幸运的是,连附带的M文件
colonop
也在,而且看起来这个函数仍然符合MATLAB的功能(我在R2017a上):这里我将重复函数在一般情况下的作用(生成整数向量和处理特殊情况有一些快捷方式),我将用更有意义的变量名替换函数的变量名,输入为
start
、step
和stop
。首先,它计算
start
和stop
之间有多少步。如果最后一步超出stop
的距离大于容差,则不执行该步:这解释了问题中最后一项观察结果。
接下来,它计算最后一个元素的值,并确保它不超过
stop
值,即使在前面的计算中允许它超过该值。这就是为什么问题中向量
A
中的lasat值实际上具有stop
值作为最后一个值。接下来,它分两部分计算输出数组,正如所宣传的那样:独立地填充阵列的左半部分和右半部分:
注意,它们不是通过递增来填充的,而是通过计算一个整数数组并将其乘以步长来填充的,就像
linspace
一样。这解释了问题中对数组E
的观察。不同之处在于数组的右半部分是通过从last
值中减去这些值来填充的。最后一步,对于奇数大小的数组,将单独计算中间值,以确保它正好位于两个端点的中间:
完整的函数
colonop
复制在底部。请注意,分别填充数组的左侧和右侧并不意味着步长中的误差应该完全对称。这些误差由舍入误差给出。但是,如果步长没有精确到达
stop
点,则会产生差异,如问题中的数组A
。在这种情况下,在阵列的中间而不是在末端采用稍短的步长:但是,即使在
stop
点正好到达的情况下,中间也会累积一些额外的误差,以问题中的数组C
为例,这种误差累积不会发生在linspace
中:一个月十九个月: