python numpy machine epsilon


105

ฉันพยายามทำความเข้าใจว่า machine 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คลาส ใครสามารถช่วยแก้ไขฟังก์ชันได้หรือไม่?


8
ฟังก์ชั่นนั้นทั่วไปเพียงพอที่จะทำงานกับข้อ จำกัด ทั้งหมด เพียงแค่ส่งnumpy.float32เป็นอาร์กิวเมนต์ไปยังฟังก์ชัน!
David Zwicker

คำตอบ:


192

วิธีที่ง่ายกว่าในการรับเครื่อง epsilon สำหรับประเภทลูกลอยที่กำหนดคือการใช้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.floatแทนเพราะมันเป็นเพียงนามแฝงของ floatbuiltin Python float เป็น 64 บิต (C double) ในเกือบทุกแพลตฟอร์ม floatและnp.float64ดังนั้นจึงมักจะมีความแม่นยำเทียบเท่าและเพื่อวัตถุประสงค์มากที่สุดที่คุณสามารถใช้แทนกันได้ อย่างไรก็ตามมันไม่เหมือนกัน - np.float64เป็นประเภทที่เฉพาะเจาะจงเป็นตัวเลขและnp.float64สเกลาร์มีวิธีการที่แตกต่างไปจากfloatสเกลาร์ดั้งเดิม ตามที่คุณคาดหวังnp.float32คือโฟลต 32 บิต
ali_m

94

อีกวิธีง่ายๆในการรับ epsilon คือ:

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

4
ใช่แล้วทำไม8./3 - 5./3 - 1ให้ผล-epsและ4./3 - 1./3 - 1ให้ผลเป็นศูนย์และ10./3 - 7./3 - 1ให้ผลเป็นศูนย์?
Steve Tjoa

20
อ่าคำตอบอยู่ที่นี่ปัญหาที่ 3: rstudio-pubs-static.s3.amazonaws.com/…โดยพื้นฐานแล้วถ้าคุณลบการแทนค่าไบนารีของ 4/3 จาก 7/3 คุณจะได้คำจำกัดความของ machine epsilon ดังนั้นฉันคิดว่าสิ่งนี้ควรถือสำหรับแพลตฟอร์มใด ๆ
Steve Tjoa

13
นี่เป็นคำตอบที่ลึกลับเกินไปซึ่งต้องใช้ความรู้เกี่ยวกับ Python และnumpyinternals มากเกินไปเมื่อมีnumpyฟังก์ชันที่มีอยู่ในการค้นหา epsilon
Olga Botvinnik

30
คำตอบนี้ไม่จำเป็นต้องมีความรู้เกี่ยวกับ Python หรือ numpy internalals
GuillaumeDufay

6
อันที่จริงมันเป็นการยืนยันว่าผู้อ่านรับทราบเกี่ยวกับ Python ที่ทำงานบนคอมพิวเตอร์ที่ไม่ได้ใช้การคำนวณฐาน 3 พื้นฐาน
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.