具有大量术语的双精度乘积中的正确十进制数字的数量

时间:2012-08-21 01:40:50

标签: matlab floating-point numerical

无理数集合 N 的大小紧密下限,在64位计算机上的Matlab中表示为双精度数,我将它相乘,同时对< em> k 产品的十进制数字?什么精度,例如我可以预期在将10 ^ 12个双倍编码后编码不同的pi随机块?

3 个答案:

答案 0 :(得分:3)

如果要求紧束缚,@ EricPostpischil的响应是绝对误差界限,如果所有操作都以IEEE 754双精度执行。

如果您要求自信,我将其理解为错误的统计分布。假设[-e / 2,e / 2]中的误差均匀分布,你可以尝试在数学堆栈交换的M次操作之后要求理论上的误差分布...我猜这个紧束缚在某种程度上非常保守。

让我们用一些Smalltalk代码说明这些统计数据的实验估计(任何具有大整数/分数算术的语言都可以):

nOp := 500.
relativeErrorBound := ((1 + (Float epsilon asFraction / 2)) raisedTo: nOp * 2 - 1) - 1.0.
nToss := 1000.
stats := (1 to: nToss)
    collect: [:void |
        | fractions exactProduct floatProduct relativeError  |
        fractions := (1 to: nOp) collect: [:e | 10000 atRandom / 3137].
        exactProduct := fractions inject: 1 into: [:prod :element | prod * element].
        floatProduct := fractions inject: 1.0 into: [:prod :element | prod * element].
        relativeError := (floatProduct asFraction - exactProduct) / exactProduct.
        relativeError].
s1 := stats detectSum: [:each | each].
s2 := stats detectSum: [:each | each squared].
maxEncounteredError  := (stats detectMax: [:each | each abs]) abs asFloat.
estimatedMean := (s1 /nToss) asFloat.
estimatedStd := (s2 / (nToss-1) - (s1/nToss) squared) sqrt.

我得到这些结果用于乘以nOp = 20 double:

relativeErrorBound -> 4.440892098500626e-15
maxEncounteredError -> 1.250926201710214e-15
estimatedMean -> -1.0984634797115124e-18
estimatedStd -> 2.9607828266493842e-16

对于nOp = 100:

relativeErrorBound -> 2.220446049250313e-14
maxEncounteredError -> 2.1454964094158273e-15
estimatedMean -> -1.8768492273800676e-17
estimatedStd -> 6.529482793500846e-16

对于nOp = 500:

relativeErrorBound -> 1.1102230246251565e-13
maxEncounteredError -> 4.550696454362764e-15
estimatedMean -> 9.51007740905571e-17
estimatedStd -> 1.4766176010100097e-15

您可以观察到标准偏差增长比误差界限慢得多。

UPDATE:在第一个近似值(1+e)^m = 1+m*e+O((m*e)^2),所以只要m * e足够小,分布大约是[-e,e]中m均匀的总和,这个sum非常接近方差m*(2e)^2/12的正态分布(高斯)。您可以在Matlab中检查std(sum(rand(100,5000)))是否在sqrt(100/12)附近。

我们可以认为m=2*10^12-1仍然如此,大约是m=2^41m*e=2^-12。在这种情况下,全局误差是准正态分布,全局误差的标准偏差为sigma=(2^-52*sqrt(2^41/12))或大约sigma=10^-10

请参阅http://en.wikipedia.org/wiki/Normal_distribution计算P(abs(错误)&gt; k * sigma)

  • 在68%的情况下(1 sigma),你将拥有10位数或更多精度。
  • erfc(10/sqrt(2))为您提供精度小于9位的概率,大约1 * 6 * 10 ^ 22 的情况,所以我让你计算只有4的概率精度数字(你不能用双精度评估它,它下溢)!!!

我的实验标准偏差略小于理论标准差(2e-15 9e-16 4e-16适用于20 100&amp; 500 double)但这必须归因于我输入错误的偏差分配i / 3137 i = 1..10000 ...

这是一个很好的方法来提醒结果将由输入中的错误分布控制,如果它们是由M_PI * num / den

等浮点运算产生的,则可能超过e

另外,正如埃里克所说,仅使用*是一个非常理想的情况,如果你混合+,事情可能会更快地退化。

最后注意:我们可以制作一个达到最大误差范围的输入列表,将所有元素设置为(1 + e),将其四舍五入为1.0,并且我们得到最大理论误差界限,但是我们的输入分布很有偏见! HEM WRONG 因为所有乘法都是精确的,我们只得到(1 + e)^ n,而不是(1 + e)^(2n-1),所以大约只有一半错误...

更新2:反问题

既然你想要逆,那么序列的长度n是多少,这样我就可以得到具有一定置信水平的精确k位数10 ^ -c

我只会回答k>=8,因为上述近似值需要(m*e) << 1

我们取c=7,得到k位数,置信度为10 ^ -7表示5.3*sigma < 10^-k.
sigma = 2*e*sqrt((2*n-1)/12) n=0.5+1.5*(sigma/e)^2 e=2^-53。{。} 因此,n~3 * 2 ^ 105 * sigma ^ 2,如sigma ^ 2&lt; 10 ^ -2k / 5.3 ^ 2,我们可以写n < 3*2^105*10^-(2*k)/5.3^2

