lmfit:如何通过将参数限制在 LMFIT 中的其他参数之间来添加对参数的约束?
lmfit: how to add a constraint on a parameter by bounding it between other parameters in LMFIT?
我有一个拟合函数:
import cvxpy as cp
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from lmfit import Model, Parameters
def f(wdata, pr, pi, cr, ci):
return ( np.arctan2(-2*ci*pi - 2*cr*pr, 2*cr*wdata) - np.arctan2((pi)**2 + (pr)**2 - (wdata)**2, -2*pr*wdata) )
wdata = (500000000.0, 520000000.0, 540000000.0, 560000000.0, 580000000.0, 600000000.0, 620000000.0, 640000000.0, 660000000.0, 680000000.0, 700000000.0, 720000000.0, 740000000.0, 760000000.0])
wdata= np.asarray(wdata)
ydata = f(wdata, -355574682.231318, -9040912422.93189, 31570159.4732856, -6238484.15663787)
fmodel = Model(f)
params = Parameters()
params.add('pr', value=-355574682.231318, vary=True)
params.add('pi', value=-9040912422.93189, vary=True)
params.add('pi', value=-9040912422.93189, vary=True)
params.add('cr', value=31570159.4732856, vary=True)
params.add('ci', expr='-((cr*pr)/pi) < ci < (cr*pr)/pi if pi<0 else ((cr*pr)/pi) < ci < -(cr*pr)/pi ', vary=True)
result = fmodel.fit(ydata, params, wdata=wdata)
print(result.fit_report())
plt.plot(wdata, ydata, 'bo')
plt.plot(wdata, result.init_fit, 'k--')
plt.plot(wdata, result.best_fit, 'r-')
plt.show()
如您所见,参数 "ci" 必须限制在其他参数之间。我将约束放在 if 语句中;但是,我得到一个错误,名称 'ci' 未定义。我认为原因是我将 ci 与其他参数放在两个不等式中。如何告诉我的代码我希望 "ci" 有界? (我现在在我的代码中显示了界限)
这里发生了许多奇怪的事情,引起了警钟,您可能应该解决这些问题:
Zeroth,不要命名参数'pi'。代码是用来阅读的,这只会扰乱人们的思想。下面,我将其称为'phi'.
首先,您的参数的初始值不需要 15 位有效数字。
其次,注意避免变量的值在规模上相差很多数量级。如果 'pr' 预计为 ~3e8 并且 'phi' 预计为 ~9e9,请考虑将 "changing units" 乘以 1e6 或 1e9,以便变量值更接近统一。
好的,进入正题。我会试试这个:
params.add('pr', value=-3.6e8, vary=True)
params.add('phi', value=-9.0e9, vary=True)
params.add('cr', value=3.2e7, vary=True)
# add a new *internal* variable that is bound on [-pi/2, pi/2]
params.add('xangle', value=0.05, vary=True, min=-np.pi/2, max=np.pi/2)
# constrain 'ci' to be '(cr*pr/phi)*sin(xangle)'
params.add('ci', expr='(cr*pr/phi)*sin(xangle)')
现在,由于 xangle
在 -pi/2
和 +pi/2
之间变化,ci
将能够取 -cr*pr/phi
和 [= 之间的任何值16=].
我有一个拟合函数:
import cvxpy as cp
import numpy as np
from scipy.optimize import minimize
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from lmfit import Model, Parameters
def f(wdata, pr, pi, cr, ci):
return ( np.arctan2(-2*ci*pi - 2*cr*pr, 2*cr*wdata) - np.arctan2((pi)**2 + (pr)**2 - (wdata)**2, -2*pr*wdata) )
wdata = (500000000.0, 520000000.0, 540000000.0, 560000000.0, 580000000.0, 600000000.0, 620000000.0, 640000000.0, 660000000.0, 680000000.0, 700000000.0, 720000000.0, 740000000.0, 760000000.0])
wdata= np.asarray(wdata)
ydata = f(wdata, -355574682.231318, -9040912422.93189, 31570159.4732856, -6238484.15663787)
fmodel = Model(f)
params = Parameters()
params.add('pr', value=-355574682.231318, vary=True)
params.add('pi', value=-9040912422.93189, vary=True)
params.add('pi', value=-9040912422.93189, vary=True)
params.add('cr', value=31570159.4732856, vary=True)
params.add('ci', expr='-((cr*pr)/pi) < ci < (cr*pr)/pi if pi<0 else ((cr*pr)/pi) < ci < -(cr*pr)/pi ', vary=True)
result = fmodel.fit(ydata, params, wdata=wdata)
print(result.fit_report())
plt.plot(wdata, ydata, 'bo')
plt.plot(wdata, result.init_fit, 'k--')
plt.plot(wdata, result.best_fit, 'r-')
plt.show()
如您所见,参数 "ci" 必须限制在其他参数之间。我将约束放在 if 语句中;但是,我得到一个错误,名称 'ci' 未定义。我认为原因是我将 ci 与其他参数放在两个不等式中。如何告诉我的代码我希望 "ci" 有界? (我现在在我的代码中显示了界限)
这里发生了许多奇怪的事情,引起了警钟,您可能应该解决这些问题:
Zeroth,不要命名参数'pi'。代码是用来阅读的,这只会扰乱人们的思想。下面,我将其称为'phi'.
首先,您的参数的初始值不需要 15 位有效数字。
其次,注意避免变量的值在规模上相差很多数量级。如果 'pr' 预计为 ~3e8 并且 'phi' 预计为 ~9e9,请考虑将 "changing units" 乘以 1e6 或 1e9,以便变量值更接近统一。
好的,进入正题。我会试试这个:
params.add('pr', value=-3.6e8, vary=True)
params.add('phi', value=-9.0e9, vary=True)
params.add('cr', value=3.2e7, vary=True)
# add a new *internal* variable that is bound on [-pi/2, pi/2]
params.add('xangle', value=0.05, vary=True, min=-np.pi/2, max=np.pi/2)
# constrain 'ci' to be '(cr*pr/phi)*sin(xangle)'
params.add('ci', expr='(cr*pr/phi)*sin(xangle)')
现在,由于 xangle
在 -pi/2
和 +pi/2
之间变化,ci
将能够取 -cr*pr/phi
和 [= 之间的任何值16=].