2011-11-19 19 views
7

कल्पना कीजिए मैं Mathematica में एक पुनरावर्ती भाज्य परिभाषित किया है इस तरह,:गणित में, यह क्यों है कि एक पुनरावर्ती समारोह में एक प्रतिस्थापन समाप्त नहीं होता है?

Clear[fact] 
fact[0] = 1 
fact[n_] := n fact[n - 1] 

तथ्य [10] का मूल्यांकन इस बात की पुष्टि समारोह काम करता है और समाप्त हो जाता है कि।

एक प्रमुख उदाहरण का थोड़ा सा, लेकिन यह इस प्रश्न में अपना उद्देश्य प्रदान करता है। दरअसल, मेरा प्रश्न वैसे भी सामान्य रूप से पुनरावर्ती कार्य परिभाषाओं से संबंधित है।

x fact[x-1] /. x -> 2 

ओह, यह एक प्रत्यावर्तन गहराई सीमा में चलता है:

:

$RecursionLimit::reclim: Recursion depth of 256 exceeded. 

मैं की तरह कुछ देखने के लिए उम्मीद

मैं भी समाप्त करने के लिए निम्न लिखित परिवर्तन का मूल्यांकन करने की उम्मीद

2 fact[2-1] 

या सिर्फ मूल्य

2 

अद्यतन: तथ्य का एक वैकल्पिक पुनरावर्ती परिभाषाकरता काम अपेक्षा के अनुरूप:

Clear[fact] 
fact[n_] := If[n < 1, 1, n fact[n - 1]] 

लेकिन इस तथ्य (यमक इरादा ;-) यह भी रहस्यमय मेरे लिए बनाता है: क्यों यह होता है इतना अलग व्यवहार करते हो?

मेरा प्रश्न दोहरा है:

  1. यहां तक ​​कि साथ में निर्मित और सुराग के लिए शुद्ध खोज, मैं व्याख्या नहीं कर सकते क्यों मेथेमेटिका में जोर देते हैं, जाहिरा तौर पर, प्रतीकात्मक परिणाम रखने के बजाय का मूल्यांकन

    'इंटरमीडिएट' परिणाम और अच्छी तरह से समाप्त हो रहा है। एक व्यवहार्य व्याख्या कौन उद्यम करता है?

  2. मैनेमैटिका को अपने निष्पादन के अनुसार प्रदर्शन करने के लिए कैसे समझा सकता हूं (का उपयोग कर वैकल्पिक उपयोग करने के अलावा [])?

मैं वास्तव में इस से परेशान हूं, और मुझे उम्मीद है कि कोई बाहर मेरी मदद कर सकता है।

/Twan

उत्तर

6

u[x_] := x; Trace[x*u[x] /. x -> 2] कोशिश कर रहा है, यह पहली x और u[x] मूल्यांकन करता है। आपके मामले में, यह पहली बार को 2 से बदलकर fact[x-1] का मूल्यांकन करने का प्रयास करता है, और रिकर्सन सीमा को हिट करता है।

Attributes[ReplaceAll] दिखाता है कि इसमें HoldFirst विशेषता नहीं है, इसलिए यह अपने पहले तर्क का मूल्यांकन करके शुरू होता है। उदाहरण के लिए,

[email protected][Hold[x*fact[x - 1]], x -> 2] 

उम्मीद 2 के रूप में यह पहला तर्क रखती है, की जगह देता है, है, तो, पकड़ विज्ञप्ति के रूप में आप चाहते थे।

एक और तरीका यह

Unprotect[ReplaceAll] 
SetAttributes[ReplaceAll, HoldFirst] 
ReplaceAll[x*fact[x - 1], x -> 2] 

है, लेकिन ऐसा नहीं करते हैं करने के लिए।

निश्चित रूप से कोई व्यक्ति जल्द ही बेहतर स्पष्टीकरण देगा, हालांकि।

संपादित करें: क्यों

Clear[factif] 
factif[n_] := If[n < 1, 1, n factif[n - 1]] 

अनंत प्रत्यावर्तन में परिणाम नहीं करता है के रूप में जोड़ा प्रश्न के उत्तर में: इस तरह से परिभाषित, factif[x]If[x < 1, 1, x factif[x - 1]] करने, मूल्यांकन करता है के बाद से x<1 मूल्यांकन नहीं किया जा सकता। तो यह ReplaceAll का पहला तर्क का प्रयास किया मूल्यांकन के बाद इस रूप में बनी हुई है, तो प्रतिस्थापन होता है आदि

+0

