[英]Recursive Function Help (Python)
好的,我已經使用遞歸函數創建了一個函數,如下所示。
global totalExposure
totalExposure = 0
def f(x):
import math
return 10 * math.e**(math.log(0.5)/5.27 * x)
def radiationExposure(start, stop, step):
time = (stop-start)
newStart = start+step
if(time!=0):
radiationExposure(newStart, stop, step)
global totalExposure
radiation = f(start) * step
totalExposure += radiation
return totalExposure
else:
return totalExposure
現在,當我輸入整數值時,該函數可以正常工作。
rad = radiationExposure(0, 5, 1)
# rad = 39.1031878433
但是,當我輸入小數點的值時,函數會給出錯誤的值。 那么,如何使我的函數也可以使用小數?
例如:
rad = radiationExposure(0, 4, 0.25)
您的輸出:1217.5725783047335正確的輸出:1148.6783342153556
我最初回答這是floordiv
的錯,然后我認為這是浮點偽造,現在我認為這只是錯誤的代碼。 讓我們再深入一點,好嗎?
首先,如果您在代碼中看到過global
,請嘗試非常困難以擺脫它。 它總是導致這樣的錯誤代碼。 讓我們在沒有global
...的情況下重寫它。
import math
def f(x):
return 10 * math.e**(math.log(0.5)/5.27 * x)
def radiationExposure(start, stop, step):
totalExposure = 0
while stop-start > 0:
totalExposure += f(start)*step # I dont' know this formula, but this
# feels wrong -- maybe double check the
# math here?
start += step
return totalExposure
這實際上也設法擺脫了遞歸,這將節省大量的內存。
### DEMO ###
>>> radiationExposure(0,5,1)
39.10318784326239
>>> radiationExposure(0,4,0.25)
31.61803641252657
我看到的問題是您的global
變量在函數的遞歸和調用之間被保存。 當我第一次運行您的代碼時,我得到:
>>> radiationExposure(0,5,1)
39.10318784326239
>>> radiationExposure(0,5,1)
78.20637568652478
這顯然是錯誤的。 更不用說,遞歸公式應該自己調用,但是它們傾向於在return
語句中調用! 遞歸地寫這個就像:
def radiationExposure(start, stop, step):
time = stop-start
new_start = start+step
radiation = f(start)*step
if time <= 0: # <= accounts for something like (0, 3, 0.33) where it will never EXACTLY hit zero
return radiation
# if we're on the last tick, return one dose of radiation
else:
return radiation + radiationExposure(newStart,stop,step)
# otherwise, return one dose of radiation plus all following doses
首先,校正后的歐拉積分方法可以保證從頭到尾真正地進行積分,並且如果浮點誤差加起來,則確實會在停止ε處添加一個附加積分點(大小為step,將積分間隔更改為stop + step結束)。針對這種情況。
回想一下,微分方程y'(x)= f(x,y(x)),y(x0)= y0的Euler積分通過重復計算來進行
y=y+h*f(x,y)
x=x+h
在純積分問題中,f中沒有y,因此將f(x)從a積分到b從而初始化y = 0並反復應用
y=y+h*f(x)
x=x+h
只要x小於b。 在最后一步中,當bh <= x <= b時,設置h = bx,以使積分過程精確地以(浮點)x = b結束。
import math
def f(x):
return 10 * math.exp(math.log(0.5)/5.27 * x)
def radiationExposure(start, stop, step):
totalExposure = 0
while stop-start > 0:
if stop-start < step:
step = stop-start;
totalExposure += f(start)*step
start += step
return totalExposure
if __name__ == "__main__":
print radiationExposure(0,5,1);
print radiationExposure(0,5,0.25);
print radiationExposure(0,5,0.1);
print radiationExposure(0,5,0.01);
更好的解決方案是使用numpy的數字積分例程。
甚至更好的是,通過反導數F(x)= C / A * exp(C * A)實際上知道該函數f(x)= C * exp(A * x)的積分,以便值是R(start,stop)= F(stop)-F(start),所以
import math
def radiationExposure2(start, stop, dummy):
A=math.log(0.5)/5.27;
C=10
return C/A*(math.exp(A*stop)-math.exp(A*start))
if __name__ == "__main__":
print radiationExposure2(0,5,1);
print radiationExposure2(0,5,1);
返回的值用於Euler積分
39.1031878433 (step=1)
37.2464645611 (step=0.25)
36.8822478677 (step=0.1)
36.6648587685 (step=0.01)
與精確積分的數值
36.6407572458
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.