2

我能够使用peak-o-mat将曲线拟合到 ax/y 数据集,如下所示。那是一个线性背景和 10 条洛伦兹曲线。 Peak-o-mat 结果

因为我需要拟合许多相似的曲线,所以我使用mpfit.py编写了一个脚本拟合例程,它是一种 Levenberg-Marquardt-Algorithm。然而,拟合需要更长的时间,而且在我看来,它不如 peak-o-mat 结果准确:

起始值 起始值

使用固定线性背景拟合结果(取自 peak-o-mat 结果的线性背景值) 适合固定

适合所有变量的结果 不合身

我相信起始值已经非常接近,但即使使用固定的线性背景,左洛伦兹显然是拟合的退化。

对于完全自由贴合,结果更糟。

Peak-o-mat 似乎使用scipy.odr.odrpack。现在更有可能的是:

  1. 我做了一些实现错误?
  2. odrpack 更适合这个特殊问题?

拟合一个更简单的问题(中间有一个峰值的线性数据)显示 peak-o-mat 和我的脚本之间的相关性非常好。我也没有找到很多关于 ordpack 的信息。

编辑:看来我可以自己回答这个问题,但是答案有点令人不安。使用 scipy.odr (允许使用 odr 或 leastsq 方法拟合)都将结果作为 peak-o-mat ,即使没有约束。

下图再次显示了数据、起始值(几乎完美),然后是 odr 和 leastsq 拟合。分量曲线是针对 odr 的

scipy.odr

我将切换到 odr,但这仍然让我感到不安。方法(mpfit.py、scipy.optimize.leastsq、scipy.odr in leastsq 模式)“应该”产生相同的结果。

对于偶然发现这篇文章的人:要进行 odr 拟合,必须为 x 和 y 值指定错误。如果没有错误,请使用 sx << sy 的小值。

linear = odr.Model(f)
mydata = odr.RealData(x, y, sx = 1e-99, sy = 0.01)
myodr = odr.ODR(mydata, linear, beta0 = beta0, maxit = 2000)
myoutput1 = myodr.run() 
4

1 回答 1

1

您也可以使用 peak-o-mat 进行脚本编写。最简单的方法是创建包含您希望通过 GUI 拟合的所有数据的项目,对其进行清理、转换并将其附加(即选择一个模型,提供初始猜测并拟合)基本模型到其中一组。然后,您可以(深度)复制该模型并将其附加到所有其他数据集。试试这个:

from peak_o_mat.project import Project
from peak_o_mat.fit import Fit
from copy import deepcopy

p = Project()
p.Read('in.lpj')

base = p[2][0]    # this is the set which has been fit already

for data in p[2][1:]: # all remaining sets of plot number 2

    mod = deepcopy(base.mod)
    data.mod = mod

    f = Fit(data, data.mod)
    res = f.run()

    pars = res[0]
    err = res[1]

    data.mod._newpars(pars, err)

    print data.mod.parameters_as_table()

p.Write('out')

请告诉我,如果您需要更多详细信息。

于 2012-07-08T12:38:17.410 回答