2013-09-26 29 views
2

我必須編寫代碼來執行歐拉的近似方法爲diffeq類的步長爲.5和.1。當它是.5我的代碼運行良好,並提供近似值。然而,當它比0.5少幾乎所有的東西,我得到歐拉的方法在Python給RuntimeError

RuntimeError: maximum recursion depth exceeded in cmp 

如果我試着加大遞歸深度,我最終得到Segmentation fault: 11

這是代碼。請幫我弄清楚爲什麼我得到一個遞歸錯誤,或者如何改進代碼,所以遞歸較少。

import sys 
from pylab import * 
h=.4 
t=0 
dep=[] 
ind=[] 
def sqr(q): 
    return q*q 
def d(x,t): 
    return x+sqr(t)-2 
while t<=3: 
    def x(t): 
     if t==0: 
      return 1 
     else: 
      return x(t-h)+h*d(x(t-h),t) 
    dep.append(x(t)) 
    ind.append(t) 
    t+=h 
plot(ind,dep,'o') 
t=arange(0,3,.01) 
x=exp(t)-t*(t+2) 
plot(t,x,) 
title("Euler's Method for dx/dt=x+t^2-2") 
xlabel('t') 
ylabel('x') 
show() 

回答

0

你停止條件if t==0過於具體,因此,除非在某些點上反覆撞擊正是0,遞歸不會停止。

相反趕上t==0及以下,與t<=0

while t<=3: 
    def x(t): 
     if t<=0: 
      return 1 
0

您的問題是從浮點舍入誤差的到來。如果你通過調試器在一個點t = 1.1110223 e-16運行它,它不等於0,所以它開始無限地運行到負數。

我改變了比較

if t < 0.001: 

和程序實現的3.0

在一個不太重要的注意事項T的值收斂,聲明你的X(T):功能之外的循環,因爲它增加了額外的開銷,使你的else語句

delta = x(t-h) 
return delta + h*d(delta, t) 

,以便它不會爲每個numbe運行遞歸循環兩次河

+0

爲什麼<0.001,而不是<0?不是0.001只是在計算中添加一個錯誤,或者我錯過了什麼?看來這真的是「<」在這裏很重要。 – tom10

+0

<0會改變代碼的含義,它會在迭代中觸發大約爲0的中斷,並在下一次迭代中斷裂它。當然,我不知道算法,所以我可能是錯誤的意圖。 –

+0

我改變了t條件,現在運行時間更短。謝謝! – zeke21703