首页 文章

Python 2.7中的非线性拟合没有给出任何好的结果

提问于
浏览
0

这是我的问题:我有实验数据以适应模型 . 为此,我使用了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 的情节 . 红点是实验,蓝线是带有返回拟合参数的函数(未修改,因此它们是猜测值)

D = model(O)

enter image description here

2 回答

  • 0

    很难用常量和很长公式的混合来判断发生了什么 . 但有几点需要考虑:

    • 如果变量没有从初始值改变,则应该注意缩放 . 你的( X**2+Z**2)*10**(6) 将在~1e16左右,这可能使得很难做出好的数值导数 . 你可能需要修改发送到 leastsq()epsfcn 的值 .

    • 看起来你的模型函数计算一个复杂的数组 . 我相信curve_fit()只能处理严格的实数值 .

    您可能会发现 lmfit 模块很有用 .

  • 0

    好的人,谢谢你,我终于找到了解决方案!

    而不是使用 curve_fit ,我试图直接使用 leastsq 跟随this tutorial以查看会发生什么 . 它的效果比预期的要好,因为拟合确实成功并且给了我正确的峰值位置和振幅 . 我给你纠正的代码,因为它对我有用 .

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

    再次感谢您的关注

相关问题