Skip to content

Add support lmfit scipy least square #70

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

Merged
merged 2 commits into from
Sep 2, 2024
Merged
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
3 changes: 3 additions & 0 deletions src/easyscience/fitting/available_minimizers.py
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@ class AvailableMinimizers(Enum):
LMFit_powell = auto()
LMFit_cobyla = auto()
LMFit_differential_evolution = auto()
LMFit_scipy_least_squares = auto()

if bumps_engine_available:
Bumps = auto()
@@ -63,6 +64,8 @@ def from_string_to_enum(minimizer_name: str) -> AvailableMinimizers:
minmizer_enum = AvailableMinimizers.LMFit_cobyla
elif minimizer_name == 'LMFit_differential_evolution':
minmizer_enum = AvailableMinimizers.LMFit_differential_evolution
elif minimizer_name == 'LMFit_scipy_least_squares':
minmizer_enum = AvailableMinimizers.LMFit_scipy_least_squares

elif minimizer_name == 'Bumps':
minmizer_enum = AvailableMinimizers.Bumps
2 changes: 2 additions & 0 deletions src/easyscience/fitting/minimizers/factory.py
Original file line number Diff line number Diff line change
@@ -23,6 +23,8 @@ def factory(minimizer_enum: AvailableMinimizers, fit_object, fit_function: Calla
minimizer = LMFit(obj=fit_object, fit_function=fit_function, method='cobyla')
elif minimizer_enum == AvailableMinimizers.LMFit_differential_evolution:
minimizer = LMFit(obj=fit_object, fit_function=fit_function, method='differential_evolution')
elif minimizer_enum == AvailableMinimizers.LMFit_scipy_least_squares:
minimizer = LMFit(obj=fit_object, fit_function=fit_function, method='least_squares')

elif minimizer_enum == AvailableMinimizers.Bumps:
minimizer = Bumps(obj=fit_object, fit_function=fit_function, method='amoeba')
7 changes: 4 additions & 3 deletions tests/unit_tests/Fitting/minimizers/test_factory.py
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ def pull_minminizer(self, minimizer: AvailableMinimizers) -> MinimizerBase:
minimizer = factory(minimizer, mock_fit_object, mock_fit_function)
return minimizer

@pytest.mark.parametrize('minimizer_method,minimizer_enum', [('leastsq', AvailableMinimizers.LMFit), ('leastsq', AvailableMinimizers.LMFit_leastsq), ('powell', AvailableMinimizers.LMFit_powell), ('cobyla', AvailableMinimizers.LMFit_cobyla)])
@pytest.mark.parametrize('minimizer_method,minimizer_enum', [('leastsq', AvailableMinimizers.LMFit), ('leastsq', AvailableMinimizers.LMFit_leastsq), ('powell', AvailableMinimizers.LMFit_powell), ('cobyla', AvailableMinimizers.LMFit_cobyla), ('differential_evolution', AvailableMinimizers.LMFit_differential_evolution), ('least_squares', AvailableMinimizers.LMFit_scipy_least_squares)])
def test_factory_lm_fit(self, minimizer_method, minimizer_enum):
minimizer = self.pull_minminizer(minimizer_enum)
assert minimizer._method == minimizer_method
@@ -31,7 +31,7 @@ def test_factory_dfo_fit(self, minimizer_method, minimizer_enum):
assert minimizer.wrapping == 'dfo'


@pytest.mark.parametrize('minimizer_name,expected', [('LMFit', AvailableMinimizers.LMFit), ('LMFit_leastsq', AvailableMinimizers.LMFit_leastsq), ('LMFit_powell', AvailableMinimizers.LMFit_powell), ('LMFit_cobyla', AvailableMinimizers.LMFit_cobyla), ])
@pytest.mark.parametrize('minimizer_name,expected', [('LMFit', AvailableMinimizers.LMFit), ('LMFit_leastsq', AvailableMinimizers.LMFit_leastsq), ('LMFit_powell', AvailableMinimizers.LMFit_powell), ('LMFit_cobyla', AvailableMinimizers.LMFit_cobyla), ('LMFit_differential_evolution', AvailableMinimizers.LMFit_differential_evolution), ('LMFit_scipy_least_squares', AvailableMinimizers.LMFit_scipy_least_squares) ])
def test_from_string_to_enum_lmfit(minimizer_name, expected):
assert from_string_to_enum(minimizer_name) == expected

@@ -52,10 +52,11 @@ def test_available_minimizers():
assert AvailableMinimizers.LMFit_powell
assert AvailableMinimizers.LMFit_cobyla
assert AvailableMinimizers.LMFit_differential_evolution
assert AvailableMinimizers.LMFit_scipy_least_squares
assert AvailableMinimizers.Bumps
assert AvailableMinimizers.Bumps_simplex
assert AvailableMinimizers.Bumps_newton
assert AvailableMinimizers.Bumps_lm
assert AvailableMinimizers.DFO
assert AvailableMinimizers.DFO_leastsq
assert len(AvailableMinimizers) == 11
assert len(AvailableMinimizers) == 12
9 changes: 4 additions & 5 deletions tests/unit_tests/Fitting/minimizers/test_minimizer_lmfit.py
Original file line number Diff line number Diff line change
@@ -3,7 +3,6 @@
from unittest.mock import MagicMock

import easyscience.fitting.minimizers.minimizer_lmfit
from easyscience.fitting import AvailableMinimizers
from easyscience.fitting.minimizers.minimizer_lmfit import LMFit
from easyscience.Objects.new_variable import Parameter
from lmfit import Parameter as LMParameter
@@ -16,7 +15,7 @@ def minimizer(self) -> LMFit:
minimizer = LMFit(
obj='obj',
fit_function='fit_function',
method='least_squares'
method='leastsq'
)
return minimizer

@@ -99,7 +98,7 @@ def test_fit(self, minimizer: LMFit) -> None:

# Expect
assert result == 'gen_fit_results'
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='least_squares')
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='leastsq')
minimizer._make_model.assert_called_once_with()
minimizer._set_parameter_fit_result.assert_called_once_with('fit', False)
minimizer._gen_fit_results.assert_called_once_with('fit')
@@ -116,7 +115,7 @@ def test_fit_model(self, minimizer: LMFit) -> None:
minimizer.fit(x=1.0, y=2.0, model=mock_model)

