如何使用 lmfit 修复此拟合例程(2 个自变量)?
How to fix this fitting routine (2 independent variable) using lmfit?
我目前正在尝试使用 lmfit
实现曲线拟合例程,尽管我的编码技能有限而且我之前使用 curve_fit
的经验也无济于事。另外,我一直在浏览 https://lmfit.github.io/lmfit-py/model.html 上的文档,但我仍然无法修复它。
正如您在下面看到的,我试图拟合以下等式:R2avg*(np.sin(thetas))**2 + ((np.sin(thetas))**2)*(phi_ex*k_ex/(k_ex**2 + omega_eff**2))
,它有 2 个自变量(omega_eff
和 thetas
),而我想以适应其余三个参数。
import lmfit as lf
from lmfit import Model, Parameters
import numpy as np
import matplotlib.pyplot as plt
from math import atan
def on_res(omega_eff, thetas, R2avg=5, k_ex=0.1, phi_ex=500):
return R2avg*(np.sin(thetas))**2 + ((np.sin(thetas))**2)*(phi_ex*k_ex/(k_ex**2 + omega_eff**2))
model = Model(on_res,independent_vars=['omega_eff','thetas'])
model.set_param_hint('R2avg',value=5)
model.set_param_hint('k_ex',value=0.1)
model.set_param_hint('phi_ex',value=500)
carrier = 6146.53
O_1 = 5846
spin_locks = (1000, 2000, 3000, 4000, 5000)
delta_omega = (O_1 - carrier)
omega_eff1 = ((delta_omega**2) + (spin_locks[0]**2))**0.5
omega_eff2 = ((delta_omega**2) + (spin_locks[1]**2))**0.5
omega_eff3 = ((delta_omega**2) + (spin_locks[2]**2))**0.5
omega_eff4 = ((delta_omega**2) + (spin_locks[3]**2))**0.5
omega_eff5 = ((delta_omega**2) + (spin_locks[4]**2))**0.5
theta_rad1 = atan(spin_locks[0]/delta_omega)
theta_rad2 = atan(spin_locks[1]/delta_omega)
theta_rad3 = atan(spin_locks[2]/delta_omega)
theta_rad4 = atan(spin_locks[3]/delta_omega)
theta_rad5 = atan(spin_locks[4]/delta_omega)
x = (omega_eff1/1000, omega_eff2/1000, omega_eff3/1000, omega_eff4/1000, omega_eff5/1000)# , omega_eff6/1000)# , omega_eff7/1000)
theta = (theta_rad1, theta_rad2, theta_rad3, theta_rad4, theta_rad5)
R1rho_vals = (7.9328, 6.2642, 6.0005, 5.9972, 6.1988)
e = (0.33, 0.31, 0.32, 0.33, 0.5)
new_x = np.linspace(0, 6, 1000)
omega_eff = np.array(x, dtype=float)
thetas = np.array(theta, dtype=float)
R1rho_vals = np.array(R1rho_vals, dtype=float)
result = model.fit(R2avg, k_ex, phi_ex, thetas=thetas, omega_eff=omega_eff)
plt.errorbar(x, R1rho_vals, yerr = e, fmt = ".k", markersize = 8, capsize = 3)
# plt.plot(new_x, result.best_fit, label="Two sites fast exchange")
# plt.show()
print(model.param_names)
print(model.independent_vars)
如果我 运行 我发布的脚本,我得到:
result = model.fit(R2avg, k_ex, phi_ex, thetas=thetas, omega_eff=omega_eff)
NameError: name 'R2avg' is not defined
这个我不是很懂。
我做了一些故障排除,并通过检查:
print(model.param_names)
和 print(model.independent_vars)
似乎一切都被恰当地定义了。
非常欢迎任何帮助!
您使用 lmfit.Model
来定义独立参数看起来不错。你不是做的是定义一组要在拟合中使用的参数。
你做到了:
model = Model(on_res,independent_vars=['omega_eff','thetas'])
model.set_param_hint('R2avg',value=5)
model.set_param_hint('k_ex',value=0.1)
model.set_param_hint('phi_ex',value=500)
但是set_param_hint
告诉模型如何制作参数,但它自己不制作。你必须明确地这样做。在我看来,这样做会更好
model = Model(on_res,independent_vars=['omega_eff','thetas'])
params = model.make_params(R2avg=5, k_ex=0.1, phi_ex=500)
部分原因是 a) 您 需要 一个参数对象以使拟合工作,并且 b) 这些值并不是您模型的真正一部分(参数或约束的边界表达式可能是,但值很少是)。
然后要拟合独立的(y
)数据,你要做
result = model.fit(data, params, thetas=thetas, omega_eff=omega_eff)
或者(如果你真的坚持不创建参数)你可以明确说明每个参数的起始值:
result = model.fit(data, R2avg=5, k_ex=0.1, phi_ex=500,
thetas=thetas, omega_eff=omega_eff)
但不是
result = model.fit(param1, param2, ..., thetas=thetas, omega_eff=omega_eff) # NO!
通常,首选明确使用参数对象。
似乎(但我不确定)R1rho_vals
是要拟合的数据,所以这意味着您想要这样做:
result = model.fit(R1rho_vals, params, thetas=thetas, omega_eff=omega_eff)
要包括不确定性(您的 e
),您可以这样做:
result = model.fit(R1rho_vals, params, weights=1.0/e,
thetas=thetas, omega_eff=omega_eff)
然后你可以打印并绘制结果:
print(result.fit_report())
plt.errorbar(x, R1rho_vals, yerr = e, fmt = ".k", markersize = 8, capsize = 3)
plt.plot(new_x, result.best_fit, label="Two sites fast exchange")
plt.show()
我目前正在尝试使用 lmfit
实现曲线拟合例程,尽管我的编码技能有限而且我之前使用 curve_fit
的经验也无济于事。另外,我一直在浏览 https://lmfit.github.io/lmfit-py/model.html 上的文档,但我仍然无法修复它。
正如您在下面看到的,我试图拟合以下等式:R2avg*(np.sin(thetas))**2 + ((np.sin(thetas))**2)*(phi_ex*k_ex/(k_ex**2 + omega_eff**2))
,它有 2 个自变量(omega_eff
和 thetas
),而我想以适应其余三个参数。
import lmfit as lf
from lmfit import Model, Parameters
import numpy as np
import matplotlib.pyplot as plt
from math import atan
def on_res(omega_eff, thetas, R2avg=5, k_ex=0.1, phi_ex=500):
return R2avg*(np.sin(thetas))**2 + ((np.sin(thetas))**2)*(phi_ex*k_ex/(k_ex**2 + omega_eff**2))
model = Model(on_res,independent_vars=['omega_eff','thetas'])
model.set_param_hint('R2avg',value=5)
model.set_param_hint('k_ex',value=0.1)
model.set_param_hint('phi_ex',value=500)
carrier = 6146.53
O_1 = 5846
spin_locks = (1000, 2000, 3000, 4000, 5000)
delta_omega = (O_1 - carrier)
omega_eff1 = ((delta_omega**2) + (spin_locks[0]**2))**0.5
omega_eff2 = ((delta_omega**2) + (spin_locks[1]**2))**0.5
omega_eff3 = ((delta_omega**2) + (spin_locks[2]**2))**0.5
omega_eff4 = ((delta_omega**2) + (spin_locks[3]**2))**0.5
omega_eff5 = ((delta_omega**2) + (spin_locks[4]**2))**0.5
theta_rad1 = atan(spin_locks[0]/delta_omega)
theta_rad2 = atan(spin_locks[1]/delta_omega)
theta_rad3 = atan(spin_locks[2]/delta_omega)
theta_rad4 = atan(spin_locks[3]/delta_omega)
theta_rad5 = atan(spin_locks[4]/delta_omega)
x = (omega_eff1/1000, omega_eff2/1000, omega_eff3/1000, omega_eff4/1000, omega_eff5/1000)# , omega_eff6/1000)# , omega_eff7/1000)
theta = (theta_rad1, theta_rad2, theta_rad3, theta_rad4, theta_rad5)
R1rho_vals = (7.9328, 6.2642, 6.0005, 5.9972, 6.1988)
e = (0.33, 0.31, 0.32, 0.33, 0.5)
new_x = np.linspace(0, 6, 1000)
omega_eff = np.array(x, dtype=float)
thetas = np.array(theta, dtype=float)
R1rho_vals = np.array(R1rho_vals, dtype=float)
result = model.fit(R2avg, k_ex, phi_ex, thetas=thetas, omega_eff=omega_eff)
plt.errorbar(x, R1rho_vals, yerr = e, fmt = ".k", markersize = 8, capsize = 3)
# plt.plot(new_x, result.best_fit, label="Two sites fast exchange")
# plt.show()
print(model.param_names)
print(model.independent_vars)
如果我 运行 我发布的脚本,我得到:
result = model.fit(R2avg, k_ex, phi_ex, thetas=thetas, omega_eff=omega_eff)
NameError: name 'R2avg' is not defined
这个我不是很懂。 我做了一些故障排除,并通过检查:
print(model.param_names)
和 print(model.independent_vars)
似乎一切都被恰当地定义了。
非常欢迎任何帮助!
您使用 lmfit.Model
来定义独立参数看起来不错。你不是做的是定义一组要在拟合中使用的参数。
你做到了:
model = Model(on_res,independent_vars=['omega_eff','thetas'])
model.set_param_hint('R2avg',value=5)
model.set_param_hint('k_ex',value=0.1)
model.set_param_hint('phi_ex',value=500)
但是set_param_hint
告诉模型如何制作参数,但它自己不制作。你必须明确地这样做。在我看来,这样做会更好
model = Model(on_res,independent_vars=['omega_eff','thetas'])
params = model.make_params(R2avg=5, k_ex=0.1, phi_ex=500)
部分原因是 a) 您 需要 一个参数对象以使拟合工作,并且 b) 这些值并不是您模型的真正一部分(参数或约束的边界表达式可能是,但值很少是)。
然后要拟合独立的(y
)数据,你要做
result = model.fit(data, params, thetas=thetas, omega_eff=omega_eff)
或者(如果你真的坚持不创建参数)你可以明确说明每个参数的起始值:
result = model.fit(data, R2avg=5, k_ex=0.1, phi_ex=500,
thetas=thetas, omega_eff=omega_eff)
但不是
result = model.fit(param1, param2, ..., thetas=thetas, omega_eff=omega_eff) # NO!
通常,首选明确使用参数对象。
似乎(但我不确定)R1rho_vals
是要拟合的数据,所以这意味着您想要这样做:
result = model.fit(R1rho_vals, params, thetas=thetas, omega_eff=omega_eff)
要包括不确定性(您的 e
),您可以这样做:
result = model.fit(R1rho_vals, params, weights=1.0/e,
thetas=thetas, omega_eff=omega_eff)
然后你可以打印并绘制结果:
print(result.fit_report())
plt.errorbar(x, R1rho_vals, yerr = e, fmt = ".k", markersize = 8, capsize = 3)
plt.plot(new_x, result.best_fit, label="Two sites fast exchange")
plt.show()