एक कम्प्यूटेशनल वैज्ञानिक को अपने स्वयं के संस्करण को लागू करने की आवश्यकता क्यों होगी :: जटिल?


14

कम्प्यूटेशनल साइंस जैसे Eigen , Trilinos , और deal.II में बेहतर ज्ञात C ++ पुस्तकालयों में से कई मानक std::complex<>फ्लोटिंग-पॉइंट संख्याओं का प्रतिनिधित्व करने के लिए मानक C ++ टेम्पलेट हेडर लाइब्रेरी ऑब्जेक्ट का उपयोग करते हैं।

जैक पॉल्सन के डिफॉल्ट कंस्ट्रक्टरों के बारे में एक सवाल के जवाब में , वह बताते हैं कि "कई कारणों से" एलीमेंटstd::complex में उनका अपना कार्यान्वयन है । वे कारण क्या हैं? इस दृष्टिकोण के फायदे और नुकसान क्या हैं?

जवाबों:


16

मेरा मानना ​​है कि पेट्सक सूची पर यह चर्चा कई बार सामने आई है। मेरे मुख्य कारण हैं:

  1. C ++ मानक में कहा गया है कि std :: complex को केवल float, double, और long double datatypes के लिए परिभाषित किया गया है। इस प्रकार इसका उपयोग अन्य डेटाटाइप्स के लिए नहीं किया जा सकता है, जैसे कि क्वाड-प्रिसिजन।

  2. मानक जटिल अंकगणित की स्थिरता के बारे में कोई गारंटी नहीं देता है।

  3. मानक इस बात की कोई गारंटी नहीं देता है कि डेटा std :: परिसर में वास्तविक घटक के रूप में संग्रहीत है और उसके बाद काल्पनिक घटक। यह बाहरी पुस्तकालयों जैसे BLAS और LAPACK के साथ इंटरफेस के लिए महत्वपूर्ण है। यह सभी प्रमुख कार्यान्वयनों के लिए सही है, लेकिन मैं इसे सुनिश्चित करने में सक्षम होना पसंद करूंगा।

  4. मैं वास्तविक और काल्पनिक घटकों में सीधे हेरफेर करने में सक्षम होना पसंद करता हूं। std :: complex इसे अनावश्यक रूप से कठिन बनाता है।

  5. मैं अंततः एक अधिक सामान्य संस्करण रखना चाहूंगा, जिसमें केवल फ़ील्ड की आवश्यकता के बजाय डेटाटाइप को एक अंगूठी की आवश्यकता होती है। इसमें गाऊसी पूर्णांक शामिल होंगे।


6
बिंदु 3 को C ++ 11 में संबोधित किया गया है। 26.4.4 कहा गया है कि यदि zप्रकार का एक lvalue अभिव्यक्ति है सीवी std::complex<T> तो reinterpret_cast<cv T(&)[2]>(z)और reinterpret_cast<cv T(&)[2]>(z)[0]का असली हिस्सा नामित करेगा z, और reinterpret_cast<cv T(&)[2]>(z)[1]के काल्पनिक भाग नामित करेगा z। जटिल संख्याओं की सरणियों को भी संबोधित किया जाता है।
जेम्स कस्टर

3
@JamesCuster: मैं अंततः C ++ 11 पर स्विच करने के लिए हूं, लेकिन वैज्ञानिक कोड जो अर्ध-विदेशी आर्किटेक्चर के लिए पोर्टेबल रहना चाहते हैं, उन्हें ऐसा करने के लिए संभवतः कम से कम दो से तीन और वर्षों तक इंतजार करना होगा। साथ ही, C ++ 11 दुर्भाग्य से केवल समस्या का हिस्सा है।
जैक पॉल्सन

मैं समझता हूं, मैं इसे सिर्फ इसलिए बाहर फेंक रहा था जब कोई भविष्य में इस प्रश्न को देखता है।
जेम्स कस्टर

2
खैर, मुझे लगता है कि यह कहना है कि आपको C ++ 11 का समर्थन करने तक इंतजार करना होगा। स्पष्ट आवश्यकता को नए मानक में डाल दिया गया था क्योंकि सभी मौजूदा कार्यान्वयन पहले से ही इसका समर्थन करते हैं। मैं एक ऐसे मामले के बारे में नहीं सोच सकता जहाँ यह पहले से ही मौजूद संकलकों / पुस्तकालयों में इस विशेष लेआउट को ग्रहण करने के लिए असुरक्षित होगा क्योंकि यह एसटीडी को लागू करने का कोई मतलब नहीं होगा :: किसी अन्य तरीके से जटिल।
वुल्फगैंग बंगर्थ

1
@WolfgangBangerth: C ++ 11 पर स्विच करने पर यह एक सामान्य टिप्पणी थी। किसी भी तरह से, C ++ 11 std :: complex के साथ अधिकांश समस्याओं को ठीक नहीं करता है।
जैक पॉल्सन

7

