python numpy机器epsilon

Bob*_*Bob 90 python numpy epsilon

我想了解什么是机器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
Run Code Online (Sandbox Code Playgroud)

但是,它仅适用于双精度数字.我有兴趣修改它以支持单精度数字.我读过numpy可以用,尤其是numpy.float32课堂.有人可以帮忙修改功能吗?

ali*_*i_m 166

获取给定浮点类型的机器epsilon的更简单方法是使用np.finfo():

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

print(np.finfo(np.float32).eps)
# 1.19209e-07
Run Code Online (Sandbox Code Playgroud)

  • 请注意,numpy 的标准精度是 64(在 64 位计算机中):`>>> print(np.finfo(np.float).eps) = 2.22044604925e-16` 和 `>>> print(np.finfo(np) .float64).eps) = 2.22044604925e-16` (3认同)
  • @CharlieParker 我本可以使用 `np.float` 代替,因为它只是 Python 内置 `float` 的别名。Python 浮点数在几乎所有平台上都是 64 位(C `double`)。`float` 和 `np.float64` 因此通常具有相同的精度,并且在大多数情况下,您可以互换使用它们。然而它们并不相同——`np.float64` 是一个 numpy 特定的类型,一个 `np.float64` 标量与原生 `float` 标量有不同的方法。如您所料,`np.float32` 是一个 32 位浮点数。 (3认同)
  • 只是为了100%自信,第一个提供了先天浮点数的python“标准”精度,而第二个提供了numpy浮点数的精度? (2认同)

小智 85

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

In [1]: 7./3 - 4./3 -1
Out[1]: 2.220446049250313e-16
Run Code Online (Sandbox Code Playgroud)

  • 这个答案不需要任何Python或numpy内部的知识. (23认同)
  • 啊,答案就在这里,问题3:http://rstudio-pubs-static.s3.amazonaws.com/13303_daf1916bee714161ac78d3318de808a9.html基本上,如果你从7/3中减去4/3的二进制表示,你会得到定义的机器epsilon.所以我认为这适用于任何平台. (19认同)
  • 这很有意思 - 你能详细说明为什么有效吗? (14认同)
  • 这是一个太深奥的答案,当需要有一个'numpy`函数来找到epsilon时,需要太多的Python和'numpy`内部知识. (11认同)
  • 这被投票的唯一原因是因为它很酷。但这是一个糟糕的答案。我希望没有代码库必须处理类似这样的事情。 (5认同)
  • 实际上,它声称读者了解在不使用底层base-3计算的计算机上运行的Python. (4认同)
  • 是的,为什么`8./3 - 5./3 - 1`产生`-eps`,而`4./3 - 1./3 - 1`产生零,和`10./3 - 7./3 - 1`产生零? (2认同)
  • 那应该是`abs(7./3-4./3-1-1)`,因为否则会在[ESP32微控制器]上获得`-1.192093e-07`(https://en.wikipedia.org/ Wiki / ESP32)。 (2认同)

Cla*_*diu 15

正如大卫指出的那样,它已经有效了!

>>> 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
Run Code Online (Sandbox Code Playgroud)