python numpy机器epsilon


103

我试图了解什么是机器epsilon。根据维基百科,可以如下计算:

def machineEpsilon(func=float):
    machine_epsilon = func(1)
    while func(1)+func(machine_epsilon) != func(1):
        machine_epsilon_last = machine_epsilon
        machine_epsilon = func(machine_epsilon) / func(2)
    return machine_epsilon_last

但是,它仅适用于双精度数字。我有兴趣修改它以支持单精度数字。我读到可以使用numpy,尤其是numpy.float32类。有人可以帮助您修改功能吗?


8
该功能足以满足所有精度要求。只需将a numpy.float32作为参数传递给函数!
David Zwicker

Answers:


192

对于给定的float类型,获取机器epsilon的更简单方法是使用np.finfo()

print(np.finfo(float).eps)
# 2.22044604925e-16

print(np.finfo(np.float32).eps)
# 1.19209e-07

3
只是为了100%的自信,第一个提供了固有浮点数的python“标准”精度,而第二个提供了numpy浮点数的精度?
查理·帕克

2
请注意,numpy的标准精度为64(在64位计算机中): >>> print(np.finfo(np.float).eps) = 2.22044604925e-16>>> print(np.finfo(np.float64).eps) = 2.22044604925e-16
Charlie Parker

2
我可以用@CharlieParker np.float代替,因为它只是Python内置的别名floatdouble几乎所有平台上的Python浮点数都是64位(C )。floatnp.float64因此通常具有相当的精度,而对于大多数的目的,您可以互换使用。但是它们并不相同- np.float64是特定于numpy的类型,并且np.float64标量与本机float标量具有不同的方法。如您所料,np.float32是32位浮点数。
ali_m

92

获得epsilon的另一种简单方法是:

In [1]: 7./3 - 4./3 -1
Out[1]: 2.220446049250313e-16

4
是的,为什么8./3 - 5./3 - 1产生yield -eps4./3 - 1./3 - 1产生0,10./3 - 7./3 - 1产生0?
史蒂夫·乔阿

20
嗯,答案就在这里,问题3:rstudio-pubs-static.s3.amazonaws.com/…基本上,如果从7/3中减去4/3的二进制表示形式,则会得到机器epsilon的定义。因此,我认为这适用于任何平台。
史蒂夫·乔阿

13
这是一个过于深奥的答案,numpy当有一个现有的numpy函数来查找epsilon 时,就需要对Python和内部知识有足够的了解。
Olga Botvinnik

29
此答案不需要任何Python或numpy内部知识。
GuillaumeDufay

5
实际上,它断言读者已经意识到在未使用基础base-3计算的计算机上运行的Python。
kokociel

17

正如David指出的那样,它已经可以工作了!

>>> def machineEpsilon(func=float):
...     machine_epsilon = func(1)
...     while func(1)+func(machine_epsilon) != func(1):
...         machine_epsilon_last = machine_epsilon
...         machine_epsilon = func(machine_epsilon) / func(2)
...     return machine_epsilon_last
... 
>>> machineEpsilon(float)
2.220446049250313e-16
>>> import numpy
>>> machineEpsilon(numpy.float64)
2.2204460492503131e-16
>>> machineEpsilon(numpy.float32)
1.1920929e-07

顺便说一句,NameError如果while在第一次检查中满足条件,您的函数就会提高,因此machine_epsilon = machine_epsilon_last = func(1)在第一条语句中这样做很有意义
Azat Ibrakov
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.