एक बहुपद की वास्तविक जड़ों का पता लगाएं


24

एक स्व-निहित कार्यक्रम लिखें, जब एक बहुपद दिया जाता है और एक बाउंड को पार न करने के लिए उस बहुपद की सभी वास्तविक जड़ें मिलेंगी।

प्रतिबन्ध

मुझे पता है कि गणितज्ञ और शायद कुछ अन्य भाषाओं में एक-प्रतीक समाधान है, और यह उबाऊ है, इसलिए आपको आदिम संचालन (इसके अलावा, घटाव, गुणन, विभाजन) से चिपके रहना चाहिए।

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

आपको यह साबित करने में सक्षम होना चाहिए कि आपका प्रोग्राम हमेशा काम क्यों करेगा (modulo numerical issues), हालांकि पूर्ण साक्ष्य इनलाइन की आपूर्ति करना आवश्यक नहीं है।

कार्यक्रम को बार-बार जड़ों के साथ बहुपद को संभालना चाहिए।

उदाहरण

x^2 - 2 = 0 (error bound 0.01)

इनपुट उदाहरण हो सकता है

-2 0 1 0.01
100 1 0 -2
1/100 ; x^2-2

आउटपुट उदाहरण के लिए हो सकता है

-1.41 1.42

लेकिन नहीं

-1.40 1.40

जैसा कि लगभग 0.014 की पूर्ण त्रुटियाँ हैं ...

परीक्षण के मामलों

सरल:

x^2 - 2 = 0 (error bound 0.01)

x^4 + 0.81 x^2 - 0.47 x + 0.06 (error bound 10^-6)

एकाधिक रूट:

x^4 - 8 x^3 + 18 x^2 - 27 (error bound 10^-6)

विल्किंसन की बहुपद:

x^20 - 210 x^19 + 20615 x^18 - 1256850 x^17 + 53327946 x^16 -1672280820 x^15 +
    40171771630 x^14 - 756111184500 x^13 + 11310276995381 x^12 - 135585182899530 x^11 +
    1307535010540395 x^10 - 10142299865511450 x^9 + 63030812099294896 x^8 -
    311333643161390640 x^7 + 1206647803780373360 x^6 -3599979517947607200 x^5 +
    8037811822645051776 x^4 - 12870931245150988800 x^3 + 13803759753640704000 x^2 -
    8752948036761600000 x + 2432902008176640000  (error bound 2^-32)

NB यह प्रश्न लगभग 3 महीने तक सैंडबॉक्स में था । यदि आपको लगता है कि पोस्ट करने से पहले इसमें सुधार की आवश्यकता है, तो सैंडबॉक्स पर जाएं और अन्य प्रस्तावित प्रश्नों पर टिप्पणी करें, इससे पहले कि वे मेन पर पोस्ट किए जाएं।



@ सबिसरियस, ??
पीटर टेलर

