Matlab的数组运算误差(Matlab array arithmetic inaccuracy)

2019-10-16 20:11发布

当我试图模仿我的正弦逼近MATLAB中我发现了一个奇怪的问题。 的问题是,当我申请我的函数的阵列,它返回一个结果,而施加的作用是单独的值给出了一个稍微不同的结果。

我能得到在这个例子中相同的行为:

z = single(0:0.001:1);
F = @(x) (x.^2 - single(1.2342320e-001)).*x.^2;  %some test function

z(999)        % Returns 9.9800003e-001
F(z(999))     % Returns 8.6909407e-001
temp = F(z);  
temp(999)     % Voila! It returns 8.6909401e-001

此外,我发现了一些东西。 其中之一是,第一个结果是正确的(而非后者)。 其次,是项是重排,有时解决问题。 所以,我不知道如何摆脱这一点。

Answer 1:

使用单精度数,二者的结果是“等于”(差大于所述的相对精度较小single类型)。 下面的语句评估为真:

max(abs( arrayfun(F,z) - F(z) )) < eps('single')

编辑

如果你真的想在这个控件,您可以尝试禁用MATLAB加速器,迫使它使用相同的执行路径,同时定期和量化代码:

feature('jit', 'off')
feature('accel', 'off')
max(abs( arrayfun(F,z) - F(z) ))

feature('jit', 'on')
feature('accel', 'on')
max(abs( arrayfun(F,z) - F(z) ))

第一/第二分别的结果:

ans =
     0
ans =
   5.9605e-08

显然,在默认情况下对于油门和刚刚在即时编译器被接通。



Answer 2:

Single-precision only has up to 7 decimal digits of meaningful precision, so to say that 8.6909407e-001 is "right" and 8.6909401e-001 is "wrong" is not terribly meaningful in this situtaion.

Floating-point arithmetic is also sensitive to the order of operations, as you've already found. It's likely that Matlab subtly changes the order of calculations when operating on a matrix rather than a scalar.



Answer 3:

对于矢量算术,MATLAB的线性代数文库可以使用SIMD指令代替的x87 FPU,精度会稍有不同。

相对误差是非常非常小的,应该不会打破任何合理的设计计算。 你测试浮点平等?



Answer 4:

我可以保证,任何采用浮点运算装置不会 ,事实上,提供二进制等于结果数学表达式相等。 尝试在您的各种平台下MATLAB相当于:

a = [repmat(1, 10000, 1); 1e16];
format long
sum(a)
sum(flipud(a))

结果:

1.000000000001000e+16
1.000000000000000e+16

加法是可交换的,所以表达式是数学上等价。 但在浮点数的世界秩序的问题。 显然,增加10000名1的顺序应该不会出现什么问题了浮点,当累计值约为0。但是,一旦浮点已经“漂”到1E16,1简直是太小,无法代表,所以它永远不会添加。

这里有一个额外的皱纹:本的x87 FPU计算在扩展精度(80位),在内部。 所以FPU代码会给你一个不同的答案,如果编译器决定,以保持FPU内部的中间结果。 相反,如果它决定洒中间结果到堆栈,那么你回到64如果它决定计算使用SSE指令,那么你回到64。

在其他答案建议这些不同的MATLAB技巧可能让你足够接近你的问题。 但是,如果您的系统的完美的造型后真的,你可能需要一个模拟框架,更可控。 也许使用vpa ,以转化成在每一步的正确的比特数。 或切换到C或C ++,要非常小心,注意优化控制设置。

或数学计算基于输入缩放你的错误的界限,并确认你的答案总是低于绑定。



Answer 5:

好的。 所有的答案是正确的,但他们并没有解决问题。 我要的是数学上等于表达式带来二进制等于结果,无论我如果用标量或矢量运算。 这使我在FPU我的Cortex-M4,我的计算器,和许多其他programms的和设备,但不Matlab的结果。

到目前为止,我看到的唯一解决办法是使用for -loops代替矢量运算。 丑陋,但它的工作原理。

编辑

多亏了回应,我们对这个问题的一些更多的解决方案。



文章来源: Matlab array arithmetic inaccuracy