如何解决在 Python 中使用多个变量将数据拟合到互补误差函数
我无法将实验数据拟合到 Python 3.7.4 中的互补误差函数。
import matplotlib.pyplot as plt
import math
import numpy as np
from scipy import optimize
from scipy import integrate
with open('C:Path\\Data\\test.txt','r') as f:
lines = f.readlines()
x = [float(line.split(',')[0]) for line in lines]
y = [float(line.split(',')[1]) for line in lines]
int_start = 35
int_end = 75
start = float(x[int_start])
end = float(x[int_end])
x_data = np.linspace(start,end,(int_end-int_start)+1)
y_data = y[int_start: int_end+1]
def integrand(x,a,b,c):
return a*np.exp(((-1)*(x-b)**2)/(2*(c**2)))
def cerf(x,c):
return integrate.quad(integrand,x,np.inf)
params,params_covariance = optimize.curve_fit(cerf,x_data,y_data)
plt.plot(x_data,y_data,'x',label='Data')
plt.plot(x_data,integrand(x_data,params[0],params[1],params[2]),'-',label="fit")
plt.legend(loc='best')
plt.show()
更准确地说,我想将我的数据拟合到由 integrand
函数组成的互补误差函数,参数为 a
、b
、c
和 { {1}} 函数进行实际集成。积分应该从 x(函数的参数)到 +infinity。之后,我想使用 cerf
中的标准 curve_fit
。但现在我收到如下值错误:
scipy
如果有人知道如何使用 x 参数作为积分的下界来拟合函数,我会非常感激。
数据如下:
> ValueError Traceback (most recent call last)
<ipython-input-33-8130a3eb44bb> in <module>
29 return integrate.quad(integrand,np.inf)
30
---> 31 params,y_data)
~\AppData\Roaming\Python\Python37\site-packages\scipy\integrate\quadpack.py in quad(func,args,full_output,epsabs,epsrel,limit,points,weight,wvar,wopts,maxp1,limlst)
346
347 # check the limits of integration: \int_a^b,expect a < b
--> 348 flip,b = b < a,min(a,b),max(a,b)
349
350 if weight is None:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
解决方法
根据文档,scipy.integrate.quad 不接受数组,也不能调用带参数的函数。因此,我们必须在由 f
寻址的函数内构造一个辅助函数 scipy.curve_fit
:
import matplotlib.pyplot as plt
import numpy as np
from scipy import optimize,integrate
#define a function that integrates or evaluates f depending on the Boolean flag func_integr
def cerf(x,a,b,c,func_integr=True):
f = lambda x: a*np.exp(((-1)*(x-b)**2)/(2*(c**2)))
#flag is preset to True,so will return the integrated values
if func_integr:
return np.asarray([integrate.quad(f,i,np.inf)[0] for i in x])
#unless the flag func_integr is set to False,then it will return the function values
else:
return f(x)
#read file
arr=np.genfromtxt("test.txt",delimiter=",")
x_data = arr[:,0]
y_data = arr[:,1]
#provide reasonable start values...
start_p = [1,-1]
#...for scipy.curve_fit
params,params_covariance = optimize.curve_fit(cerf,x_data,y_data,p0=start_p)
print(params)
#[ 2.26757666 0.56501062 -0.0704476 ]
#plot our results
plt.plot(x_data,'x',label='Data')
plt.plot(x_data,cerf(x_data,*params),'-',label="fit")
plt.legend(loc='best')
plt.show()
示例输出:
这种方法不是最快的 - 每个 x 值都是单独集成的。也许还有其他 scipy.integrate
函数可以处理 numpy 数组;我不知道。
评估 f
而不是其积分值的部分在这里并不是真正必要的。但我最初使用它来验证 cerf
是否按预期工作,所以我将它留在脚本中。
曲线的形状看起来更像逻辑而非高斯。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。