3
एक मजाक के रूप में इरादा किया गया था :(
डॉ। belisarius

मुझे पता है कि यह एक पुरानी चुनौती है, इसलिए यदि आप इसे फिर से खोलने की तरह महसूस नहीं करते हैं, तो जवाब देने के लिए बाध्य न करें। (a) क्या हम एक फंक्शन, या केवल एक पूर्ण प्रोग्राम लिख सकते हैं? (ख) यदि हम कोई फ़ंक्शन लिख सकते हैं, तो क्या हम मान सकते हैं कि इनपुट कुछ सुविधाजनक डेटा प्रकार, जैसे, पायथन fractions.Fraction(एक तर्कसंगत प्रकार) का उपयोग करता है? (c) क्या हमें डिग्री <1 के बहुपदों को संभालना है? (d) क्या हम मान सकते हैं कि अग्रणी गुणांक 1 है?
एल डे

(ई) बार-बार जड़ों के साथ बहुपद के संबंध में, यह विषम और यहां तक ​​कि गुणाओं की जड़ों के बीच अंतर करने के लायक है (परीक्षण के मामलों में केवल विषम गुणा की जड़ें हैं।) जबकि विषम बहुलता की जड़ें सौदा करने के लिए बहुत कठिन नहीं हैं, मैं '। यह निश्चित नहीं है कि संख्यात्मक रूप से कितनी गुणा की जड़ों को सही ढंग से संभाला जा सकता है, खासकर जब से आप केवल जड़ों के मूल्यों के लिए एक त्रुटि मार्जिन निर्दिष्ट करते हैं, न कि उनके अस्तित्व के लिए। (...)
एल डे

जवाबों:


8

गणितज्ञ, २२३

r[p_,t_]:=Module[{l},l=Exponent[p[x],x];Re@Select[NestWhile[Table[#[[i]]-p[#[[i]]]/Product[If[i!=j,#[[i]]-#[[j]],1],{j,l}],{i,l}]&,Table[(0.9+0.1*I)^i,{i,l}],2*Max[Table[Abs[#1[[i]]-#2[[i]]],{i,l}]]>t&,2],Abs[Im[#]]<t^.5&]]

यह समाधान बहुपद को हल करने के लिए डूरंड-कर्नेर विधि को लागू करता है। ध्यान दें कि यह एक पूर्ण समाधान नहीं है (जैसा कि नीचे दिखाया जाएगा) क्योंकि मैं अभी तक विल्किंसन के बहुपद को निर्दिष्ट परिशुद्धता तक नहीं संभाल सकता हूं। सबसे पहले मैं क्या कर रहा हूँ की एक व्याख्या: गणित में कोडिंग स्वरूपण

#[[i]]-p[#[[i]]]/Product[If[i!=j,#[[i]]-#[[j]],1],{j,l}]&: इस प्रकार फ़ंक्शन प्रत्येक सूचकांक के iलिए अगले डूरंड-कर्नेर सन्निकटन के लिए गणना करता है । फिर इस लाइन को टेबल में एनकैप्सुलेट किया जाता है और नेस्टव्हील का उपयोग करके उत्पन्न इनपुट पॉइंट्स पर लागू किया जाता है Table[(0.9+0.1*I)^i,{i,l}]। NestWhile पर शर्त यह है कि एक पुनरावृत्ति से दूसरे में अधिकतम परिवर्तन (सभी शर्तों पर) निर्दिष्ट परिशुद्धता से अधिक है। जब सभी शब्द इससे कम हो गए हैं, तो NestWhile समाप्त हो जाता है और Re@Selectउन शून्य को हटा देता है जो वास्तविक रेखा पर नहीं आते हैं।

उदाहरण आउटपुट:

> p[x_] := x^2 - 2
> r[p, .01]
{1.41421, -1.41421}

> p[x_] := x^4 - 8 x^3 + 18 x^2 - 27
> r[p, 10^-6]
{2.99999, 3., 3.00001, -1.}

> p[x_] := x^20 - 210 x^19 + ... + 2432902008176640000 (Wilkinson's)
> Sort[r[p, 2^-32]]
{1., 2., 3., 4., 5., 6., 7.00001, 7.99994, 9.00018, 10.0002, 11.0007, \
11.9809, 13.0043, 14.0227, 14.9878, 16.0158, 16.9959, 17.9992, \
19.0001, 20.}

जैसा कि आप शायद देख सकते हैं, जब डिग्री अधिक बढ़ जाती है तो यह विधि सही मानों के आसपास उछलने लगती है, वास्तव में कभी भी पूरी तरह से घर नहीं बनाती है। अगर मैं अपने कोड की रोक की स्थिति को "एक पुनरावृत्ति से अगले इप्सिलोन से अधिक नहीं होने वाले अनुमानों" की तुलना में कुछ सख्त होने के लिए सेट करता हूं, तो एल्गोरिथ्म कभी भी बंद नहीं होता है। मुझे लगता है कि मुझे न्यूटन की विधि के इनपुट के रूप में डूरंड-कर्नेर का उपयोग करना चाहिए?


डुरंड-कर्नर में कई जड़ों के साथ संभावित समस्याएं भी हैं। (न्यूटन की विधि बहुत मदद नहीं कर सकती है - विल्किंसन की बहुपद विशेष रूप से बीमार होने के लिए चुना गया है)।
पीटर टेलर

आप काफी हद तक सही हैं: मैंने विल्किंसन के निकट x = 17 पर ज़ूम करने के बाद कार्रवाई के उस कोर्स को छोड़ दिया, यह एक पूर्ण गड़बड़ है। मुझे चिंता है कि बहुत अधिक सटीकता प्राप्त करने के लिए मुझे ग्रोबनर आधार के साथ एक प्रतीकात्मक समाधान के लिए जाना होगा।
काया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.