python numpy makinesi epsilon


103

Epsilon makinesinin ne olduğunu anlamaya çalışıyorum. Wikipedia'ya göre şu şekilde hesaplanabilir:

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

Ancak, yalnızca çift duyarlıklı sayılar için uygundur. Tek duyarlıklı sayıları da destekleyecek şekilde değiştirmekle ilgileniyorum. O numpy'nin kullanılabileceğini okudum, özellikle numpy.float32sınıf. İşlevi değiştirmeye kimse yardımcı olabilir mi?


8
Bu işlev, tüm hassasiyetlerle çalışacak kadar geneldir. İşleve numpy.float32argüman olarak a iletin!
David Zwicker

Yanıtlar:


192

Belirli bir şamandıra türü için makine epsilon'u elde etmenin daha kolay bir yolu şunu kullanmaktır np.finfo():

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

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

3
% 100 emin olmak için, birincisi doğuştan kayan noktaların python "standart" hassasiyetini sağlarken, ikincisi uyuşukluğun kaymasının doğruluğunu sağlar?
Charlie Parker

2
numpy'nin standart doğruluğunun 64 (64 bit bilgisayarda) olduğuna dikkat edin: >>> print(np.finfo(np.float).eps) = 2.22044604925e-16 ve >>> print(np.finfo(np.float64).eps) = 2.22044604925e-16
Charlie Parker

2
@CharlieParker Bunun np.floatyerine kullanabilirdim, çünkü bu sadece Python'un yerleşikinin bir takma adı float. Python kayar sayıları doubleneredeyse tüm platformlarda 64 bittir (C ). floatve np.float64bu nedenle genellikle eşdeğer hassasiyete sahiptir ve çoğu amaç için bunları birbirinin yerine kullanabilirsiniz. Ancak aynı değillerdir - np.float64numpy'ye özgü bir türdür ve bir np.float64skaler, yerel bir skalere göre farklı yöntemlere sahiptir float. Beklediğiniz gibi np.float32, 32 bitlik bir kayan nokta.
ali_m

92

Epsilon almanın başka bir kolay yolu şudur:

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

4
Evet, neden sonuç 8./3 - 5./3 - 1veriyor -epsve 4./3 - 1./3 - 1sıfır 10./3 - 7./3 - 1veriyor ve sıfır veriyor?
Steve Tjoa

20
Ah, cevap burada, Problem 3: rstudio-pubs-static.s3.amazonaws.com/… Temel olarak, 4 / 3'ün ikili gösterimini 7 / 3'ten çıkarırsanız, makine epsilon'un tanımını elde edersiniz. Bu yüzden bunun herhangi bir platform için geçerli olduğunu düşünüyorum.
Steve Tjoa

13
Bu, epsilon'u bulmak için numpymevcut bir numpyişlev varken Python ve dahili bilgiler hakkında çok fazla bilgi gerektiren bir cevap için çok ezoteriktir .
Olga Botvinnik

29
Bu cevap herhangi bir Python veya uyuşuk iç bilgisini gerektirmez.
GuillaumeDufay

5
Aslında, okuyucunun temel 3 hesaplamasını kullanmayan bilgisayarlarda çalışan Python'dan haberdar olduğunu iddia eder.
kokociel

17

David'in belirttiği gibi, zaten işe yarayacak!

>>> 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 İlk kontrolde NameErrorkoşul whileyerine machine_epsilon = machine_epsilon_last = func(1)
getirilirse işleviniz yükselir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.