2013-09-05 6 views
13

क्या कोई जानता है कि नीचे 0 के बराबर क्यों नहीं है?पाइथन और numpy का उपयोग करते समय पाप (180) शून्य क्यों नहीं है?

import numpy as np 
np.sin(np.radians(180)) 

या:

np.sin(np.pi) 

जब मैं यह अजगर में प्रवेश यह मेरे 1.22e -16 देता है।

+7

फ़्लोटिंग पॉइंट राउंडिंग त्रुटि। – Keith

+3

पीआई को फ्लोटिंग पॉइंट नंबर के रूप में बिल्कुल प्रदर्शित नहीं किया जा सकता है, इसलिए 'पाप (पीआई)' बिल्कुल शून्य नहीं होने वाला है। – Blender

+0

क्या कोई फिक्स है या क्या मुझे इसे int में बदलने की ज़रूरत है? – MCF

उत्तर

13

संख्या π को एक फ़्लोटिंग-पॉइंट नंबर के रूप में बिल्कुल प्रदर्शित नहीं किया जा सकता है। तो, np.radians(180) आपको π नहीं देता है, यह आपको 3.1415926535897931 देता है।

और sin(3.1415926535897931) वास्तव में 1.22e-16 जैसा कुछ है।

तो, आप इससे कैसे निपटते हैं?

आप बाहर काम करने के लिए है, या कम से कम उचित निरपेक्ष और/या रिश्तेदार त्रुटि सीमा पर, लगता है, और फिर x == y के बजाय, आप लिखें:

abs(y - x) < abs_bounds and abs(y-x) < rel_bounds * y 

(यह भी मतलब है कि आप को व्यवस्थित करने के लिए है कि अपने गणना ताकि रिश्तेदार त्रुटि, x करने से y को बड़ा सापेक्ष है। आपके मामले में क्योंकि y निरंतर 0 है, कि तुच्छ-बस इसे पिछड़े करते हैं।)

Numpy एक समारोह है कि भर में आप के लिए यह करता है प्रदान करता है एक पूरी सरणी, allclose:

np.allclose(x, y, rel_bounds, abs_bounds) 

(यह वास्तव में abs(y - x) < abs_ bounds + rel_bounds * y) की जाँच करता है, लेकिन यह लगभग हमेशा पर्याप्त है, और जब यह नहीं है आप आसानी से अपने कोड का पुनर्गठन कर सकते हैं।)

आपके मामले में:

np.allclose(0, np.sin(np.radians(180)), rel_bounds, abs_bounds) 

तो, आप कैसे जानते हैं कि सही सीमाएं क्या हैं? SO SO में आपको पर्याप्त त्रुटि विश्लेषण सिखाने का कोई तरीका नहीं है। विकिपीडिया पर Propagation of uncertainty एक उच्च स्तरीय अवलोकन प्रदान करता है। यदि आपके पास वास्तव में कोई सुराग नहीं है, तो आप डिफ़ॉल्ट का उपयोग कर सकते हैं, जो 1e-5 रिश्तेदार और 1e-8 पूर्ण हैं।

+2

मुझे वास्तव में त्रुटि विश्लेषण का अच्छा ज्ञान है इसलिए यह बहुत उपयोगी है। – MCF

+2

इस विशेष स्थान में त्रुटि लगभग np.radians (180) में त्रुटि के बराबर होगी।यह त्रुटि शायद 0.5 से 1.0 यूएलपी (अंतिम स्थान पर इकाइयां), या लगभग 3.14 * डीबीएल_ईपीएसआईएलओएन, या लगभग 7e-16 है। मेरा त्रुटि अनुमान सबसे खराब मामला अनुमान था इसलिए यह आश्चर्य की बात नहीं है कि वास्तविक त्रुटि थोड़ा छोटा है। इस लेख को गोरो विवरण के लिए देखें (और इस विचार को वास्तव में कितना आश्चर्यजनक रूप से अच्छा लगता है): https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by- 1-3-क्विंटिलियन/ –

-3

समस्या यह पीआई की एक गोल त्रुटि नहीं है। ध्यान दें कि समस्या कोज्या के लिए दिखाई नहीं देते:

In [2]: np.sin(np.pi) 
    Out[2]: 1.2246467991473532e-16 != 0. 
    In [3]: np.cos(np.pi) 
    Out[3]: -1.0     == -1. 

समस्या भी बहुत कुछ ... जटिल है। यह प्रोसेसर के अंदर पीआई की परिशुद्धता से संबंधित है। यह यहां खोजा गया और समझाया गया: https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/

+1

सिवाय इसके कि उस लेख के रूप में (मेरा आलेख, जैसा कि यह पता चला है) बताता है कि पीआई की गोल करने वाली समस्या इस मुद्दे का एक बड़ा हिस्सा है। यदि पाप (डबल (पीआई) शून्य शून्य देता है तो आपका पाप फ़ंक्शन टूट जाता है। लेख में जो बग इंगित करता है वह यह है कि कुछ मशीनों पर पाप (डबल (पीआई)) * गलत * गैर-शून्य संख्या देता है। कॉस काम करता है क्योंकि त्रुटि 1.0 के लिए सटीकता की दहलीज से नीचे है, जो कैलकुस से संबंधित है (कोस (पीआई) की ढलान शून्य है, पाप की ढलान (पीआई) एक है और उत्तर की परिमाण है। –

संबंधित मुद्दे