Raku का उपयोग कर ई संख्या की गणना


9

मैं सूत्र की गणना करके स्थिर ( AKA Euler की संख्या ) की गणना करने की कोशिश कर रहा हूंइ

एक शॉट में भाज्य और विभाजन की गणना करने के लिए, मैंने यह लिखा:

my @e = 1, { state $a=1; 1 / ($_ * $a++) } ... *;
say reduce  * + * , @e[^10];

लेकिन यह काम नहीं किया। इसे सही तरीके से कैसे करें?


किस तरह से किया: "यह काम नहीं किया"?
शेरलहोमन

1
नमूना कोड में भाजक भाग बाहर काम नहीं किया क्योंकि यह पिछले $_ निर्माण चर का उपयोग कर रहा था , इस तथ्य के निर्माण के प्रयास में। यह स्पष्ट रूप से बेमानी था। नीचे दिए गए सही समाधान में, $_इसे गिरा दिया गया और इसने पूरी तरह से काम किया।
लार्स माल्मस्टीन

धन्यवाद। मुझे लगता है, मैं उस कथन के लिए वास्तव में क्या चाहता था के लिए और अधिक देख रहा था। जैसे कोई त्रुटि थी, आप जिस चीज की उम्मीद कर रहे थे, उस तरह की कोई संगत नहीं थी। मुझे लगता है, आपकी गणना उस गणना के लिए ज्ञात उत्तरों से मेल नहीं खाती। खुशी है कि आप इसे बाहर काम किया !! इसके अलावा, वास्तविक समस्या के रूप में महान उत्तर-उत्तर का वर्णन :-)
शेरिलहोमन

जवाबों:


11

मैं अनुभाग में अपने कोड का विश्लेषण अपने कोड का विश्लेषण करना । इससे पहले मैं बोनस सामग्री के कुछ मजेदार खंड प्रस्तुत करता हूं।

वन लाइनर वन लेटर 1

say e; # 2.718281828459045

"कई तरीकों पर एक ग्रंथ" 2

eRaku में कंप्यूटिंग पर डेमियन कॉनवे के असाधारण लेख को देखने के लिए उपरोक्त लिंक पर क्लिक करें ।

लेख बहुत मजेदार है (आखिरकार, यह डेमियन है)। यह कंप्यूटिंग के बारे में बहुत समझने योग्य चर्चा है e। और यह राकू के बाइकार्बोनेट पुनर्जन्म का एक श्रद्धांजलि है जो लारियल वाल द्वारा जासूसी की गई TIMTOWTDI दर्शन का पुनर्जन्म है। 3

क्षुधावर्धक के रूप में, यहाँ लेख के माध्यम से लगभग आधे रास्ते से एक उद्धरण है:

यह देखते हुए कि ये कुशल विधियाँ सभी तरह से काम करती हैं- संक्षेप में (प्रारंभिक उपसमुच्चय) शब्दों की एक अनंत श्रृंखला है - शायद यह बेहतर होगा यदि हमारे पास ऐसा करने के लिए कोई फ़ंक्शन हो। और यह निश्चित रूप से बेहतर होगा यदि फ़ंक्शन अपने आप से काम कर सकता है, तो श्रृंखला के उस प्रारंभिक उपसमुच्चय का वास्तव में कितना सटीक उत्तर देने के लिए शामिल करने की आवश्यकता है ... बजाय मैन्युअल रूप से परिणाम के माध्यम से कंघी करने की आवश्यकता के कई परीक्षणों की खोज करने के लिए।

और, इतनी बार Raku में, यह आश्चर्यजनक रूप से आसान बनाने के लिए बस हमें क्या चाहिए:

sub Σ (Unary $block --> Numeric) {
  (0..∞).map($block).produce(&[+]).&converge
}

अपने कोड का विश्लेषण

यहां पहली पंक्ति है, श्रृंखला उत्पन्न करना:

my @e = 1, { state $a=1; 1 / ($_ * $a++) } ... *;

