-
Notifications
You must be signed in to change notification settings - Fork 291
Description
Yes, I read the instructions and I am sure this is a GitHub Issue.
Python: 3.10.9 (main, Jan 11 2023, 09:18:20) [Clang 14.0.6 ]
lmfit: 1.1.0, scipy: 1.10.0, numpy: 1.23.5,asteval: 0.9.28, uncertainties: 3.1.7
Apparently, there is a difference in calculating the confidence region using the conf_interval or the conf_interval2d method. It was expected that when plotting the regions calculated by both methods (as I did below), the 1D confidence region would be overlapping the maximum points and minima of the 2D region. However, the results show a significant deviation from this expectation.
I would like to investigate this issue further, but before doing so, I need to know whether this behavior is expected or not. If it is not expected, I can focus on understanding the underlying reasons behind this behavior.
Can anyone provide any insights or guidance regarding this issue? Any help would be greatly appreciated.
# same code from Documentation Example
import matplotlib.pyplot as plt
import numpy as np
import lmfit
x = np.linspace(1, 10, 250)
np.random.seed(0)
y = 3.0*np.exp(-x/2) - 5.0*np.exp(-(x-0.1)/10.) + 0.1*np.random.randn(x.size)
p = lmfit.Parameters()
p.add_many(('a1', 4.), ('a2', 4.), ('t1', 3.), ('t2', 3.))
def residual(p):
return p['a1']*np.exp(-x/p['t1']) + p['a2']*np.exp(-(x-0.1)/p['t2']) - y
mini = lmfit.Minimizer(residual, p, nan_policy='propagate')
out1 = mini.minimize(method='Nelder')
out2 = mini.minimize(method='leastsq', params=out1.params)
# arrays to store bounds for three different sigma values (1, 2, and 3)
bound_a1 = np.zeros((3, 2))
bound_a2 = np.zeros((3, 2))
bound_t1 = np.zeros((3, 2))
bound_t2 = np.zeros((3, 2))
# calculate and store respective confidence intervals
for i, sig in enumerate([1, 2, 3]):
ci, trace = lmfit.conf_interval(mini, out2, sigmas=[sig], trace=True)
bound_a1[i] = (ci['a1'][0][1], ci['a1'][-1][1])
bound_a2[i] = (ci['a2'][0][1], ci['a2'][-1][1])
bound_t1[i] = (ci['t1'][0][1], ci['t1'][-1][1])
bound_t2[i] = (ci['t2'][0][1], ci['t2'][-1][1])
colors = ['r', 'b', 'g']
levels = [0.683, 0.955, 0.997]
# plot confidence intervals (a1 vs t2 and a2 vs t2)
fig, axes = plt.subplots(1, 2, figsize=(12.8, 4.8))
cx, cy, grid = lmfit.conf_interval2d(mini, out2, 'a1', 't2', 200, 200)
ctp = axes[0].contourf(cx, cy, grid, np.linspace(0, 1, 501), cmap='gray')
axes[0].contour(cx, cy, grid, levels=levels, colors=colors)
fig.colorbar(ctp, ax=axes[0])
axes[0].set_xlabel('a1')
axes[0].set_ylabel('t2')
# plot boxes
for i, c in zip(range(3), colors):
axes[0].plot([bound_a1[i][0], bound_a1[i][1], bound_a1[i][1], bound_a1[i][0], bound_a1[i][0]],
[bound_t2[i][0], bound_t2[i][0], bound_t2[i][1], bound_t2[i][1], bound_t2[i][0]],
color=c, linestyle='--', alpha=0.5)
cx, cy, grid = lmfit.conf_interval2d(mini, out2, 'a2', 't2', 200, 200)
ctp = axes[1].contourf(cx, cy, grid, np.linspace(0, 1, 501), cmap='gray')
axes[1].contour(cx, cy, grid, levels=levels, colors=colors)
fig.colorbar(ctp, ax=axes[1])
axes[1].set_xlabel('a2')
axes[1].set_ylabel('t2')
# plot boxes
for i, c in zip(range(3), colors):
axes[1].plot([bound_a2[i][0], bound_a2[i][1], bound_a2[i][1], bound_a2[i][0], bound_a2[i][0]],
[bound_t2[i][0], bound_t2[i][0], bound_t2[i][1], bound_t2[i][1], bound_t2[i][0]],
color=c, linestyle='--', alpha=0.5)
plt.show()