# Expect
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='least_squares')
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='leastsq')
minimizer._make_model.assert_not_called()

def test_fit_method(self, minimizer: LMFit) -> None:
@@ -148,7 +147,7 @@ def test_fit_kwargs(self, minimizer: LMFit) -> None:
minimizer.fit(x=1.0, y=2.0, minimizer_kwargs={'minimizer_key': 'minimizer_val'}, engine_kwargs={'engine_key': 'engine_val'})

# Expect
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='least_squares', fit_kws={'minimizer_key': 'minimizer_val'}, engine_key='engine_val')
mock_model.fit.assert_called_once_with(2.0, x=1.0, weights=0.7071067811865475, method='leastsq', fit_kws={'minimizer_key': 'minimizer_val'}, engine_key='engine_val')

def test_fit_exception(self, minimizer: LMFit) -> None:
# When
2 changes: 1 addition & 1 deletion tests/unit_tests/Fitting/test_fitter.py
Original file line number Diff line number Diff line change
@@ -166,7 +166,7 @@ def test_available_minimizers(self, fitter: Fitter):

# Then Expect
assert minimizers == [
'LMFit', 'LMFit_leastsq', 'LMFit_powell', 'LMFit_cobyla', 'LMFit_differential_evolution',
'LMFit', 'LMFit_leastsq', 'LMFit_powell', 'LMFit_cobyla', 'LMFit_differential_evolution', 'LMFit_scipy_least_squares',
'Bumps', 'Bumps_simplex', 'Bumps_newton', 'Bumps_lm',
'DFO', 'DFO_leastsq'
]
Loading