我正在研究物理学,目前正在评估有关放射性的实验。我测量了具有不同激活时间的银的活性,并测量了正常的环境辐射,因此数据是“随时间而变化的每秒衰减”。
现在,我需要一次为所有数据添加一个函数,其形式取决于我使用的激活时间。我想用scipy.curve_fit做到这一点,所以我可以使用Marquardt-Levenberg方法,但是我不知道如何告诉函数当前的激活时间,因为fit函数可能只有一个自由变量和参数适合。
我尝试了两种失败的方法。为了一次拟合所有数据,我首先将所有测量的x和y值的所有数组连接到两个数组。我的第一个想法是提供一个全局变量,该变量显示我们正在使用什么激活时间,并且每次当前时间小于最后一次时间时都会更改该激活时间,因此每次下一次测量都将被更改。但这没有用,因为curve_fit似乎将整个数组带入函数,而不是将所有元素一一对应。 有了这些知识,我的第二次尝试就是仅使用切片来显示该函数,它应该使用数据的哪一部分,但这引发了错误“ numpy.float64”对象无法解释为整数”。
拳头尝试
m = 1
t0 = 0
def f(t, n_A1, n_A2, n_A4, n_A8, n_B1, n_B2, n_B4, n_B8, n_null, T_A, T_B):
global m
global t0
if t < t0:
m += 1
t0 = t
if m == 1:
return n_A1 * exp(-ln(2)/T_A * t) + n_B1 * exp(-ln(2)/T_B * t) + n_null
elif m == 2:
return n_A2 * exp(-ln(2)/T_A * t) + n_B2 * exp(-ln(2)/T_B * t) + n_null
elif m == 3:
return n_A4 * exp(-ln(2)/T_A * t) + n_B4 * exp(-ln(2)/T_B * t) + n_null
elif m == 4:
return n_A8 * exp(-ln(2)/T_A * t) + n_B8 * exp(-ln(2)/T_B * t) + n_null
elif m == 5:
return n_null
time = array(list(x1) + list(x2) + list(x4) + list(x8) + list(x0))
N = array(list(y1) + list(y2) + list(y4) + list(y8) + list(y0))
popt, pcov = curve_fit(f,time,N)
第二次尝试:
t0 = [1 for i in t[146:]]
def f(t, n_A1, n_A2, n_A4, n_A8, n_B1, n_B2, n_B4, n_B8, n_null, T_A, T_B):
return array(list(n_A1 * exp(-log(2)/T_A * t[:31]) + n_B1 * exp(-log(2)/T_B * t[:31]) + n_null) + list(n_A2 * exp(-log(2)/T_A * t[31:64]) + n_B2 * exp(-log(2)/T_B * t[31:64]) + n_null) + list(n_A4 * exp(-log(2)/T_A * t[64:98]) + n_B4 * exp(-log(2)/T_B * t[64:98]) + n_null) + list(n_A8 * exp(-log(2)/T_A * t[98:146]) + n_B8 * exp(-log(2)/T_B * t[98:146]) + n_null) + list(n_null * t0))
time = array(list(x1) + list(x2) + list(x4) + list(x8) + list(x0))
N = array(list(y1) + list(y2) + list(y4) + list(y8) + list(y0))
popt, pcov = curve_fit(f,time,N)