在Python中用多变量将数据拟合到互补误差函数
在Python3.7.4中,我很难将实验数据拟合到互补错误函数中在Python中用多变量将数据拟合到互补误差函数,python,numpy,scipy,integration,curve-fitting,Python,Numpy,Scipy,Integration,Curve Fitting,在Python3.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.spli
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, a, b, 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()
更准确地说,我想将我的数据拟合到互补误差函数,该函数由被积函数
函数和参数a
、b
、c
,以及执行实际积分的cerf
函数组成。积分应该从x(函数的参数)到+无穷大。之后,我想从scipy
使用标准curve\u-fit
。但现在我得到一个值错误,如下所示:
> ValueError Traceback (most recent call last)
<ipython-input-33-8130a3eb44bb> in <module>
29 return integrate.quad(integrand, x, np.inf)
30
---> 31 params, params_covariance = optimize.curve_fit(cerf, x_data, y_data)
~\AppData\Roaming\Python\Python37\site-packages\scipy\integrate\quadpack.py in quad(func, a, b, 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, a, 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()
曲线的形状看起来更像逻辑曲线而不是高斯曲线
根据文档,它不接受数组,并且不能调用带有参数的函数。因此,我们必须在函数中构造一个辅助函数
f
,该函数由scipy.curve\u 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, 0, -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, y_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
是否按预期工作,所以我把它留在了脚本中。你能给这个问题添加一个有代表性的数据示例吗?不,它应该是互补误差函数,因为当我用刀口切割高斯光束时,我正在测量光电二极管上的电压。我想找出梁的浪费。这里也有:非常感谢!!对我有用。
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, 0, -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, y_data, 'x', label='Data')
plt.plot(x_data, cerf(x_data, *params), '-', label="fit")
plt.legend(loc='best')
plt.show()