5

पहली समस्यादो मेथेमेटिका में अजीब दक्षता समस्याओं

मैं समय समाप्त हो गया है कि कब तक यह निम्नलिखित बयानों (जहां वी [x] एक समय गहन समारोह कॉल है) की गणना करने के लेता है:

Alice  = Table[V[i],{i,1,300},{1000}]; 
Bob  = Table[Table[V[i],{i,1,300}],{1000}]^tr; 
Chris_pre = Table[V[i],{i,1,300}]; 
Chris  = Table[Chris_pre,{1000}]^tr; 

ऐलिस , बॉब और क्रिस समान मैट्रिक 3 अलग-अलग तरीकों की गणना करते हैं। मुझे लगता है कि ऐलिस और बॉब की तुलना में क्रिस की तुलना 1000 गुना तेज है।

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

बॉब इतनी धीमी गति से मूल्यांकन क्यों करता है?


दूसरी समस्या

मान लीजिए मैं फार्म के मेथेमेटिका में एक समारोह को संकलित करना चाहते

f(x)=x+y 

जहां "y" एक निरंतर संकलन समय पर तय हो गई है (लेकिन जो मैं नहीं करना पसंद करते हैं सीधे कोड में इसके संख्यात्मक रूप से प्रतिस्थापित करें क्योंकि मैं इसे आसानी से बदल सकता हूं)। यदि y का वास्तविक मान y = 7.3 है, और मैं

f1=Compile[{x},x+y] 
f2=Compile[{x},x+7.3] 

परिभाषित करता है तो f1 f2 से 50% धीमी गति से चलाता है। एफ 1 संकलित होने पर मैथमैटिका "7.3" को "7.3" के साथ कैसे बदल सकता है, ताकि f1 f2 जितनी जल्दी हो सके?


संपादित करें:

मैं दूसरी समस्या के लिए एक बदसूरत वैकल्पिक हल मिल गया:

f1=ReleaseHold[Hold[Compile[{x},x+z]]/.{z->y}] 

एक बेहतर तरीका होना चाहिए ...

उत्तर

5

आप शायद इन पोस्ट किया है चाहिए अलग प्रश्न के रूप में, लेकिन कोई चिंता नहीं!

समस्या एक

ऐलिस के साथ समस्या यह है कि तुम क्या उम्मीद करते हैं निश्चित रूप से है। बॉब के साथ समस्या यह है कि बाहरी Table बाहरी Table के प्रति पुनरावृत्ति के बाद मूल्यांकन किया जाता है। इस ट्रेस के साथ स्पष्ट रूप से दिखाई दे रहा है:

Trace[Table[Table[i, {i, 1, 3}], {3}]] 

{ 
Table[Table[i,{i,1,2}],{2}], 
{Table[i,{i,1,2}],{i,1},{i,2},{1,2}},{Table[i,{i,1,2}],{i,1},{i,2},{1,2}}, 
{{1,2},{1,2}} 
} 

लाइन ब्रेक जोर देने के लिए कहा, और हाँ, टेबल पर ट्रेस के उत्पादन में एक छोटे से अजीब है, लेकिन आप इसे देख सकते हैं। स्पष्ट रूप से मैथमैटिका इसे बेहतर ढंग से अनुकूलित कर सकता है, यह जानकर कि बाहरी तालिका में कोई इटरेटर नहीं है, लेकिन किसी भी कारण से, यह इसे ध्यान में रखता नहीं है। केवल क्रिस आप क्या चाहते हैं करता है, आप बॉब को संशोधित कर सकता है, हालांकि:

Transpose[Table[Evaluate[Table[V[i],{i,1,300}]],{1000}]] 

यह लगता है कि यह वास्तव में दो या तो का एक पहलू से क्रिस से बेहतर साबित है, क्योंकि यह मध्यवर्ती परिणाम स्टोर करने के लिए नहीं है।

समस्या दो

