我正在尝试拟合交通灯曲线的参数。
我观察到了过渡光曲线数据,我在python中使用了.py,它通过4个参数(周期,a(半长轴),倾斜度,行星半径)返回了模型过渡光曲线。我想最小化这两条光曲线之间的残差。这就是我要做的事情:首先-使用method =“ L-BFGS-B”估计最大似然,然后使用emcee应用mcmc来估计不确定性。
代码:
p = lmfit.Parameters()
p.add_many(('per', 2.), ('inc', 90.), ('a', 5.), ('rp', 0.1))
per_b = [1., 3.]
a_b = [4., 6.]
inc_b = [88., 90.]
rp_b = [0.1, 0.3]
bounds = [(per_b[0], per_b[1]), (inc_b[0], inc_b[1]), (a_b[0], a_b[1]), (rp_b[0], rp_b[1])]
def residual(p):
v = p.valuesdict()
eclipse.criarEclipse(v['per'], v['a'], v['inc'], v['rp'])
lc0 = numpy.array(eclipse.getCurvaLuz()) (observed flux data)
ts0 = numpy.array(eclipse.getTempoHoras()) (observed time data)
c = numpy.linspace(min(time_phased[bb]),max(time_phased[bb]),len(time_phased[bb]),endpoint=True)
nn = interpolate.interp1d(ts0,lc0)
return nn(c) - smoothed_LC[bb] (residual between the model and the data)
在def残差(p)内,我确保所观察到的数据(time_phased [bb]和smoothed_LC [bb])具有与模型过渡光曲线相同的大小。我希望它为我提供最适合参数的值(v ['per'],v ['a'],v ['inc'],v ['rp'])。
我需要您的帮助,感谢您的宝贵时间和关注。亲切的问候,尤里。
答案 0 :(得分:0)
您的示例不完整,包含许多局部概念和一些无效的Python。这使您很难理解您的意图。如果下面的答案还不够,请使用完整的示例更新您的问题。
很显然,您希望使用某种模型来对数据smoothed_LC[bb]
(不确定bb
是什么)进行建模,以产生某种日蚀效果。基于这种假设,我建议使用lmfit.Model
方法。首先编写一个对数据进行建模的函数,以便检查并绘制模型。我不能完全确定我了解您所做的一切,但是此模型函数可能看起来像这样:
import numpy
from scipy import interpolate
from lmfit import Model
# import eclipse from somewhere....
def eclipse_lc(c, per, a, inc, p):
eclipse.criarEclipse(per, a, inc, rp)
lc0 = numpy.array(eclipse.getCurvaLuz()) # observed flux data
ts0 = numpy.array(eclipse.getTempoHoras()) # observed time data
return interpolate.interp1d(ts0,lc0)(c)
使用此模型功能,您可以构建模型:
lc_model = Model(eclipse_lc)
,然后为您的模型构建参数。这将自动以模型函数的参数名称命名它们。在这里,您还可以为其指定初始值:
params = lc_model.make_params(per=2, inc=90, a=5, rp=0.1)
您想在这些参数上设置上限和下限。这是通过设置min
和max
参数来完成的,而不是对边界进行有序排列:
params['per'].min = 1.0
params['per'].max = 3.0
,依此类推。而且:设置如此严格的界限通常不是一个好主意。设置边界以避免非自然的参数值,或者当您明显需要放置它们时。
现在,您可以使用此模型拟合数据。好吧,首先,您需要获取要建模的数据。从您的示例来看,这似乎不太清楚,但是也许:
c_data = numpy.linspace(min(time_phased[bb]), max(time_phased[bb]),
len(time_phased[bb]), endpoint=True)
lc_data = smoothed_LC[bb]
嗯:为什么需要制作这个c_data
?为什么不只使用time_phased
作为自变量?无论如何,现在您可以使用参数使数据适合模型:
result = lc_model(lc_data, params, c=c_data)
这时,您可以打印出结果报告和/或查看或获取最适合的数组:
print(result.fit_report())
for p in result.params.items(): print(p)
import matplotlib.pyplot as plt
plt.plot(c_data, lc_data, label='data')
plt.plot(c_data. result.best_fit, label='fit')
plt.legend()
plt.show()
希望有帮助...