好的,我使用递归函数创建了一个函数,如下所示。
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
答案 0 :(得分:0)
我原本回答说是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
被保存在函数的递归和BETWEEN CALLS之间。当我第一次运行你的代码时,我得到了:
>>> 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
答案 1 :(得分:0)
首先校正的Euler积分方法保证真正从开始到停止集成,并且如果浮点数在stop-epsilon(大小步长,将积分间隔改为停止+步骤结束)中添加额外的积分点错误总结了这种情况。
回想一下,微分方程y'(x)= f(x,y(x)),y(x0)= y0的Euler积分通过重复计算进行
y=y+h*f(x,y)
x=x+h
在纯积分问题中,f中没有y,从a到b积分f(x)因此初始化y = 0并重复应用
y=y+h*f(x)
x=x+h
只要x小于b。在最后一步中,当b-h <= x <= b时,设置h = b-x,使得积分过程以(浮点)精确地结束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 * exp(A * x)实际上是通过反导数F(x)= C / A * exp(C * A)得知的,使得值为R(开始,停止)= F(停止)-F(开始),所以
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