बंद ( { code goes here }) एक शब्द की गणना करता है। एक क्लोजर में एक हस्ताक्षर है, या तो निहित या स्पष्ट है, यह निर्धारित करता है कि यह कितने तर्क स्वीकार करेगा। इस मामले में कोई स्पष्ट हस्ताक्षर नहीं है। $_( "विषय" चर ) के उपयोग से एक निहित हस्ताक्षर होता है जिसके लिए एक तर्क की आवश्यकता होती है $_

अनुक्रम ऑपरेटर ( ...) बार-बार अपने बाईं ओर बंद होने को बुलाता है, पिछले शब्द को क्लोजर के तर्क के रूप में पारित करता है, आलसी रूप से अपने दाईं ओर समापन बिंदु तक शर्तों की एक श्रृंखला का निर्माण करने के लिए , जो इस मामले में उर्फ अनन्तता के *लिए आशुलिपि है Inf

बंद करने के लिए पहली कॉल में विषय है 1। इसलिए क्लोजर गणना करता है और 1 / (1 * 1)श्रृंखला में पहले दो शब्दों की उपज देता है 1, 1/1

दूसरी कॉल में विषय पिछले एक का मूल्य है 1/1, अर्थात 1फिर से। तो समापन गणना और रिटर्न 1 / (1 * 2), श्रृंखला को विस्तारित करता है 1, 1/1, 1/2। यह सब अच्छा लग रहा है।

अगला क्लोजर कम्प्यूट करता है 1 / (1/2 * 3)जो है 0.666667। वह पद होना चाहिए 1 / (1 * 2 * 3)। उफ़।

अपने कोड को सूत्र से मिलान करना

आपका कोड सूत्र से मेल खाने वाला है:
इ

इस सूत्र में, प्रत्येक पद की गणना श्रृंखला में उसकी स्थिति के आधार पर की जाती है । कश्मीर वें श्रृंखला (जहां में अवधि कश्मीर = 0 पहले के लिए 1) केवल भाज्य है कश्मीर की पारस्परिक।

(तो यह कोई लेना देना नहीं मिला है मूल्य पहले कार्यकाल के। इस प्रकार $_, जो प्राप्त करता है मूल्य पहले कार्यकाल के, बंद में नहीं किया जाना चाहिए।)

आइए एक फैक्टोरियल पोस्टफ़िक्स ऑपरेटर बनाएं:

sub postfix:<!> (\k) { [×] 1 .. k }

( ×एक इन्फिक्स मल्टीप्लोरेशन ऑपरेटर है, जो कि एक सामान्य ASCII इन्फिनिटी का यूनिकोड उर्फ देख रहा है *।)

इसके लिए आशुलिपि है:

sub postfix:<!> (\k) { 1 × 2 × 3 × .... × k }

