Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions src/easyscience/fitting/minimizers/minimizer_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def __init__(
fit_function: Callable,
method: Optional[str] = None,
): # todo after constraint changes, add type hint: obj: BaseObj # noqa: E501
if method not in self.available_methods():
if method not in self.supported_methods():
raise FitError(f'Method {method} not available in {self.__class__}')
self._object = obj
self._original_fit_function = fit_function
Expand Down Expand Up @@ -132,12 +132,23 @@ def convert_to_pars_obj(self, par_list: Optional[Union[list]] = None):
:return: engine Parameters compatible object
"""

@staticmethod
@abstractmethod
def supported_methods() -> List[str]:
"""
Return a list of supported methods for the minimizer.

:return: List of supported methods
:rtype: List[str]
"""

@staticmethod
@abstractmethod
def available_methods(self) -> List[str]:
def all_methods() -> List[str]:
"""
Return a list of available methods for the engine.
Return a list of all available methods for the minimizer.

:return: List of available methods
:return: List of all available methods
:rtype: List[str]
"""

Expand Down
11 changes: 9 additions & 2 deletions src/easyscience/fitting/minimizers/minimizer_bumps.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,16 @@ def __init__(
super().__init__(obj=obj, fit_function=fit_function, method=method)
self._p_0 = {}

def available_methods(self) -> List[str]:
@staticmethod
def all_methods() -> List[str]:
return FIT_AVAILABLE_IDS_FILTERED

@staticmethod
def supported_methods() -> List[str]:
# only a small subset
methods = ['scipy.leastsq','amoeba', 'newton', 'lm']
return methods

def fit(
self,
x: np.ndarray,
Expand Down Expand Up @@ -92,7 +99,7 @@ def fit(
default_method = {}
if self._method is not None:
default_method = {'method': self._method}
if method is not None and method in self.available_methods():
if method is not None and method in self.supported_methods():
default_method['method'] = method

if weights is None:
Expand Down
11 changes: 9 additions & 2 deletions src/easyscience/fitting/minimizers/minimizer_dfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,16 @@ def __init__(
super().__init__(obj=obj, fit_function=fit_function, method=method)
self._p_0 = {}

def available_methods(self) -> List[str]:
@staticmethod
def supported_methods() -> List[str]:
return ['leastsq']

@staticmethod
def all_methods() -> List[str]:
return [
'leastsq',
]

def fit(
self,
x: np.ndarray,
Expand Down Expand Up @@ -83,7 +90,7 @@ def fit(
default_method = {}
if self._method is not None:
default_method = {'method': self._method}
if method is not None and method in self.available_methods():
if method is not None and method in self.supported_methods():
default_method['method'] = method

if weights is None:
Expand Down
14 changes: 12 additions & 2 deletions src/easyscience/fitting/minimizers/minimizer_lmfit.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ def __init__(
"""
super().__init__(obj=obj, fit_function=fit_function, method=method)

def available_methods(self) -> List[str]:
@staticmethod
def all_methods() -> List[str]:
return [
'least_squares',
'leastsq',
Expand All @@ -65,6 +66,15 @@ def available_methods(self) -> List[str]:
'bfgs',
]

@staticmethod
def supported_methods() -> List[str]:
return [
'least_squares',
'leastsq',
'powell',
'cobyla',
]

