2015-03-02 98 views
1

我想用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') 

的eror,我得到的是:

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

我不明白,既然功能是明确界定。我知道我的问题的解决方案是feeded参数(我已经适合mathematica)。我试图寻找Bloch-Gruneisen函数的拟合(自变量也定义了积分极限),但我没有找到任何线索。

回答

1

的问题是,scipy.optimize.curve_fit预计zfc对数组参数工作,即给定的x值的n阵列和​​3 N阵列,k2k3zfc(x,k1,k2,k3)应返回包含n阵列对应函数的值。这可以很容易但是通过使用np.vectorize函数创建一个包装来实现:

zfc_wrapper = np.vectorize(zfc) 
popt, pcov = curve_fit(zfc_wrapper,T,M,p0=(0.5,2.802e-13,0.46)) 

下一次,这将是很好,如果你能提供一些样本输入数据。我设法使用一些任意函数的测试数据来运行它,但这可能并非总是如此。

干杯。