简体   繁体   English

指数衰减拟合

[英]exponential decay fitting

I am trying to fit some data that are distributed in the time following an exponential decay. 我正在尝试拟合指数衰减后随时间分布的一些数据。 I tried to follow some fitting examples on the web, but my code doesn't fit the data. 我尝试在网络上遵循一些合适的示例,但是我的代码不适合数据。 Only a straight line results from the fit. 拟合仅产生一条直线。 Maybe there is something wrong with the initial parameters? 初始参数可能有问题吗? Until now I have only used gaussian and line fits, using the same method, that maybe is not correct for this case. 到现在为止,我只使用高斯拟合和线拟合,并且使用相同的方法,这种情况可能不正确。 The code take the data from the web, so it is directly executable. 代码从网络上获取数据,因此可以直接执行。 Question: why doesn't the code result in any fit? 问题:为什么代码不适合? Many thanks in advance. 提前谢谢了。

#!/usr/bin/env python

import pyfits, os, re, glob, sys
from scipy.optimize import leastsq
from numpy import *
from pylab import *
from scipy import *

rc('font',**{'family':'serif','serif':['Helvetica']})
rc('ps',usedistiller='xpdf')
rc('text', usetex=True)
#------------------------------------------------------

tmin = 56200
tmax = 56249

data=pyfits.open('http://heasarc.gsfc.nasa.gov/docs/swift/results/transients/weak/GX304-1.orbit.lc.fits')
time  = data[1].data.field(0)/86400. + data[1].header['MJDREFF'] + data[1].header['MJDREFI']
rate  = data[1].data.field(1)
error = data[1].data.field(2)
data.close()

cond = ((time > 56210) & (time < 56225))
time = time[cond]
rate = rate[cond]
error = error[cond]

right_exp = lambda p, x: p[0]*exp(-p[1]*x)
err = lambda p, x, y:(right_exp(p, x) -y)
v0= [0.20, 56210.0, 1]
out = leastsq(err, v0[:], args = (time, rate), maxfev=100000, full_output=1)
v = out[0] #fit parameters out
xxx = arange(min(time), max(time), time[1] - time[0])
ccc = right_exp(v, xxx)
fig = figure(figsize = (9, 9)) #make a plot
ax1 = fig.add_subplot(111)
ax1.plot(time, rate, 'g.') #spectrum
ax1.plot(xxx, ccc, 'b-') #fitted spectrum
savefig("right exp.png")

axis([tmin-10, tmax, -0.00, 0.45])

Your problem is ill conditioned because your array times contains big numbers that when used in exp(-a*time) are giving values close to 0. , which tricks the err function because your rate array contains small values also close to 0. , leading to small errors. 您的问题是病态的,因为您的数组times包含大数,而在exp(-a*time)中使用时,它们给出的值接近0. ,这会欺骗err函数,因为您的rate数组还包含也接近0.小值。小错误。 In other words, a high a in the exponential function gives a good solution. 换句话说,高a的指数函数给出了一个很好的解决方案。

To fix that you can: 要解决此问题,您可以:

  • change your decay function to include an initial time: 更改衰减函数以包括初始时间:
    exp(-a*(time-time0))
  • change your input data to start from a smaller number: 更改输入数据以从较小的数字开始:
    time -= time.min()

For both options you have to change the initial guess v0 , eg v0=[0.,0.] . 对于这两个选项,您都必须更改初始猜测v0 ,例如v0=[0.,0.] The first solution seems more robust and you do not have to manage changes in your time array. 第一个解决方案似乎更可靠,您不必管理time序列中的更改。 A good initial guess for time0 is time.min() : time0一个很好的初始猜测是time.min()

right_exp = lambda p, x: p[0]*exp(-p[1]*(x-p[2]))
err = lambda p, x, y:(right_exp(p, x) -y)
v0= [0., 0., time.min() ]
out = leastsq(err, v0, args = (time, rate))
v = out[0] #fit parameters out
xxx = arange(min(time), max(time), time[1] - time[0])
ccc = right_exp(v, xxx)
fig = figure(figsize = (9, 9)) #make a plot
ax1 = fig.add_subplot(111)
ax1.plot(time, rate, 'g.') #spectrum
ax1.plot(xxx, ccc, 'b-') #fitted spectrum
fig.show()

Giving: 赠送:

在此处输入图片说明

Still, the final results are depending on v0 , eg with v0=[1.,1.,time.min()] it decays too fast and does not find the optimum. 尽管如此,最终结果仍取决于v0 ,例如v0=[1.,1.,time.min()]它衰减太快而找不到最佳值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM