फोरट्रान पायथागोरियन त्रिकोणमितीय पहचान कई बार काम नहीं कर रही है

मैं कोडब्लॉक्स + जीएनयू फोरट्रान का उपयोग कर रहा हूं।

समस्या यह है कि मेरे पास गणनाएं हैं:

SQRT(1-COS*COS)

और जब मैं इन गणनाओं को बहुत कुछ करता हूं (कुछ मिलियन बार) कभी-कभी वर्ग रूट के नीचे मान नकारात्मक होता है और इसलिए मुझे नतीजे मिलते हैं।

मेरे प्रयासों से पता चला है कि जब वर्ग रूट की गणना ऋणात्मक संख्या के लिए की जाती है तो सीओएस "-1" के बराबर होती है। इसलिए, फोर्ट्रान की गणना -1 * -1 गलत है क्योंकि वर्ग रूट के नीचे 0 होना चाहिए लेकिन ऐसा नहीं है।

क्या इस समस्या को हल करने का कोई तरीका है? यह न केवल पायथागोरियन त्रिकोणमितीय पहचान से संबंधित है, बल्कि स्क्वायर रूट के नीचे कुछ भी दिख रहा है

SQRT(1-x*x)

एक्स के साथ [-1,1] की सीमा में है।

मूल रूप से लागत को मेरे कार्यक्रम में इस तरह परिभाषित किया जाता है (मैं स्वयं को लागत से पहले कुछ हद तक लंबे समय तक परिचय के लिए क्षमा चाहता हूं लेकिन यह है कि यह कैसे जाता है):

XDET = 0.
YDET = 0.
ZDET = 50.
RADIUS = 1.

x = RADIUS*sqrt(omega)  !omega=random number in uniform distribution [0,1]
y = 0.
z = 1.E-20

DW=SQRT((XDET-X)**2+(YDET-Y)**2+(ZDET-Z)**2)
DWW = 1./DW
AN2=(ZDET-Z)*DWW

COST = AN2
if(COST > 1. ) COST = 1.
if(COST < -1.) COST = -1.
SINT = SQRT(1.-COST*COST)

वैसे, एएन 2 कभी-कभी एक पूर्ण शून्य मानता है जो इससे पहले कि मैं इसे फंसाने से पहले NaNs का नेतृत्व करता हूं।

अनुलेख मेरे पास एक्सपी (एक्स) की एक बग भी है जिसमें एक्स 9 की तुलना में एक्स से अधिक है।

0
उच्च प्रदर्शन चिह्न, कोड अंश के लिए संपादित पोस्ट देखें।
जोड़ा लेखक Arthmost, स्रोत
ज़ियाओली झू, मुझे बेवकूफ सवाल के लिए खेद है, लेकिन अगर मैं कोडब्लॉक्स के साथ स्थापित किया गया तो मैं अपने gfortran संस्करण को कैसे निर्धारित करूं?
जोड़ा लेखक Arthmost, स्रोत
आप कितने निश्चित हैं | COS | 1.0 से अधिक कभी नहीं हो सकता है?
जोड़ा लेखक Ignacio Vazquez-Abrams, स्रोत
हमें अपना कोड दिखाएं। जैसा कि यह अभिव्यक्ति <कोड> एसक्यूआरटी (1-सीओएस * सीओएस) को सफलतापूर्वक पार्स किया जा सकता है यदि COS एक चर का नाम है, तो यह आंतरिक फ़ंक्शन पर कॉल नहीं है <कोड> सीओएस , न ही किसी अन्य समारोह के लिए। जबकि AlexanderVogt सही लाइनों पर हो सकता है, मैं निर्णय आरक्षित कर रहा हूँ।
जोड़ा लेखक High Performance Mark, स्रोत
क्या आप कृपया अपने gfortran संस्करण और ओमेगा के मूल्य निर्दिष्ट कर सकते हैं जिससे समस्या उत्पन्न हुई? मैंने 1000 यादृच्छिक संख्याओं का परीक्षण किया लेकिन उस समस्या को पुन: उत्पन्न करने में सक्षम नहीं हुए हैं।
जोड़ा लेखक Xiaolei Zhu, स्रोत
टर्मिनल में gfortran --version करना चाहिए। omega का मान अधिक उपयोगी है।
जोड़ा लेखक Xiaolei Zhu, स्रोत

2 उत्तर

मेरा अनुमान यह होगा कि यह फ्लोटिंग पॉइंट नंबरों की सीमित परिशुद्धता के कारण होगा। यहां एक नज़र डालें: फ़्लोटिंग-पॉइंट के बारे में प्रत्येक कंप्यूटर वैज्ञानिक को क्या पता होना चाहिए अंकगणित

सरल समाधान:

