-
Notifications
You must be signed in to change notification settings - Fork 281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Loading a saved SplineModel fit result using load_modelresult
does not work for more than 6 knots
#985
Comments
@B-Hartmann Hmm, yeah that's a problem ;). I think we might need to special case SplineModel when saving/loading models... that may need some work. There might be other options.... |
I believe a good approach would be to
It might also help to refactor a If this sounds good, I would be happy to submit a PR 👍 |
A workaround that does what I need is to save the fit result using pickle and extract the parameter values from the pickled object when needed. import numpy as np
import matplotlib.pyplot as plt
from lmfit.models import SplineModel
from scipy.interpolate import splev, splrep
import pickle
x = np.linspace(-10, 10, 100)
y = 0.6*np.exp(-(x**2)/(2*2.3**2))
xknots = np.linspace(-8, 8, 12)
gmodel = SplineModel(xknots=xknots)
params = gmodel.guess(y, x)
result = gmodel.fit(y, params, x=x)
# save summary of fit report
with open('spline_model.pkl', 'wb') as f:
pickle.dump(result.summary(), f)
# use the pickled data instead and manually extract the knots
with open('spline_model.pkl', 'rb') as f:
loaded_result = pickle.load(f)
fit_param_new = []
for para_set in loaded_result["params"]:
fit_param_new.append(para_set[1])
fit_param = []
for p in result.params:
fit_param.append(result.params[p].value)
x_new = np.linspace(-10, 10, 200)
# create new spline model
knots, _c, _k = splrep(xknots, np.ones(len(xknots)), k=3)
coefs = fit_param_new
coefs.extend([coefs[-1]]*4)
y_pred = splev(x_new, [knots, np.array(coefs), 3])
plt.figure()
plt.plot(x, y, 'o', label="data")
plt.plot(x, result.best_fit, '-', label="original spline")
plt.plot(x_new, y_pred, "--k", linewidth=2, label="new spline from parameters")
plt.legend()
plt.ylim([-0.2, 0.8])
plt.show() |
@B-Hartmann Yes, that would be a decent workaround, but we should also try to fix this.... @paulmueller I think that "refactor/generalize _parse_params" for this (essentially, 'allow varargs') is not that easy. Another possible workaround would be to "simply" increase the number of parameters defined in the signature at |
@newville I would be motivated to work on both approaches (refactoring If you have a preference (since you will have to review this), please let me know. |
@paulmueller I recommend the "easy route" -- and setting the max number of splines there to 100 should be good. To be clear, lmfit Model can use vark ws ( Another thing to try would be to use See:
|
lmfit 1.3.2
scipy 1.12.0
numpy 1.26.4
asteval 1.0.5
Windows 10
Python 3.10.4
Code run in a jupyter notebook using DataSpell
I would like to save the results of a fit using
SplineModel
for later use. I used the functionssave_modelresult
andload_modelresult
:I get the following error:
I believe the following line is the problem, allowing only 6 arguments to be passed to the function, but I have 10 knots:
https://github.com/lmfit/lmfit-py/blob/1.3.2/lmfit/models.py#L394
Could this be solved by adding a
*s
or**s
to the function arguments or something?The text was updated successfully, but these errors were encountered: