Skip to content

Commit

Permalink
Fixed the Multifit problem bug (fitbenchmarking#1353)
Browse files Browse the repository at this point in the history
* fixed the multifit bug

* added tests of ini_y args

* fixed linting issues
  • Loading branch information
RabiyaF authored Nov 7, 2024
1 parent c451994 commit 4f80b6a
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 71 deletions.
11 changes: 5 additions & 6 deletions fitbenchmarking/parsing/fitting_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,11 @@ def ini_y(self, parameter_set=0):
"""
if parameter_set not in self._ini_y:
params = self.starting_values[parameter_set].values()
if self.multifit:
self._ini_y[parameter_set] = [
self.eval_model(params=params, x=x) for x in self.data_x
]
else:
self._ini_y[parameter_set] = self.eval_model(params=params)
self._ini_y[parameter_set] = (
self.eval_model(params=params, x=self.data_x[0])
if self.multifit
else self.eval_model(params=params)
)
return self._ini_y[parameter_set]


Expand Down
122 changes: 57 additions & 65 deletions fitbenchmarking/parsing/tests/test_fitting_problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
"""

from unittest import TestCase
from unittest.mock import patch

import numpy as np
from parameterized import parameterized

from fitbenchmarking.parsing.fitting_problem import FittingProblem
from fitbenchmarking.utils import exceptions
Expand Down Expand Up @@ -160,53 +162,42 @@ def test_correct_data_single_fit(self):
Tests that correct data gives the expected result
"""
fitting_problem = FittingProblem(self.options)
x_data = np.array([-0.5, 0.0, 1.0, 0.5, 1.5, 2.0, 2.5, 3.0, 4.0])
y_data = np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0])
e_data = np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 9.0])
start_x = 0.5
end_x = 2.5
fitting_problem.data_x = np.array(
[-0.5, 0.0, 1.0, 0.5, 1.5, 2.0, 2.5, 3.0, 4.0]
)
fitting_problem.data_y = np.array(
[0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]
)
fitting_problem.data_e = np.array(
[1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 70.0, 80.0, 9.0]
)
fitting_problem.start_x = 0.5
fitting_problem.end_x = 2.5

expected_x_data = np.array([0.5, 1.0, 1.5, 2.0, 2.5])
expected_y_data = np.array([3.0, 2.0, 4.0, 5.0, 6.0])
expected_e_data = np.array([40.0, 30.0, 50.0, 60.0, 70.0])

fitting_problem.data_x = x_data
fitting_problem.data_y = y_data
fitting_problem.data_e = e_data
fitting_problem.start_x = start_x
fitting_problem.end_x = end_x

fitting_problem.correct_data()

sort = fitting_problem.sorted_index
self.assertTrue(
np.isclose(
fitting_problem.data_x[fitting_problem.sorted_index],
expected_x_data,
).all()
(fitting_problem.data_x[sort] == expected_x_data).all()
)
self.assertTrue(
np.isclose(
fitting_problem.data_y[fitting_problem.sorted_index],
expected_y_data,
).all()
(fitting_problem.data_y[sort] == expected_y_data).all()
)
self.assertTrue(
np.isclose(
fitting_problem.data_e[fitting_problem.sorted_index],
expected_e_data,
).all()
(fitting_problem.data_e[sort] == expected_e_data).all()
)

self.options.cost_func_type = ["nlls"]
fitting_problem.correct_data()
self.assertTrue(
np.isclose(
fitting_problem.data_x[fitting_problem.sorted_index],
expected_x_data,
).all()
(fitting_problem.data_x[sort] == expected_x_data).all()
)
self.assertTrue(
np.isclose(
fitting_problem.data_y[fitting_problem.sorted_index],
expected_y_data,
).all()
(fitting_problem.data_y[sort] == expected_y_data).all()
)
self.assertIs(fitting_problem.data_e, None)

Expand All @@ -216,23 +207,24 @@ def test_correct_data_multi_fit(self):
"""
fitting_problem = FittingProblem(self.options)
fitting_problem.multifit = True
x_data = [
fitting_problem.data_x = [
np.array([-0.5, 0.0, 1.0, 0.5, 1.5, 2.0, 2.5, 3.0, 4.0]),
np.array([-0.5, 0.0, 1.0, 0.5, 1.4, 2.0, 2.5, 3.0, 4.0]),
np.array([-0.5, 0.0, 1.0, 0.5, 1.7, 2.0, 2.5, 3.0, 4.0]),
]
y_data = [
fitting_problem.data_y = [
np.array([0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]),
np.array([0.0, 1.0, 2.0, 3.0, 24.0, 5.0, 6.0, 7.0, 8.0]),
np.array([0.0, 1.0, 2.8, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]),
]
e_data = [
fitting_problem.data_e = [
np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 1.0, 6.0, 9.0]),
np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 1.0, 6.0, 9.0]),
np.array([1.0, 20.0, 30.0, 40.0, 50.0, 60.0, 1.0, 6.0, 9.0]),
]
start_x = [0.5, 1.1, 0.0]
end_x = [2.5, 2.6, 1.0]
fitting_problem.start_x = [0.5, 1.1, 0.0]
fitting_problem.end_x = [2.5, 2.6, 1.0]