def fit(
self,
x: np.ndarray,
Expand Down Expand Up @@ -102,7 +112,7 @@ def fit(
if self._method is not None:
default_method = {'method': self._method}
if method is not None:
if method in self.available_methods():
if method in self.supported_methods():
default_method['method'] = method
else:
raise FitError(f'Method {method} not available in {self.__class__}')
Expand Down
4 changes: 2 additions & 2 deletions tests/integration_tests/Fitting/test_fitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def test_lmfit_methods(fit_method):
sp_sin.phase.fixed = False

f = Fitter(sp_sin, sp_sin)
assert fit_method in f._minimizer.available_methods()
assert fit_method in f._minimizer.supported_methods()
result = f.fit(x, y, method=fit_method)
check_fit_results(result, sp_sin, ref_sin, x)

Expand All @@ -171,7 +171,7 @@ def test_bumps_methods(fit_method):

f = Fitter(sp_sin, sp_sin)
f.switch_minimizer("Bumps")
assert fit_method in f._minimizer.available_methods()
assert fit_method in f._minimizer.supported_methods()
result = f.fit(x, y, method=fit_method)
check_fit_results(result, sp_sin, ref_sin, x)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def test_lmfit_methods(fit_method):
sp_sin.phase.fixed = False

f = Fitter(sp_sin, sp_sin)
assert fit_method in f._minimizer.available_methods()
assert fit_method in f._minimizer.supported_methods()
result = f.fit(x, y, method=fit_method)
check_fit_results(result, sp_sin, ref_sin, x)

Expand All @@ -171,7 +171,7 @@ def test_bumps_methods(fit_method):

f = Fitter(sp_sin, sp_sin)
f.switch_minimizer("Bumps")
assert fit_method in f._minimizer.available_methods()
assert fit_method in f._minimizer.supported_methods()
result = f.fit(x, y, method=fit_method)
check_fit_results(result, sp_sin, ref_sin, x)

Expand Down
4 changes: 2 additions & 2 deletions tests/unit_tests/Fitting/minimizers/test_minimizer_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class TestMinimizerBase():
def minimizer(self):
# This avoids the error: TypeError: Can't instantiate abstract class with abstract methods __init__
MinimizerBase.__abstractmethods__ = set()
MinimizerBase.available_methods = MagicMock(return_value=['method'])
MinimizerBase.supported_methods = MagicMock(return_value=['method'])

minimizer = MinimizerBase(
obj='obj',
Expand All @@ -27,7 +27,7 @@ def minimizer(self):
def test_init_exception(self):
# When Then
MinimizerBase.__abstractmethods__ = set()
MinimizerBase.available_methods = MagicMock(return_value=['method'])
MinimizerBase.supported_methods = MagicMock(return_value=['method'])

# Expect
with pytest.raises(FitError):
Expand Down
8 changes: 6 additions & 2 deletions tests/unit_tests/Fitting/minimizers/test_minimizer_bumps.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ def test_init_exception(self) -> None:
method='not_leastsq'
)

def test_available_methods(self, minimizer: Bumps) -> None:
def test_all_methods(self, minimizer: Bumps) -> None:
# When Then Expect
assert minimizer.available_methods() == ['amoeba', 'de', 'dream', 'newton', 'scipy.leastsq', 'lm']
assert minimizer.all_methods() == ['amoeba', 'de', 'dream', 'newton', 'scipy.leastsq', 'lm']

def test_supported_methods(self, minimizer: Bumps) -> None:
# When Then Expect
assert set(minimizer.supported_methods()) == set(['scipy.leastsq','newton', 'lm', 'amoeba'])

def test_fit(self, minimizer: Bumps, monkeypatch) -> None:
# When
Expand Down
8 changes: 6 additions & 2 deletions tests/unit_tests/Fitting/minimizers/test_minimizer_dfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ def test_init_exception(self) -> None:
method='not_leastsq'
)

def test_available_methods(self, minimizer: DFO) -> None:
def test_supported_methods(self, minimizer: DFO) -> None:
# When Then Expect
assert minimizer.available_methods() == ['leastsq']
assert minimizer.supported_methods() == ['leastsq']

def test_supported_methods(self, minimizer: DFO) -> None:
# When Then Expect
assert minimizer.supported_methods() == ['leastsq']

def test_fit(self, minimizer: DFO) -> None:
# When
Expand Down
5 changes: 3 additions & 2 deletions tests/unit_tests/Fitting/minimizers/test_minimizer_lmfit.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,15 @@ def test_fit_method(self, minimizer: LMFit) -> None:
minimizer._make_model = MagicMock(return_value=mock_model)
minimizer._set_parameter_fit_result = MagicMock()
minimizer._gen_fit_results = MagicMock(return_value='gen_fit_results')
minimizer.available_methods = MagicMock(return_value=['method_passed'])
minimizer.supported_methods = MagicMock(return_value=['method_passed'])
minimizer.all_methods = MagicMock(return_value=['method_passed'])

# Then
minimizer.fit(x=1.0, y=2.0, method='method_passed')

# Expect
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='method_passed')
minimizer.available_methods.assert_called_once_with()
minimizer.supported_methods.assert_called_once_with()

def test_fit_kwargs(self, minimizer: LMFit) -> None:
# When
Expand Down