वहाँ मूल्यांकन के साथ एक सरल समाधान, हालांकि मैं यह सब संभव कार्यों के साथ काम नहीं करेंगे (यानी जो कि वास्तव में आयोजित किया जाना चाहिए) संकलित की उम्मीद: आप

f1 = Compile[{x}, Evaluate[x + y]]; 

With[{y=7.3}, 
    f1 = Compile[{x}, x + y]; 
] 

या यदि y कहीं परिभाषित किया गया है, एक अस्थायी उपयोग करें:: यह भी एक With इस्तेमाल कर सकते हैं

y = 7.3; 
With[{z = y}, 
    f1 = Compile[{x}, x + z]; 
] 

मैथमैटिका के स्कोपिंग और मूल्यांकन तंत्र पर एक विशेषज्ञ नहीं हूं, इसलिए आसानी से एक बेहतर तरीका हो सकता है, लेकिन उम्मीद है कि उनमें से एक यह आपके लिए करता है!

+0

वाह, बहुत बहुत धन्यवाद! यही वह है जिसकी तलाश में मैं हूं। (और मैं भविष्य में इस तरह की समस्याओं को अलग-अलग पोस्ट करना सुनिश्चित कर दूंगा।) –

+0

'साथ' का उपयोग करना शायद समस्या से निपटने का सबसे सुरक्षित तरीका है, क्योंकि यह अपने शरीर के किसी भी मूल्यांकन से पहले वास्तविक शब्दावली प्रतिस्थापन करता है। –

+0

@ माइकल पिलैट: सहमत हुए। मैंने सुझाव दिया है कि यदि आप पहले से ही 'y' परिभाषित कर चुके हैं, तो त्वरित और गंदे दृष्टिकोण की भावना में मूल्यांकन करें, लेकिन अस्थायी अतिरिक्त चर निश्चित रूप से सुरक्षित है। – Cascabel

1

पहली समस्या क्या आपने Chris_pre गणना के आउटपुट की जांच की है? आप पाएंगे कि यह एक बड़ा मैट्रिक्स नहीं है, क्योंकि आप चरणीय के बजाए एक पैटर्न में मध्यवर्ती परिणाम स्टोर करने की कोशिश कर रहे हैं। इसके बजाए क्रिसपेरे आज़माएं। फिर सभी समय तुलनीय हैं।

दूसरी समस्या संकलन के उपयोग पर कई कठोर प्रतिबंध हैं। एक मुद्दा यह है कि आप वैश्विक चर का उल्लेख नहीं कर सकते हैं। निर्माण के साथ जो पहले से ही सुझाव दिया गया था, इस बारे में सुझाया गया तरीका है। आप संकलित करें के बारे में अधिक जानने के लिए चाहते हैं, टेड Ersek की चाल की जाँच: http://www.verbeia.com/mathematica/tips/Tricks.html

+0

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

2

आपका पहला समस्या पहले से ही समझाया गया है, लेकिन मैं कहना है कि ConstantArray मेथेमेटिका में पेश किया गया था इस मुद्दे के समाधान करना चाहते हैं। उस समय से पहले Table[expr, {50}] दोनों निश्चित और बदलती अभिव्यक्तियों के लिए उपयोग किया गया था।

ConstantArray की शुरूआत के बाद से पुनर्मूल्यांकन के साथ पुनरावृत्ति के बीच स्पष्ट पृथक्करण और अभिव्यक्ति के सरल डुप्लिकेशंस के बीच स्पष्ट अलगाव है। आप व्यवहार इस का उपयोग करते हुए देख सकते हैं:

ConstantArray[Table[Pause[1]; i, {i, 5}], {50}] ~Monitor~ i 

यह Pause[1] की वजह से Table लूप करने के लिए पाँच सेकंड लेता है, लेकिन उसके बाद पाश पूरा हो गया है यह पुनः मूल्यांकन नहीं किया गया है और 50 प्रतिलिपियों को तुरंत मुद्रित कर रहे हैं।

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