【问题标题】:python numpy machine epsilonpython numpy机器epsilon
【发布时间】:2013-10-09 02:28:31
【问题描述】:

我想了解什么是机器 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 类。有人可以帮忙修改功能吗?

【问题讨论】:

  • 该函数足够通用,可以处理所有精度。只需将 numpy.float32 作为参数传递给函数!

标签: python numpy epsilon


【解决方案1】:

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

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

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

【讨论】:

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

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

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

【讨论】:

  • 是的,为什么8./3 - 5./3 - 1 产生-eps4./3 - 1./3 - 1 产生零,而10./3 - 7./3 - 1 产生零?
  • 啊,答案就在这里,问题3:rstudio-pubs-static.s3.amazonaws.com/…基本上,如果你从7/3中减去4/3的二进制表示,你就会得到机器ε的定义。所以我想这应该适用于任何平台。
  • 当有一个现有的 numpy 函数来查找 epsilon 时,这个答案需要太多的 Python 知识和 numpy 内部知识。
  • 这个答案不需要任何 Python 或 numpy 内部知识。
  • 确实,它断言读者知道 Python 在不使用底层 base-3 计算的计算机上运行。
【解决方案3】:

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

>>> 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

【讨论】:

  • 顺便说一句,如果while 中的条件在第一次检查时满足,您的函数将引发NameError,因此在第一个语句中执行machine_epsilon = machine_epsilon_last = func(1) 可能是有意义的
猜你喜欢
  • 2016-04-09
  • 2015-04-06
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 2011-02-06
  • 2015-02-15
  • 1970-01-01
  • 2012-03-20
相关资源
最近更新 更多