Setting Fitter.tolerance and fitting with any gradient-free LMFit method (LMFit_powell, LMFit_cobyla) makes the fit raise immediately:
easyscience.fitting.minimizers.utils.FitError: minimize() got an unexpected keyword argument 'ftol'
Without a tolerance, the same fit completes, which makes the bug easy to miss. LMFit_differential_evolution is affected by the same keyword-selection logic.
Reproducible with
import numpy as np
from easyscience import AvailableMinimizers, Fitter, ObjBase, Parameter
class AbsSin(ObjBase):
def __init__(self, offset_val, phase_val):
super().__init__('sin',
offset=Parameter('offset', offset_val),
phase=Parameter('phase', phase_val))
def __call__(self, x):
return np.abs(np.sin(self.phase.value * x + self.offset.value))
ref_sin = AbsSin(0.2, np.pi)
sp_sin = AbsSin(0.354, 3.05)
sp_sin.offset.fixed = False
sp_sin.phase.fixed = False
x = np.linspace(0, 5, 200)
f = Fitter(sp_sin, sp_sin)
f.switch_minimizer(AvailableMinimizers.LMFit_powell) # or LMFit_cobyla
f.tolerance = 1e-4 # <- the trigger
f.fit(x=x, y=ref_sin(x), weights=np.ones_like(x))
# FitError: minimize() got an unexpected keyword argument 'ftol'
Setting Fitter.tolerance and fitting with any gradient-free LMFit method (LMFit_powell, LMFit_cobyla) makes the fit raise immediately:
easyscience.fitting.minimizers.utils.FitError: minimize() got an unexpected keyword argument 'ftol'Without a tolerance, the same fit completes, which makes the bug easy to miss. LMFit_differential_evolution is affected by the same keyword-selection logic.
Reproducible with