在Python中用多变量将数据拟合到互补误差函数

在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

在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.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()