(मैंने आवश्यकतानुसार कई शब्दों को जोड़ने या घटाने के विचार को दर्शाने के लिए ब्रेसिज़ के अंदर छद्म मेटासाइनेटिक संकेतन का उपयोग किया है।

अधिक आम तौर पर, opएक अभिव्यक्ति की शुरुआत में वर्ग कोष्ठक में एक infix ऑपरेटर डालने से एक समग्र उपसर्ग ऑपरेटर बनता है जो इसके बराबर होता है reduce with => &[op],। अधिक जानकारी के लिए रिडक्शन मेटाऑपरेटर देखें ।

अब हम नए फैक्टरियल पोस्टफिक्स ऑपरेटर का उपयोग करने के लिए बंद को फिर से लिख सकते हैं:

my @e = 1, { state $a=1; 1 / $a++! } ... *;

बिंगो। यह सही श्रृंखला का निर्माण करता है।

... जब तक ऐसा नहीं होता, एक अलग कारण से। अगली समस्या संख्यात्मक सटीकता है। लेकिन इससे अगले भाग में बात करते हैं।

आपके कोड से प्राप्त एक लाइनर

हो सकता है कि तीन पंक्तियों को एक में संकुचित करें:

say [+] .[^10] given 1, { 1 / [×] 1 .. ++$ } ... Inf

.[^10]उस विषय पर लागू होता है, जो इसके द्वारा निर्धारित होता है given। (इसके ^10लिए शॉर्टहैंड है 0..9, इसलिए उपरोक्त कोड श्रृंखला में पहले दस शब्दों के योग की गणना करता है।)

मैंने $aक्लोजर कंप्यूटिंग से अगले कार्यकाल को समाप्त कर दिया है । एक अकेला एक $समान है (state $), जो एक अनौपचारिक अवस्था है। मैं इसे एक पूर्व वेतन वृद्धि के बजाय बाद वेतन वृद्धि एक ही प्रभाव को प्राप्त करने के रूप में आप आरंभ द्वारा किया बनाया $aकरने के लिए 1

अब हम अंतिम (बड़ी!) समस्या से बचे हैं, आपके द्वारा नीचे टिप्पणी में बताया गया है।

बशर्ते इसके दोनों ऑपरेंड्स में से कोई भी एक Num(एक फ्लोट, और इस प्रकार अनुमानित) नहीं है, /ऑपरेटर आमतौर पर 100% सटीक Rat(एक सीमित परिशुद्धता तर्कसंगत) देता है। लेकिन यदि परिणाम का भाजक 64 बिट से अधिक हो जाता है, तो उस परिणाम को एक में बदल दिया जाता है Num- जो सटीकता के लिए प्रदर्शन करता है, एक ट्रेडऑफ़ जिसे हम नहीं बनाना चाहते हैं। हमें इसे ध्यान में रखना होगा।

असीमित सटीकता के साथ-साथ 100% सटीकता को निर्दिष्ट करने के लिए , बस FatRatएस का उपयोग करने के लिए ऑपरेशन को रोकना । इसे सही तरीके से करने के लिए, बस ऑपरेंड्स में से एक FatRat( कम से कम) में से कोई एक बनाएं (और कोई नहीं Num)

say [+] .[^500] given 1, { 1.FatRat / [×] 1 .. ++$ } ... Inf

मैंने इसे 500 दशमलव अंकों में सत्यापित किया है। मुझे उम्मीद है कि यह तब तक सटीक रहेगा जब तक कि राकु भाषा या राकोडो संकलक की कुछ सीमा से अधिक होने के कारण कार्यक्रम क्रैश नहीं हो जाता। ( कुछ चर्चा के लिए देशी पूर्णांक में 65536 बिट चौड़े बिगिंट को रद्द करने के लिए मेरा जवाब नहीं देखें ।)

फुटनोट

1 Raku कुछ महत्वपूर्ण गणितीय स्थिरांक में, सहित बनाया है e, iऔर pi(और इसके उर्फ π)। इस प्रकार कोई राकू में यूलर की पहचान लिख सकता है जैसे कि गणित की पुस्तकों में दिखता है। Euler की पहचान के लिए RosettaCode की Raku प्रविष्टि के लिए क्रेडिट के साथ :

# There's an invisible character between <> and i⁢π character pairs!
sub infix:<⁢> (\left, \right) is tighter(&infix:<**>) { left * right };

# Raku doesn't have built in symbolic math so use approximate equal 
say e**i⁢π + 1 ≅ 0; # True

2 डेमियन के लेख को अवश्य पढ़ा जाना चाहिए। लेकिन यह कई सराहनीय उपचारों में से एक है जो 'raku "यूलर के नंबर"' के लिए एक Google के 100+ मैचों में से एक है ।

3 अजगर के एक प्रशंसक द्वारा लिखे गए TIMTOWTDI के अधिक संतुलित विचारों में से एक के लिए TIMTOWTDI बनाम TSBO-APOO-OWTDI देखें । लेकिन वहाँ हैं बहुत दूर TIMTOWTDI लेने के लिए कमियां। इस उत्तरार्द्ध "खतरे" को प्रतिबिंबित करने के लिए, पर्ल समुदाय ने विनोदी रूप से लंबे, अपठनीय, और समझे गए TIMTOWTDIBSCINABTE को तैयार किया - इसमें एक से अधिक तरीके होते हैं लेकिन कभी-कभी संगति एक बुरी बात नहीं होती है, जिसका उच्चारण "टिम टोडी बाइकार्बोनेट" है। अजीब तरह से , लैरी ने रकु के डिजाइन के लिए बाइकार्बोनेट लगाया और डेमियन इसे eरकु में कंप्यूटिंग के लिए लागू करता है ।


जवाब के लिए धन्यवाद। आपके रास्ते के आधार पर मेरा रास्ता शीर्षक वाला खंड इसे काफी अच्छी तरह से हल करता है। मैं हालांकि पेचीदगियों को देखने की जरूरत है। मुझे नहीं पता था कि एक मैदान के $लिए एक आशुलिपि थी state $, यह काफी आसान है।
लार्स माल्मस्टीन

क्या eतीसरे समाधान के लिए अंकों की संख्या निर्दिष्ट करने का एक तरीका है ( आपके तरीके के आधार पर मेरा रास्ता शीर्षक )? मैंने 1 के आगे FatRat (500) को जोड़ने की कोशिश की है: ... given 1.FatRat(500), ...संख्याओं को 500-अंकीय बनाने के लिए सटीक है, लेकिन यह काम नहीं किया।
लार्स मैल्मस्टीन

@LarsMalmsteen मैंने FatRatअंतिम अनुभाग में आपके बहुत महत्वपूर्ण प्रश्न को संबोधित किया है । मैंने पूरे उत्तर का सम्मान भी किया है, हालांकि एकमात्र बड़ा बदलाव FatRatसामान है। (Btw, मुझे पता है कि मेरे जवाब का ज्यादातर हिस्सा वास्तव में आपके मूल प्रश्न के अनुकूल है; मुझे विश्वास है कि आपने मुझे अपना मनोरंजन करने के लिए अतिरिक्त
फुल

अतिरिक्त प्रयास के लिए धन्यवाद। इसलिए .FatRatएक्सटेंशन को कोड जनरेटर के अंदर रखा जाना चाहिए। अब मैंने इसे FatRatइस तरह से जोड़ने की कोशिश की और इसने ई की गणना 1000+ अंकों की सटीकता से की। अतिरिक्त अतिरिक्त फुलाना है। उदाहरण के लिए मुझे नहीं पता sayथा कि लंबे सरणियों / अनुक्रमों को काट रहा था । जानकारी के ऐसे बिट्स को जानना अच्छा है।
लार्स माल्मस्टीन

@LarsMalmsteen :) "तो .FatRatकोड जनरेटर के अंदर एक्सटेंशन डालना होगा।" हाँ। अधिक आम तौर पर, यदि एक विभाजन से संबंधित अभिव्यक्ति का पहले ही मूल्यांकन किया जा चुका है, तो नुकसान की पूर्ववत करने में बहुत देर हो जाती है यदि यह Ratसटीक रूप से बह निकला हो । यदि यह है, तो यह एक Num(फ्लोट) का मूल्यांकन करेगा और यह बदले में किसी भी आगे की गणना की गणना करता है, जिससे वे भी बन जाते हैंNum । बातें रहने को सुनिश्चित करने के लिए एक ही रास्ता FatRatहै शुरू उन्हें FatRatऔर किसी भी बचने Numरों। Intएस एंड Ratएस ठीक है, बशर्ते कि कम से कम एक FatRatको राकू को FatRatएस से बचने के लिए जाने दिया जाए ।
raiph

9

में भिन्‍नता है $_। इस प्रकार आपको जरूरत है 1 / (1/$_ * $a++)या बल्कि $_ /$a++

राकु द्वारा आप इस गणना को चरण दर चरण कर सकते हैं

1.FatRat,1,2,3 ... *   #1 1 2 3 4 5 6 7 8 9 ...
andthen .produce: &[*] #1 1 2 6 24 120 720 5040 40320 362880
andthen .map: 1/*      #1 1 1/2 1/6 1/24 1/120 1/720 1/5040 1/40320 1/362880 ...
andthen .produce: &[+] #1 2 2.5 2.666667 2.708333 2.716667 2.718056 2.718254 2.718279 2.718282 ...
andthen .[50].say      #2.71828182845904523536028747135266249775724709369995957496696762772

अच्छा लगा। मुझे कोई पता नहीं था andthen
होली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.