基于MINUIT的Python参数转换
我正在基于scipy的optimize.leastsq为2D数据编写一个自动曲线拟合例程,它可以正常工作。然而,当添加许多起始值很小的曲线时,我会得到非物理结果(例如负振幅) 我找到了这篇文章,并试图根据欧洲核子研究所的Minuit使用参数转换。在上面提到的问题中,有人提供了一些python代码的链接基于MINUIT的Python参数转换,python,constraints,scipy,bounds,Python,Constraints,Scipy,Bounds,我正在基于scipy的optimize.leastsq为2D数据编写一个自动曲线拟合例程,它可以正常工作。然而,当添加许多起始值很小的曲线时,我会得到非物理结果(例如负振幅) 我找到了这篇文章,并试图根据欧洲核子研究所的Minuit使用参数转换。在上面提到的问题中,有人提供了一些python代码的链接 code.google.com/p/nmrglue/source/browse/trunk/nmrglue/analysis/leastsqbound.py 我编写了这个最小的工作示例(扩展代码
code.google.com/p/nmrglue/source/browse/trunk/nmrglue/analysis/leastsqbound.py
我编写了这个最小的工作示例(扩展代码)
这是绘图输出,其中绿色表示开始条件,红色表示拟合结果:
这是正确的用法吗?External2如果超出边界,内部转换只会抛出一个nan。leastsq似乎能处理这个问题
我上传了拟合数据。只需粘贴到名为constraint.dat的文本文件中。已有一个流行的constraint.dat代码 使用python实现
我建议不要重新发明轮子 根据sega_sai的回答,我使用mpfit.py给出了这个最小的工作示例
import matplotlib.pyplot as plt
from mpfit import mpfit
import numpy as np
def _evaluate(p, x):
'''
Linear plus Lorentzian curve
p = list with three parameters ([a, b, I, Pos, FWHM])
'''
return p[0] + p[1] * x + p[2] / (1 + np.power((x - p[3]) / (p[4] / 2), 2))
def residuals(p, fjac = None, x = None, y = None, err = None):
status = 0
error = _evaluate(p, x) - y
return [status, error / err]
if __name__ == '__main__':
data = np.loadtxt('constraint.dat') # read data
x = data[:, 0]
y = data[:, 1]
err = 0 * np.ones(y.shape, dtype = 'float64')
parinfo = [{'value':5000., 'fixed':0, 'limited':[0, 0], 'limits':[0., 0.], 'parname':'a'},
{'value':0., 'fixed':0, 'limited':[0, 0], 'limits':[0., 0.], 'parname':'b'},
{'value':500., 'fixed':0, 'limited':[0, 0], 'limits':[0., 0.], 'parname':'I'},
{'value':2450., 'fixed':0, 'limited':[0, 0], 'limits':[0., 0.], 'parname':'Pos'},
{'value':3., 'fixed':0, 'limited':[0, 0], 'limits':[0., 0.], 'parname':'FWHM'}]
fa = {'x':x, 'y':y, 'err':err}
m = mpfit(residuals, parinfo = parinfo, functkw = fa)
print m
拟合结果如下:
mpfit.py: 3714.97545, 0.484193283, 2644.47271, 2440.13385, 22.1898496
leastsq: 3714.97187, 0.484194545, 2644.46890, 2440.13391, 22.1899295
结论:两种方法都有效,都允许约束。但由于mpfit来自一个非常成熟的来源,我更相信它。如果可用,它也会接受错误值。试试lmfit py-
谢谢你指出这一点。我以前没有找到任何关于mpfit的参考资料,它看起来正是我试图实现的目标。但是一个最小的工作示例会是什么样子呢?该用法与scipy的leastsq不同。似乎没有传递x和y值,而是传递引用?mpfit.py中的示例也不起作用。下面是一个肯定有效的示例:我使用了您链接的测试文件中的第一个示例来运行下面的解决方案。起初我有点困惑,因为它们使用起始值p0=[1,1],但在参数字典parinfo中,它们使用3.2和1.78。另外,调用中实际上不需要p0。请参见我的另一个:mpfit.py不适合。是的。
mpfit.py: 3714.97545, 0.484193283, 2644.47271, 2440.13385, 22.1898496
leastsq: 3714.97187, 0.484194545, 2644.46890, 2440.13391, 22.1899295