这是我的问题:我有实验数据以适应模型。为此,我使用了scipy中的curve_fit。脚本没有任何错误或警告,但没有给出令人满意的结果(它给了我一条准线而不是两个洛伦兹形图)。
但最奇怪的是,当我给拟合函数一个猜测数组时,没有任何猜测的参数被修改,除了第三个(尽管它远离预期的值)。但是我注意猜测参数的顺序。
我给你一些合适的代码。
X = 927.
Z = 88.
M = 5.e-15
O1 = 92975.
O2 = 93570.
bm = np.arctan2(Z,X)
P0 = 0.
T = np.pi/2.
TM = np.pi/3.
G = 20.
File ="Data.txt"
open(File, "rb")
dat = np.loadtxt(File)
O = dat[:,1]
D = np.sqrt(1./20. *10**(dat[:,7]/10.)*1/((X**2+Z**2)*10**(6)))
def model(W,o1,o2,p0,t,tm,g):
DB = np.abs((1./M)*(np.cos(bm-tm)*(p0*np.cos(t-tm)/(o1**2-W**2-1.j*g*W))+np.sin(bm-tm)*(p0*np.sin(t-tm)/((o2**2-W**2-1.j*g*W)))))
return DB
guess = np.array([O1,O2,P0,T,TM,G])
fit , pcov = curve_fit(model, O , D , guess)
我在整个月内搜索一项研究,以发现任何错误,但仍然注意到。函数是否可能为curve_fit复杂化?
提前感谢您的帮助。如果您需要更多信息或数据,请不要犹豫
以下是O
v D
的情节。红点是实验,蓝线是返回拟合参数的函数(未修改,因此它们是猜测值)
答案 0 :(得分:0)
很难说出常量和非常长公式的混合情况。但有几点需要考虑:
如果变量没有从初始值改变,则应该注意缩放。你的X**2+Z**2)*10**(6)
将在1e16左右,这可能会使得很难做出好的数字导数。你可能需要修改发送到epsfcn
的{{1}}的值。
看起来你的模型函数计算一个复杂的数组。我相信curve_fit()只能处理严格的实数值。
您可能会发现leastsq()
模块很有用。
答案 1 :(得分:0)
好的人,谢谢你,我终于找到了解决方案!
而不是使用curve_fit
,我尝试在this tutorial之后直接使用leastsq
以查看会发生什么。它的效果比预期的要好,因为拟合确实成功并且给了我正确的峰值位置和振幅。我给你纠正的代码,因为它对我有用。
X = 927.0
Z = 88.
M = 5.e-15
O1 = 92975.
O2 = 93570.
bm = np.arctan2(Z,X)
P0=1.e-12
T=np.pi/2.
TM=np.pi/3.
G=20.
File ="Data.csv"
open(File, "rb")
dat = np.loadtxt(File)
O = dat[:,1]
D = np.sqrt(1/1000. *10**(dat[:,7]/10.)*50.*1/((X**2+Z**2)*10**(6)))
def resid(p, y, W) :
o1,o2,p0,t,tm,g = p
err=y-(np.abs((1./M)*(np.cos(bm-tm)*(p0*np.cos(t-tm)/(o1**2-W**2-1.j*g*W))+np.sin(bm-tm)*(p0*np.sin(t-tm)/((o2**2-W**2-1.j*g*W))))))
return err
def peval(W,p) :
return np.abs((1./M)*(np.cos(bm-p[4])*(p[2]*np.cos(p[3]-p[4])/(p[0]**2-W**2-1.j*p[5]*W))+np.sin(bm-p[4])*(p[2]*np.sin(p[3]-p[4])/((p[1]**2-W**2-1.j*p[5]*W)))))
guess = np.array([O1,O2,P0,T,TM,G])
plsq = leastsq(resid,guess,args=(D,O))
print plsq[0]
plt.yscale('log')
再次感谢您的关注