以变量为积分限值的非线性最小二乘拟合
non linear least square fitting with the variable as the integration limit
我正在尝试使用 python 进行一些非线性拟合,其中涉及积分,积分的限制取决于自变量。代码如下:
import numpy as np
import scipy as sc
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.integrate import quad
T,M=np.genfromtxt("zfc.txt", unpack=True, skiprows = 0) #here I load the data to fit
plt.plot(T,M,'o')
def arg_int1(x,sigma,Ebm):
return (1/(np.sqrt(2*np.pi)*sigma*Ebm))*np.exp(-(np.log(x/float(Ebm))**2)/(2*sigma**2))
def arg_int2(x,sigma,Ebm):
return (1/(np.sqrt(2*np.pi)*sigma*x))*np.exp(-(np.log(x/float(Ebm))**2)/(2*sigma**2))
def zfc(x,k1,k2,k3):
Temp=x*k2*27/float(k2/1.36e-16)
#Temp=k2*27/float(k2/1.36e-16) #apparently x can't be fitted with curve_fit if appears as well in the integral limits
A=sc.integrate.quad(arg_int1,0,Temp,args=(k3,k2))[0]
B=sc.integrate.quad(arg_int2,Temp,10*k2,args=(k3,k2))[0]
M=k1*(k2/1.36e-16*A/x+B)
return M
T_fit=np.linspace(1,301,301)
popt, pcov = curve_fit(zfc,T,M,p0=(0.5,2.802e-13,0.46))
M_fit=np.zeros(301)
M_fit[0]=zfc(100,0.5,2.8e-13,0.46)
for i in range (1,301):
M_fit[i-1]=zfc(i,popt[0],popt[1],popt[2])
plt.plot(T_fit,M_fit,'g')
我得到的错误是:
File "C:\Users\usuario\Anaconda\lib\site-packages\scipy\integrate\quadpack.py", line 329, in _quad
if (b != Inf and a != -Inf):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我不明白,因为函数定义明确。我知道我的问题的解决方案是提供的参数(我已经适应了 mathematica)。我试图寻找 Bloch-Gruneisen 函数的拟合(其中自变量也定义了积分限制)但我没有找到任何线索。
问题是 scipy.optimize.curve_fit
期望 zfc
对数组参数起作用,即给定一个 x 值的 n 数组和 k1
的 3 个 n 数组,k2
,k3
值 zfc(x,k1,k2,k3)
应该 return 一个包含相应函数值的 n 数组。然而,这可以通过使用 np.vectorize
:
为函数创建包装器来轻松实现
zfc_wrapper = np.vectorize(zfc)
popt, pcov = curve_fit(zfc_wrapper,T,M,p0=(0.5,2.802e-13,0.46))
下次如果您能提供一些样本输入数据就更好了。我设法 运行 它使用来自某个任意函数的测试数据,但情况可能并非总是如此。
干杯。
我正在尝试使用 python 进行一些非线性拟合,其中涉及积分,积分的限制取决于自变量。代码如下:
import numpy as np
import scipy as sc
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.integrate import quad
T,M=np.genfromtxt("zfc.txt", unpack=True, skiprows = 0) #here I load the data to fit
plt.plot(T,M,'o')
def arg_int1(x,sigma,Ebm):
return (1/(np.sqrt(2*np.pi)*sigma*Ebm))*np.exp(-(np.log(x/float(Ebm))**2)/(2*sigma**2))
def arg_int2(x,sigma,Ebm):
return (1/(np.sqrt(2*np.pi)*sigma*x))*np.exp(-(np.log(x/float(Ebm))**2)/(2*sigma**2))
def zfc(x,k1,k2,k3):
Temp=x*k2*27/float(k2/1.36e-16)
#Temp=k2*27/float(k2/1.36e-16) #apparently x can't be fitted with curve_fit if appears as well in the integral limits
A=sc.integrate.quad(arg_int1,0,Temp,args=(k3,k2))[0]
B=sc.integrate.quad(arg_int2,Temp,10*k2,args=(k3,k2))[0]
M=k1*(k2/1.36e-16*A/x+B)
return M
T_fit=np.linspace(1,301,301)
popt, pcov = curve_fit(zfc,T,M,p0=(0.5,2.802e-13,0.46))
M_fit=np.zeros(301)
M_fit[0]=zfc(100,0.5,2.8e-13,0.46)
for i in range (1,301):
M_fit[i-1]=zfc(i,popt[0],popt[1],popt[2])
plt.plot(T_fit,M_fit,'g')
我得到的错误是:
File "C:\Users\usuario\Anaconda\lib\site-packages\scipy\integrate\quadpack.py", line 329, in _quad
if (b != Inf and a != -Inf):
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
我不明白,因为函数定义明确。我知道我的问题的解决方案是提供的参数(我已经适应了 mathematica)。我试图寻找 Bloch-Gruneisen 函数的拟合(其中自变量也定义了积分限制)但我没有找到任何线索。
问题是 scipy.optimize.curve_fit
期望 zfc
对数组参数起作用,即给定一个 x 值的 n 数组和 k1
的 3 个 n 数组,k2
,k3
值 zfc(x,k1,k2,k3)
应该 return 一个包含相应函数值的 n 数组。然而,这可以通过使用 np.vectorize
:
zfc_wrapper = np.vectorize(zfc)
popt, pcov = curve_fit(zfc_wrapper,T,M,p0=(0.5,2.802e-13,0.46))
下次如果您能提供一些样本输入数据就更好了。我设法 运行 它使用来自某个任意函数的测试数据,但情况可能并非总是如此。
干杯。