आह, यह समझ में आता है: गणित पहले एलएचएस का मूल्यांकन करता है। और _then_ प्रतिस्थापन करता है।और होल्ड के साथ [] आप उस 'उत्सुक' मूल्यांकन को स्थगित कर सकते हैं। महान उत्तर के लिए धन्यवाद: प्रभावी, प्रासंगिक, स्पष्ट और संक्षेप में! मेरी प्रशंसा – nanitous

+0

@nnitous चीयर्स! यदि तीन उत्तरों में से एक आपके प्रश्न का उत्तर देता है, तो आप इसे स्वीकार्य उत्तर के रूप में चिह्नित कर सकते हैं ताकि वह शीर्ष पर दिखाई दे (और यह उत्तर देने वालों को प्रतिष्ठा देता है)। – acl

+0

इसे इंगित करने के लिए धन्यवाद! – nanitous

5

इसका कारण यह है कि आप इस मूल्यांकन कर रहे हैं:

fact[x-1] 

से पहले प्रतिस्थापन होता है। बस fact[x-1] करें और आपको त्रुटि मिलती है।

तुम इतनी तरह अपने fact समारोह को ठीक कर सकते हैं:

Clear[fact] 
fact[0] = 1 
fact[n_Integer?Positive] := n fact[n - 1] 

फिर x fact[x - 1] /. x -> 2 रिटर्न 2 जो सही लगता है।

याद रखें कि आपके फ़ंक्शन तर्क पैटर्न fact[n_]अत्यंत सामान्य है। उदाहरण के लिए यह मूल्यांकन करने के लिए fact[Integrate[Sin[x], x]] जैसी कुछ चीज़ों की अनुमति देता है, जो संभवतः आपके द्वारा लक्षित कुछ नहीं है। fact[n_Integer] का उपयोग करना अधिक सटीक है, और fact फ़ंक्शन को जिस तरह से आप चाहते हैं उसे कार्य करने की अनुमति देगा।

आप इस समारोह भी बेहतर परिभाषित करना चाहते हैं, तो आप की तरह कुछ कर सकते हैं:

Clear[fact] 
fact::nicetrybuddy = "fact[``] is not defined."; 
fact[0] = 1 
fact[n_Integer?Positive] := n fact[n - 1] 
fact[n_] := (Message[fact::nicetrybuddy, n]; $Failed) 

ताकि fact["x"] की तरह कुछ एक संदेश के साथ असफल हो जायेगी:

fact::nicetrybuddy: fact[x] is not defined. 
+0

कैच-ऑल क्लॉज जोड़ने का अच्छा विचार! मुझे वह याद रखना होगा। – nanitous

1

अन्य उत्तर सही हैं : fact इसकी तर्क बदलने से पहले मूल्यांकन करता है। आवश्यक मुद्दा यह है कि आपने दिमाग में पूर्णांक इनपुट के साथ fact परिभाषित किया है, और गैर-पूर्णांक इनपुट के लिए टर्मिनल स्थिति प्रदान नहीं की है। यदि आप के बजाय

Clear[fact] 
fact[0] = 1 
fact[n_Integer?Positive] := n fact[n - 1] 

तब किया fact unevaluated रह जायेंगे जब तक यह कुछ ऐसा है जो एक सकारात्मक पूर्णांक का मिलान नहीं हुआ था।

Evaluate में आपको अपने प्रतिस्थापन कथन को लपेटने की आवश्यकता हो सकती है ताकि उसके तर्क को बदलने के बाद fact की परिभाषा को आग लगाना पड़े।

# fact[#-1]& @ 2 

कि समय से पहले का मूल्यांकन नहीं करना चाहिए:

एक वैकल्पिक दृष्टिकोण एक शुद्ध फ़ंक्शन का उपयोग हो सकता है।

+0

मैं अभी एक बड़ा सिमुलेशन चला रहा हूं (400,000 होड्रिक-प्रेस्कॉट फ़िल्टर!) इसलिए मैंने शुद्ध फ़ंक्शन के साथ उस अंतिम सुझाव की जांच नहीं की है। – Verbeia

+0

मैंने इसे माना। लेकिन मैंने विभिन्न पुनरावर्ती कार्यों के साथ प्रयोग किया है, उदाहरण के लिए सूचियों के लिए। और मैं वही व्यवहार से मिला। इसलिए मैंने सवाल को सामान्य के रूप में पोस्ट किया जैसा मैं कर सकता था। लेकिन एक उदाहरण चीजों को फिर से विशिष्ट बनाता है। उसके लिए खेद है। – nanitous

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