A.N。对于长度n = 4.3e12,小于k = 9位的概率小于10 ^ -7,对于10位数,大约n = 4.3e10。

我们将达到15位数的n = 4个数字,但是这里我们的正态分布假设是非常粗糙的并且不成立,特别是在5 sigmas的分布尾部,所以谨慎使用(Berry-Esseen定理界限与正常相距多远)这样的分发http://en.wikipedia.org/wiki/Berry-Esseen_theorem

答案 1 :(得分:2)

所描述的 M 操作中的相对错误最多为(1 + 2 -53 M -1,假设所有输入,中间和最终值都不下溢或溢出。

考虑将实数 a0 转换为双精度。结果是一些数字 a0 •(1 + e ),其中-2 -53 e ≤2 -53 (因为转换为双精度应始终产生最接近的可表示值,双精度值的量程为最高位的2 -53 ,且最接近的值总是在半个量子里)。为了进一步分析,我们将考虑 e ,2 -53 的最坏情况值。

当我们将一个(先前转换的)值乘以另一个时,数学上精确的结果是 a0 •(1 + e )• a1 •(1+ ë)。计算结果有另一个舍入误差,因此计算结果为 a0 •(1 + e )• a1 •(1+ < em> e )•(1 + e )= a0 a1 •(1 + e 3 。显然,这是(1+ e 3 的相对误差。我们可以看到错误累积为(1 + e M 这些操作:每个操作将所有先前的错误项乘以1+ < EM>电子

给定 N 输入,将有 N 次转换和 N -1次乘法,因此最差错误将是(1+ e 2 N - 1

仅在 N ≤1时才能实现此错误的等同性。否则,错误必须小于此限制。

请注意,只有在一个简单的问题中,例如具有同类操作的问题,才可能出现这种简单的错误。在典型的浮点运算中,通过加法,减法,乘法和其他运算的混合,通常不可能简单地计算约束。

对于 N = 10 12 M = 2•10 12 -1),上述界限小于2.000222062·10 12 单位的2 -53 ,并且小于.0002220693。因此,计算结果对四位十进制数字的结果是好的。 (但请记住,您需要避免溢出和下溢。)

(注意上述计算的严格性:我用Maple计算了二项式的1000项(1 + 2 -53 2•10 12 -1 (删除了最初的1个术语)并添加了一个可证明大于所有剩余项的总和的值。然后我让Maple将该确切结果评估为1000个十进制数字,并且它更少比我上面报道的那样。)

答案 2 :(得分:1)

对于64位浮点数,假设标准IEEE 754,有52 + 1位尾数。

这意味着相对精度在1.0000 ... 0和1.0000 ... 1之间,其中小数点后的二进制数字是52.(您可以将1.000 ... 0视为存储的内容尾数中的二进制AKA有效数字。)

误差是52的幂除以2(分辨率的一半)的1/2。注意我选择相对精度尽可能接近1.0,因为它是最坏的情况(否则在1.111..11和1.111..01之间,它更精确)。

在十进制中,双精度的最坏情况相对精度为1.11E-16。

如果将N个双精度乘以此精度,则新的相对精度(假设由于中间舍入而没有其他误差)为:

1 - (1 - 1.11E-16)^N

因此,如果你乘以pi(或任何双倍10 ^ 12)次数,错误的上限是:

1.1102e-004

这意味着你可以对大约4-5位数有信心。

如果CPU支持中间结果的扩展精度浮点数,则可以忽略中间舍入错误。

如果没有使用扩展精度FPU(浮点单元),则在中间步骤中进行舍入会引入额外的错误(与乘法相同)。这意味着严格的下限计算为:

1 -
((1 - 1.11E-16) * (1 - 1.11E-16) * (1 - 1.11E-16)
                * (1 - 1.11E-16) * (1 - 1.11E-16) % for multiplication, then rounding

               ... (another N-4 lines here) ...

                * (1 - 1.11E-16) * (1 - 1.11E-16))

= 1-(1-1.11E-16)^(N*2-1)

如果N太大,运行时间太长。可能的错误(中间舍入)是2.2204e-012,与没有中间舍入1-(1 - 1.11E-16)^N = 1.1102e-012相比,这是两倍。

大致上,我们可以说中间舍入会使错误加倍。

如果你将pi乘以10 ^ 12倍,并且没有扩展精度FPU。这可能是因为您在继续之前将内部步骤写入内存(并且可能做其他事情)(只是确保编译器没有重新排序您的指令以便没有FPU结果累积),然后是相对的严格上限错误是:

2.22e-004

请注意,小数点的置信度并不意味着它有时会完全是小数位。

例如,如果答案是:

1.999999999999,错误是1E-5,实际答案可能是2.000001234。

在这种情况下,即使是第一个十进制数字也是错误的。但这真的取决于你有多幸运(答案是否落在这样的边界上)。


此解决方案假设双打(包括答案​​)都已归一化。对于非规范化结果,很明显,它被非规范化的二进制数字将使精确度降低许多数字。