파이썬 numpy 기계 엡실론


103

나는 기계 입실론이 무엇인지 이해하려고 노력하고 있습니다. Wikipedia에 따르면 다음과 같이 계산할 수 있습니다.

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 % 확신을 가지기 위해 첫 번째는 고유 한 수레의 파이썬 "표준"정밀도를 제공하는 반면 두 번째는 numpy의 수레의 정밀도를 제공합니까?
Charlie Parker

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의 builtin의 별칭이기 때문에 대신 사용할 수 있습니다 float. Python float는 double거의 모든 플랫폼에서 64 비트 (C )입니다. floatnp.float64따라서 일반적으로 동등한 정밀도를 가지고 있고, 대부분의 목적을 위해 당신은 상호 교환 사용할 수 있습니다. 그러나 그들은 동일하지 않습니다 np.float64-numpy 특정 유형이며 np.float64스칼라는 네이티브 float스칼라 와 다른 방법을 가지고 있습니다. 예상대로 np.float3232 비트 부동 소수점입니다.
ali_m

92

엡실론을 얻는 또 다른 쉬운 방법은 다음과 같습니다.

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

4
예, 왜 8./3 - 5./3 - 1yield -eps, 4./3 - 1./3 - 10, 0을 10./3 - 7./3 - 1생성합니까?
Steve Tjoa

20
아, 답은 여기에 있습니다. 문제 3 : rstudio-pubs-static.s3.amazonaws.com/… 기본적으로 7/3에서 4/3의 이진 표현을 빼면 기계 엡실론의 정의를 얻게됩니다. 그래서 나는 이것이 모든 플랫폼에 적용되어야한다고 생각합니다.
Steve Tjoa 2015

13
이것은 엡실론을 찾는 numpy기존 numpy함수가 있을 때 Python 및 내부에 대한 너무 많은 지식이 필요한 답변에 대해 너무 난해합니다 .
Olga Botvinnik 2015 년

29
이 답변에는 Python 또는 numpy 내부에 대한 지식이 필요하지 않습니다.
GuillaumeDufay

5
실제로 독자가 기본 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

BTW 함수는 올릴 NameError경우의 조건 while아마 할 말이 그래서 첫 번째 검사에 만족하실 것입니다 machine_epsilon = machine_epsilon_last = func(1)첫 번째 문에
Azat Ibrakov을
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.