xx = x*x
if ( xx .gt. 1.e0 ) xx = 1.e0 ! 1.d0 for double precision

y = sqrt( 1.e0 - xx ) ! Again, 1.d0 for double precision

या, एक लाइनर के रूप में:

 y = sqrt( 1.e0 - min( x*x, 1.e0 ) )
0
जोड़ा
मार्क सही है। इसके अलावा पूर्णांक मूल्यवान वास्तविक चर के लिए अंकगणित आमतौर पर सटीक होता है।
जोड़ा लेखक Vladimir F, स्रोत
कोसाइन के डोमेन को छोड़कर [-1.0, 1.0] है, जिसे स्क्वायर किया जाना चाहिए, जिसके परिणामस्वरूप [0.0, 1.0] का डोमेन हो सकता है। समारोह में नकारात्मक तर्क की कोई संभावना नहीं होनी चाहिए।
जोड़ा लेखक Ignacio Vazquez-Abrams, स्रोत

आपके पीएस को बग के रूप में पहचानने के लिए स्पष्टीकरण सरल है

exp(90.0) > 3.4028235 x 10^38

और <कोड> 3.4028235 x 10 ^ 38 सबसे बड़ा सकारात्मक संख्या है जो एकल-परिशुद्धता फ़्लोटिंग-पॉइंट नंबर किसी भी सटीकता के साथ प्रतिनिधित्व कर सकता है।

यह विश्लेषण, ज़ाहिर है, मान लें कि आपका चर x एक आईईईई 32-बिट फ्लोटिंग-पॉइंट नंबर है।

ध्यान दें, अभिव्यक्ति ZDET-Z एकल-परिशुद्धता में कभी भी नहीं होगी, 1.0 से अलग हो। 1.0 - 1.0e-20 == 0.9999999999999999999 लेकिन इसका प्रतिनिधित्व करने से सटीक सटीकता से अधिक है और संख्या 1.0 पर गोल है।

जबकि मैं अभी भी नहीं देख सकता कि कैसे <कोड> 1.-लागत * लागत नकारात्मक होगा, फ्लोटिंग-पॉइंट अंकगणित का उपयोग मुझे यह आश्वस्त नहीं कर रहा है कि कोड के उन हिस्सों में सूक्ष्म गलतियां नहीं हैं आपने हमें नहीं दिखाया है

0
जोड़ा
हाँ, मैं एक ही निष्कर्ष पर आया हूं जब मैंने माना कि वास्तव में कितना विस्तार (9 0+) है। धन्यवाद।
जोड़ा लेखक Arthmost, स्रोत
खैर, मैं वास्तव में एफ-पी अंकगणित पर एक महान विशेषज्ञ नहीं हूं, विशेष रूप से यह मानते हुए कि मेरे वैज्ञानिक पर्यवेक्षक द्वारा मेरे अधिकांश वैज्ञानिक कोड को करने में सक्षम होने के लिए कोड प्रदान किया गया था। यदि आप यह निर्दिष्ट कर सकते हैं कि प्रोग्राम को और अधिक स्थिर बनाने के लिए मुझे क्या सही करना चाहिए, तो मैं खुशी से ऐसा करूँगा क्योंकि मैं कोड में यहां और वहां चीजों को ठीक कर रहा हूं क्योंकि मैं फोरट्रान के बारे में और जानता हूं।
जोड़ा लेखक Arthmost, स्रोत
यदि आप पहले से नहीं हैं, तो आपको फ्लोटिंग-पॉइंट पर विकिपीडिया लेख से परिचित होना चाहिए। पेपर जिस पर अलेक्जेंडर वोगेट आपको इंगित करता है, जिसे अक्सर इंगित किया जाता है, अत्यधिक तकनीकी है और शायद इस विषय पर पहले अच्छा नहीं पढ़ा जाता है। एक बार जब आप समझते हैं कि विकिपीडिया आपको क्या बताता है, तो इस संबंध में फोरट्रान की क्षमताओं के बारे में जानें। संख्यात्मक <कोड> प्रकार की परिभाषा और उपयोग पर विशेष ध्यान दें। संख्यात्मक गणना पर एक पाठ का अध्ययन करें, मुझे हैमिंग की पुस्तक वैज्ञानिकों और इंजीनियरों के लिए संख्यात्मक तरीके पसंद है लेकिन कई अन्य हैं।
जोड़ा लेखक High Performance Mark, स्रोत
आप (वैज्ञानिक) गणित की अच्छी समझ के बिना फ्लोटिंग-पॉइंट नंबरों और अंकगणित की अच्छी समझ के बिना अपने वैज्ञानिक कार्य नहीं कर सकते हैं।
जोड़ा लेखक High Performance Mark, स्रोत