Repository: fitbenchmarking/fitbenchmarking

Issue:
Multifit and make plots produces a bug
**Description of the error**
When doing multifit problems with make plots set to true I get the error message

```
No registered converter was able to produce a C++ rvalue of type double from this Python object of type numpy.ndarray
Benchmark problems: 100%|█████████████████████████████████████████████████| 2/2 [00:00<00:00,  3.37Benchmark problem/s]
Producing output for the Mantid_MultiFit problem set
Unknown exception. Exiting.
All arrays must be of the same length
```

**Describe the expected result**
I would expect either for it to work or to give a clear error about plots not working with multifit (preferably at the start instead of the end)




Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/70608100/badge)](https://coveralls.io/builds/70608100)

coverage: 90.229% (+0.02%) from 90.214%
when pulling **96c730308f684b458b329887588f6d6847ac12be on RabiyaF:1232-fixed-multifit-bug**
into **cbbfa71754bb236973ac80ffdf357cf1229ca98c on fitbenchmarking:master**.


Patch:
diff --git a/fitbenchmarking/parsing/fitting_problem.py b/fitbenchmarking/parsing/fitting_problem.py
index 788a01a8..c962eb64 100644
--- a/fitbenchmarking/parsing/fitting_problem.py
+++ b/fitbenchmarking/parsing/fitting_problem.py
@@ -296,12 +296,11 @@ class FittingProblem:
         """
         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]
 
 


Test patch:
diff --git a/fitbenchmarking/parsing/tests/test_fitting_problem.py b/fitbenchmarking/parsing/tests/test_fitting_problem.py
index b57e2a1d..b479c775 100644
--- a/fitbenchmarking/parsing/tests/test_fitting_problem.py
+++ b/fitbenchmarking/parsing/tests/test_fitting_problem.py
@@ -3,8 +3,10 @@ Test file to test the fitting_problem file.
 """
 
 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
@@ -160,53 +162,42 @@ class TestFittingProblem(TestCase):
         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)
 
@@ -216,23 +207,24 @@ class TestFittingProblem(TestCase):
         """
         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]),
@@ -249,46 +241,46 @@ class TestFittingProblem(TestCase):
             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)