मैं std::complex<>अपने कार्यक्रमों में उपयोग करता हूं, और प्रत्येक नए संकलक या संकलक उन्नयन के लिए संकलक झंडे और वर्कअराउंड के साथ लड़ना पड़ता है। मैं कालानुक्रमिक क्रम में इन झगड़ों को याद करने की कोशिश करूंगा:

  1. std::norm|z|2|z|-ffast-math
  2. लाइनक्स (या लिंकर) पर इंटेल आईसीसी कंपाइलर std::argकुछ कॉन्फ़िगरेशन (एक विशिष्ट जीसी-संस्करण के साथ लिंक संगतता) के तहत एक गैर-ऑप्ट करने के लिए संकलित किया गया है। समस्या बहुत बार std::argबदल गई , इसलिए इसे प्रतिस्थापित करना पड़ा atan2(imag(),real())। लेकिन नया कोड लिखते समय यह सब भूलना बहुत आसान था।
  3. प्रकार std::complexबिल्ट-इन C99 कॉम्प्लेक्स प्रकार की तुलना में अलग कॉल कन्वेंशन (= ABI) का उपयोग करता है, और नए gcc संस्करणों के लिए अंतर्निहित फोरट्रान कॉम्प्लेक्स प्रकार।
  4. -ffast-mathअप्रत्याशित तरीके से बिंदु अपवाद चल की हैंडलिंग के साथ संकलन ध्वज का आदान प्रदान। क्या होता है कि संकलक विभाजनों को छोरों से बाहर खींचता है, जिससे division by zeroरनटाइम पर अपवाद होता है। ये अपवाद लूप के अंदर कभी नहीं हुए होंगे, क्योंकि आसपास के तर्क के कारण संबंधित विभाजन नहीं हुआ था। यह वास्तव में बुरा था, क्योंकि यह एक पुस्तकालय था जिसे प्रोग्राम से अलग करके संकलित किया गया था जो फ्लोटिंग पॉइंट अपवाद हैंडिंग (विभिन्न संकलित झंडे का उपयोग करते हुए) का उपयोग करता था और इन मुद्दों में चलता था (इसी टीम दुनिया के विपरीत हिस्सों में बैठे थे, इसलिए इस मुद्दे ने वास्तव में बुरी परेशानी पैदा की)। यह संकलक द्वारा उपयोग किए गए अनुकूलन को अधिक सावधानी से हाथ से हल किया गया था।
  5. पुस्तकालय कार्यक्रम का हिस्सा बन गया और अब -ffast-mathसंकलन ध्वज का उपयोग नहीं किया गया । नए gcc संस्करण में अपग्रेड के बाद, प्रदर्शन एक विशाल कारक द्वारा गिरा दिया गया। मैंने अभी तक इस मुद्दे की विस्तार से जांच नहीं की है, लेकिन मुझे डर है कि यह C99 अनुलग्नक G से संबंधित है । मुझे स्वीकार करना होगा कि मैं जटिल संख्याओं के लिए गुणा की इस अजीब परिभाषा से पूरी तरह से भ्रमित हूं, और यहां तक ​​कि इसके विभिन्न संस्करणों का दावा करने के लिए मौजूद है कि अन्य संस्करणों को गुमराह किया गया है। मुझे उम्मीद है कि -fcx-limited-rangeसंकलन ध्वज इस मुद्दे को हल करेगा, क्योंकि -ffast-mathइस नए gcc संस्करण के लिए इससे संबंधित एक और समस्या प्रतीत होती है ।
  6. -ffast-mathसंकलन ध्वज के व्यवहार करता है NaNजीसीसी के नए संस्करणों के लिए पूरी तरह से अप्रत्याशित (यहां तक कि isnanप्रभावित होता है)। NaNकार्यक्रम में किसी भी घटना से बचने के लिए एकमात्र समाधान दिखता है , जो अस्तित्व के उद्देश्य को पराजित करता है NaN

अब आप पूछ सकते हैं कि क्या मैं अंतर्निहित जटिल प्रकारों को छोड़ने के std::complexलिए और इन कारणों से योजना बना रहा हूं । मैं अंतर्निहित प्रकारों के साथ रहूंगा, जब तक मैं C ++ के साथ रहता हूं। मामले में C ++ को वैज्ञानिक कंप्यूटिंग के लिए पूरी तरह से अनुपयोगी बनने का प्रबंधन करना चाहिए, मैं इसके बजाय एक ऐसी भाषा पर स्विच करने पर विचार करूंगा जो वैज्ञानिक कंप्यूटिंग के लिए प्रासंगिक मुद्दों का अधिक ध्यान रखे।


ऐसा लगता है कि C99 अनुलग्नक G से संबंधित मेरी आशंकाएं सच हो गई हैं, और -fcx-limited-range अब जटिल संख्याओं को गुणा करते समय सभ्य गणना की गति के लिए आवश्यक है। : कम से कम है कि मैं क्या निम्नलिखित हाल युद्ध कहानी से मिलता है medium.com/@smcallis_71148/...
थॉमस Klimpel
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.