expected_x_data = [
np.array([0.5, 1.0, 1.5, 2.0, 2.5]),
np.array([1.4, 2.0, 2.5]),
Expand All @@ -249,46 +241,46 @@ def test_correct_data_multi_fit(self):
np.array([20.0, 40.0, 30.0]),
]

fitting_problem.data_x = x_data
fitting_problem.data_y = y_data
fitting_problem.data_e = e_data
fitting_problem.start_x = start_x
fitting_problem.end_x = end_x

fitting_problem.correct_data()
for i in range(3):

for ix, sort in enumerate(fitting_problem.sorted_index):
self.assertTrue(
np.isclose(
fitting_problem.data_x[i][fitting_problem.sorted_index[i]],
expected_x_data[i],
).all()
(fitting_problem.data_x[ix][sort] == expected_x_data[ix]).all()
)
self.assertTrue(
np.isclose(
fitting_problem.data_y[i][fitting_problem.sorted_index[i]],
expected_y_data[i],
).all()
(fitting_problem.data_y[ix][sort] == expected_y_data[ix]).all()
)
self.assertTrue(
np.isclose(
fitting_problem.data_e[i][fitting_problem.sorted_index[i]],
expected_e_data[i],
).all()
(fitting_problem.data_e[ix][sort] == expected_e_data[ix]).all()
)

self.options.cost_func_type = ["nlls"]
fitting_problem.correct_data()
for i in range(3):
for ix, sort in enumerate(fitting_problem.sorted_index):
self.assertTrue(
np.isclose(
fitting_problem.data_x[i][fitting_problem.sorted_index[i]],
expected_x_data[i],
).all()
(fitting_problem.data_x[ix][sort] == expected_x_data[ix]).all()
)
self.assertTrue(
np.isclose(
fitting_problem.data_y[i][fitting_problem.sorted_index[i]],
expected_y_data[i],
).all()
(fitting_problem.data_y[ix][sort] == expected_y_data[ix]).all()
)
self.assertIs(fitting_problem.data_e[i], None)
self.assertIs(fitting_problem.data_e[ix], None)

@parameterized.expand(
[
(True, [np.array([1, 2]), np.array([3, 4])], ["params", "x"]),
(False, np.array([1, 2]), ["params"]),
]
)
@patch("fitbenchmarking.parsing.fitting_problem.FittingProblem.eval_model")
def test_ini_y_args(self, multifit, data_x, args, mock):
"""
Tests ini_y calls eval_model using the right args.
"""
fitting_problem = FittingProblem(self.options)
fitting_problem.multifit = multifit
fitting_problem.data_x = data_x
fitting_problem.starting_values = [{0: "0"}]

fitting_problem.ini_y()
self.assertEqual(mock.call_count, 1)
self.assertEqual(list(mock.call_args[1].keys()), args)

0 comments on commit 4f80b6a

Please sign in to comment.