我正在尝试使用python中的lmfit
模块执行多参数拟合,但受某些参数组必须总和为1的约束。
e.g。假设我的卡方中有参数B1_0和B1_1,我为第一个设置了params.add('B1_0', value=0.5, min=0, max=1)
的参数,第二个设置了params.add('B1_1', expr='1-B1_0-B1_2')
。然后,我可以使用minimize
方法找到我的模型与数据的最佳拟合。
在我的代码中并不是这么简单;有许多自动生成的参数适合所以我使用这样的方法:
for term in listOfTerms:
con = constraint(term,listOfTerms) # finds the constraint (all sum to 1)
params.add(term,value=getValue(term),expr=con)
方法getValue(term)
返回另一个已知最小化卡方的拟合方法的值。当我尝试运行我的代码时,我收到如下错误消息:
Traceback (most recent call last):
File "/home/user/Desktop/MPhys/chisquare.py", line 123, in <module>
result = minimize(objfunc,params,args=(trans,sum_in,sum_out,data))
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 467, in minimize
iter_cb=iter_cb, scale_covar=scale_covar, **fit_kws)
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 92, in __init__
self.prepare_fit()
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 219, in prepare_fit
self.update_constraints()
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 122, in update_constraints
self.__update_paramval(name)
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 109, in __update_paramval
self.__update_paramval(dep)
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 109, in __update_paramval
self.__update_paramval(dep)
... ... 等等,终止于:
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 109, in __update_paramval
self.__update_paramval(dep)
File "/usr/local/lib/python2.7/dist-packages/lmfit-0.7-py2.7.egg/lmfit/minimizer.py", line 106, in __update_paramval
par = self.params[name]
RuntimeError: maximum recursion depth exceeded while calling a Python object
我不知道为什么lmfit会在这种情况下抛出错误。有没有人有想法?它“有效”,没有约束,但会产生无法使用的结果。
答案 0 :(得分:1)
在这个特殊问题中,参数是通过lmfit模块中的params.add
方法设置的。发生错误是因为程序试图在定义某些参数之前应用约束。
首先可以通过定义所有参数然后使用params['<enter parameter here>'].expr = '<expression defining constraint>
实现约束来解决此问题。
例如:
# create a set of Parameters
params = Parameters()
params.add('amp', value= 10, min=0)
params.add('decay', value= 0.1)
params.add('shift', value= 0.0, min=-np.pi/2., max=np.pi/2)
params.add('omega', value= 0.01)
params['amp'].expr = '1-decay-shift-omega'
希望这有助于其他人使用此模块!
答案 1 :(得分:0)
除了上述内容之外,当表达式中存在参数相互依赖性时,也可以达到错误。我最近正在研究一个需要以下约束的问题并收到相同的消息:
#define mr as mi/mii
params['mr'].expr='mi/mii'
params['mi'].expr='mii*(mr)'
params['mii'].expr='mi*(1/mr)'
因为这里的表达都依赖于彼此,所以lmfit无法弄明白。我希望这可以帮助其他人查看此消息。可以通过删除表达式中的一些相互依赖性来修复错误。这似乎是一个可以通过更改源代码来接受这些类型的依赖关系来解决的问题。
干杯