時間:2019-02-09 09:18:39.0ラベル:python numpy machine epsilon


103

マシンイプシロンとは何かを理解しようとしています。ウィキペディアによると、次のように計算できます。

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
その関数は、すべての精度で機能するのに十分一般的です。numpy.float32関数に引数としてa を渡すだけです!
David Zwicker 2013年

回答:


192

特定のfloat型のマシンイプシロンを取得する簡単な方法は、次のようにすることnp.finfo()です。

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

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

3
100%の自信を持たせるために、最初のものはpythonの「標準的な」浮動小数点の精度を提供し、2番目は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.floatPythonの組み込みの単なるエイリアスであるため、代わりに使用することもできますfloat。Python floatはdouble、ほとんどすべてのプラットフォームで64ビット(C )です。floatnp.float64したがって、通常は同等の精度を持っており、ほとんどの目的のために、あなたは、互換的に使用することができます。ただし、それらは同一ではありませんnp.float64-numpy固有の型であり、np.float64スカラーにはネイティブfloatスカラーとは異なるメソッドがあります。ご想像のとおりnp.float32、32ビット浮動小数点です。
ali_m 2017年

92

イプシロンを取得する別の簡単な方法は次のとおりです。

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

4
ええ、なぜ8./3 - 5./3 - 1yield -eps4./3 - 1./3 - 1ゼロ、yield になるの10./3 - 7./3 - 1ですか?
スティーブTjoa

20
ああ、答えはここにあります。問題3:rstudio-pubs-static.s3.amazonaws.com/…基本的に、7/3から4/3のバイナリ表現を引くと、マシンイプシロンの定義が得られます。したがって、これはどのプラットフォームにも当てはまるはずです。
Steve Tjoa

13
これは、イプシロンを見つけるためのnumpy既存のnumpy関数がある場合、Pythonと内部についての知識が多すぎるため、答えが難解です。
Olga Botvinnik、2015年

29
この答えはPythonやnumpyの内部についての知識を必要としません。
GuillaumeDufay

5
確かに、それは、基礎となるbase-3計算を使用していないコンピューターで実行されているPythonについて読者が知っていると断言します。
kokociel

17

デビッドが指摘したように、それはすでに機能します!

>>> 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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.