2012-12-02 22 views
6

के लिए 2π मैं, गणना करने के लिए एक्स> 1000 मैटलैब में साथ sin(4^x) की जरूरत मूल रूप से sin(4^x mod 2π) पाप समारोह बहुत बड़ी हो अंदर मूल्यों के बाद से है के साथ, मैटलैब 4^1000 के लिए अनंत देता है। मैं इसे कुशलतापूर्वक कैसे गणना कर सकता हूं? मैं बड़े डेटा प्रकारों से बचना पसंद करता हूं।कंप्यूट 4^x आधुनिक बड़े एक्स

मुझे लगता है कि sin(n*π+z) जैसे कुछ में परिवर्तन एक संभावित समाधान हो सकता है।

+1

आप गणित पर प्रश्नों के लिए [mathoverflow] (http://mathoverflow.net/) भी देखना पसंद कर सकते हैं - हालांकि यह प्रोग्रामिंग से संबंधित है। – Jeff

+2

मेरे पास एक झुकाव है कि डबल परिशुद्धता अंकगणित के कारण किसी भी विधि को जंक का कारण बन जाएगा: उदा। कंप्यूटिंग पाप (2 * पीआई * 10^i) i = 1: 100 के लिए मैटलैब में जंक देता है (या उस मामले के लिए सी ... यह वास्तव में डबल परिशुद्धता अंकगणित का मामला है), और इसी तरह कंप्यूटिंग मोड (2 * पीआई * 10^i + 0.0001, 2 * pi) i = 1: 100 के लिए जंक देता है। – db1234

+0

यह मेरा डर भी है। इसलिए, मैं आमतौर पर लूप का उपयोग करने से पहले गणितीय समाधान खोजने की कोशिश करता हूं। धन्यवाद। – Bene

उत्तर

13

आपको सावधान रहना होगा, क्योंकि परिशुद्धता का नुकसान होगा। पाप कार्य आवधिक है, लेकिन 4^1000 एक बड़ी संख्या है। इतनी प्रभावी ढंग से, हम अंतराल [0,2 * पीआई) में तर्क को स्थानांतरित करने के लिए 2 * पीआई के एकाधिक को घटाते हैं।

4^1000 लगभग 1e600 है, वास्तव में एक बड़ी संख्या है। तो मैं अपने high precision floating point tool in MATLAB का उपयोग करके अपनी गणना करूंगा। (वास्तव में, जब मैंने एचपीएफ लिखा था तो मेरे स्पष्ट लक्ष्यों में से एक पाप (1e400) जैसी संख्या की गणना करने में सक्षम होना था। भले ही आप इसके मजाक के लिए कुछ कर रहे हों, फिर भी यह सही कर रहा है।) इस मामले में , क्योंकि मुझे पता है कि जिस शक्ति में हम रुचि रखते हैं वह लगभग 1e600 है, तो मैं परिशुद्धता के 600 अंकों से अधिक में अपनी गणना करूंगा, उम्मीद कर रहा हूं कि मैं घटिया रद्दीकरण से 600 अंकों को खो दूंगा। यह एक बड़े पैमाने पर घटिया रद्दीकरण मुद्दा है। इसके बारे में सोचो। वह मॉड्यूलस ऑपरेशन दो संख्याओं के बीच प्रभावी रूप से एक अंतर है जो पहले 600 अंकों के लिए समान होगा!

X = hpf(4,1000); 
X^1000 
ans = 
114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029376 

2 * पीआई का सबसे नजदीक एकाधिक क्या है जो इस संख्या से अधिक नहीं है? हम इसे एक साधारण ऑपरेशन से प्राप्त कर सकते हैं।

twopi = 2*hpf('pi',1000); 
twopi*floor(X^1000/twopi) 
ans = 114813069527425452423283320117768198402231770208869520047764273682576626139237031385665948631650626991844596463898746277344711896086305533142593135616665318539129989145312280000688779148240044871428926990063486244781615463646388363947317026040466353970904996558162398808944629605623311649536164221970332681344168908984458505602379484807914058900934776500429002716706625830522008132236281291761267883317206598995396418127021779858404042159853183251540889433902091920554957783589672039160081957216630582755380425583726015528348786419432054508915275783882625175435528800822842770817965453762184851149029372.6669043995793459614134256945369645075601351114240611660953769955068077703667306957296141306508448454625087552917109594896080531977700026110164492454168360842816021326434091264082935824243423723923797225539436621445702083718252029147608535630355342037150034246754736376698525786226858661984354538762888998045417518871508690623462425811535266975472894356742618714099283198893793280003764002738670747 

जैसा कि आप देख सकते हैं, पहले 600 अंक समान थे। अब, जब हम दो संख्याओं घटाना,

X^1000 - twopi*floor(X^1000/twopi) 
ans = 
3.333095600420654038586574305463035492439864888575938833904623004493192229633269304270385869349155154537491244708289040510391946802229997388983550754583163915718397867356590873591706417575657627607620277446056337855429791628174797085239146436964465796284996575324526362330147421377314133801564546123711100195458248112849130937653757418846473302452710564325738128590071680110620671999623599726132925263826 

यही कारण है कि मैं एक बड़े पैमाने पर subtractive रद्द मुद्दे के रूप में यह करने के लिए भेजा है। दो संख्याएं कई अंकों के लिए समान थीं। सटीकता के 1000 अंक भी लेते हुए, हमने कई अंक खो दिए। जब आप दो अंकों को घटाते हैं, भले ही हम 1000 अंकों के साथ परिणाम ले रहे हों, केवल उच्चतम आदेश 400 अंक अब सार्थक हैं।

एचपीएफ पाठ्यक्रम के ट्रिग फ़ंक्शन की गणना करने में सक्षम है। लेकिन जैसा कि हमने ऊपर दिखाया है, हमें केवल परिणाम के पहले 400 अंकों पर भरोसा करना चाहिए। (कुछ समस्याओं पर, पाप फ़ंक्शन का स्थानीय आकार हमें उससे अधिक अंक खोने का कारण बन सकता है।)

sin(X^1000) 
ans = 
-0.19033458127208318385994396068455455709388374041098639172943768418947125138650234240955423917696880832346734715448603532912993423621761996537053192685449334064870714463489747336279464911185192423229252660143128976923388511299599457104070322693060218958487584842139143972048735807765826659851362293280012583640059277583434162223469640779539703355744143419935430600390820454055891750089781440474478225522286222463738277009002753247363724815609283394633443329778920087022201603354152914210817007440447838392869577354385645124650950464218066771029610934877080889086985319804240164585346291661088530125354930225403524397401167317843031900829546691402971929428720760150282604082313216048252703439459284455892236101855653841958635139010896628829034919565066139672417258772760228631878006327065033172

तो क्या मैं सही हूं, और हम इन सभी अंकों पर भरोसा नहीं कर सकते हैं? मैं वही गणना करूंगा, एक बार परिशुद्धता के 1000 अंकों में, फिर 2000 अंकों में दूसरी बार। पूर्ण अंतर की गणना करें, फिर लॉग 10 लें। 2000 अंक परिणाम 1000 अंक परिणाम की तुलना में अनिवार्य रूप से सटीक रूप से हमारा संदर्भ होगा।

double(log10(abs(sin(hpf(4,[1000 0])^1000) - sin(hpf(4,[2000 0])^1000)))) 
ans = 
     -397.45 

आह। तो उन सटीक 1000 अंकों के साथ हमने शुरुआत की, हमने 602 अंकों को खो दिया। परिणाम में अंतिम 602 अंक शून्य हैं, लेकिन अभी भी कचरा पूरा है। जैसा कि मैंने उम्मीद की थी। सिर्फ इसलिए कि आपका कंप्यूटर उच्च परिशुद्धता की रिपोर्ट करता है, आपको यह जानना होगा कि इस पर भरोसा न करें।

क्या हम उच्च परिशुद्धता उपकरण के बिना सहारा के बिना गणना कर सकते हैं? सावधान रहे। उदाहरण के लिए, मान लीजिए कि हम गणना के एक पावरमॉड प्रकार का उपयोग करते हैं? इस प्रकार, प्रत्येक चरण में मॉड्यूलस लेते समय वांछित शक्ति की गणना करें। इस प्रकार, डबल परिशुद्धता में किया:

X = 1; 
for i = 1:1000 
    X = mod(X*4,2*pi); 
end 
sin(X) 
ans = 
     0.955296299215251 

आह, लेकिन याद रखें कि सही जवाब था -0,19033458127208318385994396068455455709388 ...

तो वहाँ अनिवार्य रूप से शेष महत्व की बात नहीं है। हमने उस गणना में हमारी सारी जानकारी खो दी है। जैसा कि मैंने कहा, सावधान रहना महत्वपूर्ण है।

उस लूप में प्रत्येक चरण के बाद क्या हुआ, हमने मॉड्यूलस गणना में एक छोटा सा नुकसान किया। लेकिन फिर हमने जवाब 4 से गुणा किया, जिससे 4 के कारक से त्रुटि बढ़ने लगी, और फिर 4 का एक और कारक आदि। और निश्चित रूप से, प्रत्येक चरण के बाद, परिणाम संख्या के अंत में एक छोटा सा खो देता है । अंतिम परिणाम पूरा क्रापोला था।

चलिए एक छोटी शक्ति के लिए ऑपरेशन को देखते हैं, बस यह समझाने के लिए कि क्या हुआ। उदाहरण के लिए, 20 वीं शक्ति का प्रयास करें। , डबल परिशुद्धता का उपयोग

mod(4^20,2*pi) 
ans = 
      3.55938555711037 

अब, एक powermod गणना में एक पाश का उपयोग करें, हर कदम के बाद आधुनिक ले रही। अनिवार्य रूप से, यह प्रत्येक चरण के बाद 2 * पीआई के गुणक को त्याग देता है।

X = 1; 
for i = 1:20 
    X = mod(X*4,2*pi); 
end 
X 
X = 
      3.55938555711037 

लेकिन क्या यह सही मूल्य है? दोबारा, मैं सही संख्या की गणना करने के लिए एचपीएफ का उपयोग करूंगा, जो उस संख्या के पहले 20 अंक दिखा रहा है। (जब से मैं 50 कुल अंकों में अभिकलन किया है, मैं बिल्कुल उनमें से पहले 20 पर भरोसा करेंगे।)

mod(hpf(4,[20,30])^20,2*hpf('pi',[20,30])) 
ans = 
      3.5593426962577983146 

वास्तव में, जबकि डबल परिशुद्धता में परिणामों से पता चला है, उन डबल पिछले अंक के लिए सहमत परिणाम 5 वें महत्वपूर्ण अंक से वास्तव में गलत थे। जैसा कि यह पता चला है, हमें इस लूप के लिए 600 से अधिक अंकों की परिशुद्धता लेनी होगी ताकि किसी भी महत्व का नतीजा हो सके।

आखिरकार, इस मृत घोड़े को पूरी तरह से मारने के लिए, हम पूछ सकते हैं कि बेहतर पावरमोड गणना क्या की जा सकती है। यही कारण है, हम जानते हैं के रूप में 1000 एक द्विआधारी फार्म (उपयोग dec2bin) में विघटित किया जा सकता है:

512 + 256 + 128 + 64 + 32 + 8 
ans = 
     1000 

हम एक दोहराया बराबरी योजना का उपयोग कर सकते हैं कम गुणा के साथ कि बड़े बिजली विस्तार करने के लिए, और इतने कम संचित त्रुटि का कारण? अनिवार्य रूप से, हम गणना करने के लिए

4^1000 = 4^8 * 4^32 * 4^64 * 4^128 * 4^256 * 4^512 

हालांकि कोशिश कर सकते हैं, बार-बार 4 बराबरी, तो प्रत्येक ऑपरेशन के बाद आधुनिक लेने के द्वारा इस है।हालांकि यह विफल रहता है, क्योंकि मॉड्यूलो ऑपरेशन केवल 2 * पीआई के पूर्णांक गुणक को हटा देगा। आखिरकार, मॉड वास्तव में पूर्णांक पर काम करने के लिए डिज़ाइन किया गया है। तो देखो क्या होता है।

4^2 = 16 = 3.43362938564083 + 2*(2*pi) 

हम सिर्फ हालांकि शेष वर्ग कर सकते हैं, तो आधुनिक फिर से ले रही है: हम 4^2 के रूप में व्यक्त कर सकते हैं? नहीं!

mod(3.43362938564083^2,2*pi) 
ans = 
      5.50662545075664 

mod(4^4,2*pi) 
ans = 
      4.67258771281655 

हम समझ सकते हैं कि क्या हुआ जब हम इस फ़ॉर्म का विस्तार:

4^4 = (4^2)^2 = (3.43362938564083 + 2*(2*pi))^2 

क्या आप जब आप 2 * पाई का पूर्णांक गुणकों हटाने मिलेगा? आपको समझने की जरूरत है कि प्रत्यक्ष पाश ने मुझे 2 * पीआई के पूर्णांक गुणांक को हटाने की अनुमति क्यों दी, लेकिन उपर्युक्त स्क्वायरिंग ऑपरेशन नहीं करता है। बेशक, संख्यात्मक मुद्दों के कारण प्रत्यक्ष लूप भी विफल रहा।

+0

यह एक सुंदर समाधान नहीं है। हालांकि यह काम करता है और प्रदर्शन ठीक है। धन्यवाद। – Bene

+0

समस्या यह है कि आवधिक कार्य के लिए मॉड गणना एक हत्यारा है। पूर्णांक के लिए मोड आसान हैं, क्योंकि कोई नुकसान नहीं है। लेकिन 2pi के संबंध में mod इतना आसान नहीं है। जब मैंने एचपीएफ लिखा था तो मेरे लक्ष्यों में से एक पाप (1e400) की गणना करना था। डबल (पाप (HPF ('1e400', 1000))) = - .998538231983098। वह मान सही है। –

+0

ऐसा लगता है कि आपने वास्तव में 'पाप (4^4) ~ -0.9 992' की गणना की है। 'पाप (4^1000) ~ -0.19033', मुझे लगता है। – DSM

5

मैं पहले इस प्रकार प्रश्न को फिर से परिभाषित करता हूं: गणना 4^1000 मॉड्यूलो 2pi। तो हमने समस्या को दो में विभाजित कर दिया है।

कुछ गणित प्रवंचना का उपयोग करें:

(a+2pi*K)*(b+2piL) = ab + 2pi*(garbage)

इसलिए, आप बस गुणा 4 अपने आप में कई बार कर सकते हैं और कंप्यूटिंग आधुनिक 2pi हर चरण। पूछने के लिए असली सवाल, निश्चित रूप से, इस बात की सटीकता क्या है। इसे सावधानीपूर्वक गणितीय विश्लेषण की आवश्यकता है। यह कुल बकवास हो सकता है या नहीं भी हो सकता है।

+0

मेरे पास एक झुकाव है कि इस विधि, या किसी भी विधि से डबल परिशुद्धता अंकगणित के कारण जंक हो जाएगा: उदा। कंप्यूटिंग पाप (2 * पीआई * 10^i) i = 1: 100 के लिए जंक देता है, और इसी तरह कंप्यूटिंग मोड (2 * पीआई * 10^आई + 0.0001, 2 * पीआई) – db1234

+0

हाँ .. संभव है। मशीन अंकगणित के साथ सावधान रहना चाहिए। –

+1

मुझे शक्तियों और बड़ी संख्याओं के लिए एक मॉड फ़ंक्शन मिला: http://www.mathworks.com/matlabcentral/fileexchange/7908-big-modulo-function/content/bigmod.m यह एक कामकाजी समाधान हो सकता है। – Bene

3

मोड के साथ पावेल के संकेत के बाद मुझे mathwors.com पर उच्च शक्तियों के लिए एक मॉड फ़ंक्शन मिला। bigmod(number,power,modulo) 4^4000 mod 2π की गणना नहीं कर सकता। क्योंकि यह सिर्फ मॉड्यूल के रूप में पूर्णांक के साथ काम करता है और decimals के साथ नहीं।

यह कथन अब सही नहीं है: sin(4^x)sin(bidmod(4,x,2*pi)) है।

+0

मुझे इस पर भरोसा नहीं है। ऑक्टेव (Matlab के ओपन सोर्स संस्करण) पर मैंने 'sin (2 * pi * bigmod (4, 100, 2 * pi) टाइप करके bigmod.m रूटीन का उपयोग करने की कोशिश की और परिणाम शून्य नहीं था। मैं काफी हद तक निश्चित हूं कि यह भी मटकाब में होगा। – db1234

+1

@dblazevski जब तक मैं काफी गलत नहीं हूं, यह शून्य नहीं होना चाहिए ... '4^100 mod 2pi' एक पूर्णांक नहीं है। – Dougal

+0

Opps ... मूर्ख गलती, धन्यवाद @Dougal, मुझे लगता है कि एक परीक्षण 'पाप होगा (bigmod (4 * 2 * पीआई, 100, 2 * पीआई)), और यह शून्य देता है क्योंकि यह – db1234

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