为什么在sum(b.*x1)
中使用相同的代码运行在不同版本的MATLAB (2016vs2021)时得到不同的结果,其中b
是单的,x1
是双倍的。如何避免MATLAB版本之间的这种错误?
MATLAB v.2021:
sum(b.*x1)
ans =
single
-0.0013286
MATLAB 2016
sum(b.*x1)
ans =
single
-0.0013283
发布于 2021-12-03 07:43:34
在R2017b中,它们更改了用于单精度浮点数的sum
行为,在R2020b中,它们也对其他数据类型进行了相同的更改。
这种变化加快了计算速度,减小了舍入误差,提高了计算精度。简单地说,以前该算法只是按顺序在数组中运行,然后将值相加。新行为计算数组中较小部分的和,然后将这些结果相加。这是更精确的,因为运行的总数可以成为一个非常大的数字,加上较小的数字会导致更多的四舍五入在这些较小的数字。速度的提高来自于循环展开:循环现在跨越,比如说,当时的8个值,而在循环体中,计算了8个运行总计(它们没有指定它们使用的数字,这里的8就是一个例子)。
因此,新的结果比旧的结果更接近数组的和。
有关更多细节(更好地解释新算法和更改原因),请参见这篇博客文章。
关于如何避免这种差异:您可以实现自己的sum
函数,并使用它而不是内置函数。为了提高效率,我建议把它写成MEX文件。但是,一定要与内置sum
的新行为相匹配,因为这是更好的近似。
下面是这个问题的一个例子。让我们用N+1
元素创建一个数组,其中第一个元素的值为N
,其余元素的值为1。
N = 1e8;
a = ones(N+1,1,'single');
a(1) = N;
该数组上的和预计为2*N
。如果我们设置N
足够大,w.r.t。数据类型,我在R2017a中看到(在更改之前):
>> sum(a)
ans =
single
150331648
我在R2018b中看到了这一点(在对单精度sum
进行更改之后):
>> sum(a)
ans =
single
199998976
这两个实现在这里都会产生舍入错误,但其中一个显然更接近预期结果(2e8
,或200000000
)。
https://stackoverflow.com/questions/70209828
复制相似问题