def test_eval_r(self):
        """
        Test that eval_r is correct
        """
        fitting_problem = FittingProblem()
        self.assertRaises(exceptions.FittingProblemError,
                          fitting_problem.eval_r,
                          params=[1, 2, 3],
                          x=2)

        fitting_problem.function = lambda x, p1: x + p1
        x_val = np.array([1, 8, 11])
        y_val = np.array([6, 10, 20])

        eval_result = fitting_problem.eval_r(x=x_val, y=y_val, params=[5])
        self.assertTrue(all(eval_result == np.array([0, -3, 4])))

        e_val = np.array([2, 4, 1])
        eval_result = fitting_problem.eval_r(x=x_val,
                                             y=y_val,
                                             e=e_val,
                                             params=[5])
        self.assertTrue(all(eval_result == np.array([0, -0.75, 4])))

        fitting_problem.data_x = np.array([20, 21, 22])
        fitting_problem.data_y = np.array([20, 30, 35])
        eval_result = fitting_problem.eval_r(params=[5])
        self.assertTrue(all(eval_result == np.array([-5, 4, 8])))

        fitting_problem.data_e = np.array([2, 5, 10])
        eval_result = fitting_problem.eval_r(params=[5])
        self.assertTrue(all(eval_result == np.array([-2.5, 0.8, 0.8])))
 def test_sanitised_name(self):
     fitting_problem = FittingProblem()
     expected = "test_1"
     fitting_problem.name = "test 1"
     self.assertEqual(fitting_problem.sanitised_name, expected)
     fitting_problem.name = "test,1"
     self.assertEqual(fitting_problem.sanitised_name, expected)
def generate_mock_results():
    """
    Generates results to test against

    :return: best results calculated using the chi_sq value, list of results
             and the options
    :rtype: tuple(list of best results,
                  list of list fitting results,
                  Options object)
    """
    software = 'scipy_ls'
    options = Options()
    options.software = [software]
    num_min = len(options.minimizers[options.software[0]])
    data_x = np.array([[1, 4, 5], [2, 1, 5]])
    data_y = np.array([[1, 2, 1], [2, 2, 2]])
    data_e = np.array([[1, 1, 1], [1, 2, 1]])
    func = [fitting_function_1, fitting_function_2]
    problems = [FittingProblem(options), FittingProblem(options)]

    params_in = [[[.3, .11], [.04, 2], [3, 1], [5, 0]],
                 [[4, 2], [3, .006], [.3, 10], [9, 0]]]

    starting_values = [{"a": .3, "b": .11}, {"a": 0, "b": 0}]
    error_in = [[1, 0, 2, 0], [0, 1, 3, 1]]
    link_in = [['link1', 'link2', 'link3', 'link4'],
               ['link5', 'link6', 'link7', 'link8']]
    min_chi_sq = [1, 1]
    acc_in = [[1, 5, 2, 1.54], [7, 3, 5, 1]]
    min_runtime = [4.2e-5, 5.0e-14]
    runtime_in = [[1e-2, 2.2e-3, 4.2e-5, 9.8e-1],
                  [3.0e-10, 5.0e-14, 1e-7, 4.3e-12]]

    results_out = []
    for i, p in enumerate(problems):
        p.data_x = data_x[i]
        p.data_y = data_y[i]
        p.data_e = data_e[i]
        p.function = func[i]
        p.name = "prob_{}".format(i)
        results = []
        for j in range(num_min):
            p.starting_values = starting_values
            cost_func = NLLSCostFunc(p)
            jac = Scipy(cost_func)
            jac.method = '2-point'
            r = FittingResult(options=options,
                              cost_func=cost_func,
                              jac=jac,
                              initial_params=starting_values,
                              params=params_in[i][j])
            r.chi_sq = acc_in[i][j]
            r.runtime = runtime_in[i][j]
            r.error_flag = error_in[i][j]
            r.support_page_link = link_in[i][j]
            r.minimizer = options.minimizers[software][j]
            results.append(r)
        results_out.append(results)
    return results_out, options, min_chi_sq, min_runtime
Пример #4
0
 def setUp(self):
     """
     Setting up nonlinear least squares cost function tests
     """
     self.options = Options()
     fitting_problem = FittingProblem(self.options)
     self.cost_function = NLLSCostFunc(fitting_problem)
     fitting_problem.function = lambda x, p1: x + p1
     self.x_val = np.array([1, 8, 11])
     self.y_val = np.array([6, 10, 20])
Пример #5
0
    def parse(self):
        """
        Parse the NIST problem file into a Fitting Problem.

        :return: The fully parsed fitting problem
        :rtype: fitbenchmarking.parsing.fitting_problem.FittingProblem
        """

        fitting_problem = FittingProblem()

        equation, data, starting_values, name = self._parse_line_by_line()
        data = self._parse_data(data)

        fitting_problem.data_x = data[:, 1]
        fitting_problem.data_y = data[:, 0]
        if len(data[0, :]) > 2:
            fitting_problem.data_e = data[:, 2]

        fitting_problem.name = name

        # String containing a mathematical expression
        fitting_problem.equation = self._parse_equation(equation)

        fitting_problem.starting_values = starting_values

        fitting_problem.function = \
            nist_func_definition(function=fitting_problem.equation,
                                 param_names=starting_values[0].keys())

        return fitting_problem
 def test_get_function_params(self):
     """
     Tests that the function params is formatted correctly
     """
     fitting_problem = FittingProblem(self.options)
     expected_function_def = 'a=1, b=2.0, c=3.3, d=4.99999'
     fitting_problem.starting_values = [
         OrderedDict([('a', 0), ('b', 0), ('c', 0), ('d', 0)])
     ]
     params = [1, 2.0, 3.3, 4.99999]
     function_def = fitting_problem.get_function_params(params=params)
     self.assertEqual(function_def, expected_function_def)
Пример #7
0
 def test_get_function_def(self):
     """
     Tests that the function def is formatted correctly
     """
     fitting_problem = FittingProblem()
     expected_function_def = \
         'test_function | a=1, b=2.0, c=3.3, d=4.99999999'
     fitting_problem.equation = 'test_function'
     fitting_problem.starting_values = [['a', [0]], ['b', [0]], ['c', [0]],
                                        ['d', [0]]]
     params = [1, 2.0, 3.3, 4.99999999]
     function_def = fitting_problem.get_function_def(params=params)
     self.assertEqual(function_def, expected_function_def)
 def setUp(self):
     """
     Setting up tests
     """
     options = Options()
     options.cost_func_type = "nlls"
     self.fitting_problem = FittingProblem(options)
     self.fitting_problem.function = f
     self.fitting_problem.jacobian = J
     self.fitting_problem.data_x = np.array([1, 2, 3, 4, 5])
     self.fitting_problem.data_y = np.array([1, 2, 4, 8, 16])
     self.cost_func = NLLSCostFunc(self.fitting_problem)
     self.params = [6, 0.1]
     self.actual = J(x=self.fitting_problem.data_x, p=self.params)
    def generate_mock_results(self):
        """
        Generates results to test against

        :return: A list of results objects along with expected values for
                 normallised accuracy and runtimes
        :rtype: tuple(list of FittingResults,
                      list of list of float,
                      list of list of float)
        """
        self.num_problems = 4
        self.num_minimizers = 2
        results = []
        options = Options()
        problem = FittingProblem(options)
        problem.starting_values = [{'a': 1, 'b': 2, 'c': 3}]

        acc_in = [[1, 5], [7, 3], [10, 8], [2, 3]]

        runtime_in = [[float('Inf'), 2.2e-3], [3.0e-10, 5.0e-14],
                      [6.9e-7, 4.3e-5], [1.6e-13, 1.8e-13]]

        acc_expected = []
        runtime_expected = []
        for i in range(self.num_problems):
            acc_results = acc_in[i][:]
            acc_expected.append(list(acc_results) / np.min(acc_results))

            runtime_results = runtime_in[i][:]
            runtime_expected.append(
                list(runtime_results) / np.min(runtime_results))
            prob_results = []
            cost_func = NLLSCostFunc(problem)
            jac = Scipy(cost_func)
            jac.method = "2-point"
            for j in range(self.num_minimizers):
                minimizer = 'min_{}'.format(j)
                prob_results.append(
                    FittingResult(options=options,
                                  cost_func=cost_func,
                                  jac=jac,
                                  initial_params=[1, 2, 3],
                                  params=[1, 2, 3],
                                  chi_sq=acc_results[j],
                                  runtime=runtime_results[j],
                                  minimizer=minimizer))
            results.append(prob_results)
        return results, acc_expected, runtime_expected
Пример #10
0
    def setUp(self):
        self.opts = Options()
        self.opts.use_errors = True

        self.prob = FittingProblem(self.opts)
        self.prob.data_x = np.array([1, 2, 4, 3, 5])
        self.prob.sorted_index = np.array([0, 1, 3, 2, 4])
        self.prob.data_y = np.array([4, 3, 5, 2, 1])
        self.prob.data_e = np.array([0.5, 0.2, 0.3, 0.1, 0.4])
        self.prob.starting_values = [{'x': 1, 'y': 2}]
        self.prob.name = 'full name'
        self.prob.eval_model = lambda y, x: y[0] * x + y[1]
        cost_func = NLLSCostFunc(self.prob)
        jac = Scipy(cost_func)
        jac.method = "2-point"
        self.fr = FittingResult(options=self.opts,
                                cost_func=cost_func,
                                jac=jac,
                                chi_sq=1.0,
                                initial_params=[1.8],
                                params=[1.2],
                                runtime=2.0,
                                minimizer='fit',
                                error_flag=1)

        self.opts = Options()
        self.opts.use_errors = True

        self.dir = TemporaryDirectory()
        self.plot = plots.Plot(best_result=self.fr,
                               options=self.opts,
                               figures_dir=self.dir.name)
 def test_eval_model_raise_error(self):
     """
     Test that eval_model raises and error
     """
     fitting_problem = FittingProblem(self.options)
     self.assertRaises(exceptions.FittingProblemError,
                       fitting_problem.eval_model,
                       x=2,
                       params=[1, 2, 3])
Пример #12
0
 def setUp(self):
     """
     Setting up tests
     """
     options = Options()
     options.cost_func_type = "nlls"
     self.fitting_problem = FittingProblem(options)
     self.cost_func = NLLSCostFunc(self.fitting_problem)
     self.jacobian = Jacobian(self.cost_func)
Пример #13
0
    def setup_nist_expected_problem(self):

        prob = FittingProblem()

        prob.name = 'Misra1a'
        prob.equation = 'b1*(1-exp(-b2*x))'
        prob.starting_values = [['b1', [500.0, 250.0]],
                                ['b2', [0.0001, 0.0005]]]
        data_pattern = self.setup_misra1a_expected_data_points()
        prob.data_x = data_pattern[:, 1]
        prob.data_y = data_pattern[:, 0]
        prob.ref_residual_sum_sq = 1.2455138894e-01

        return prob
Пример #14
0
    def parse(self):
        """
        Get data into a Fitting Problem via cutest.

        :return: The fully parsed fitting problem
        :rtype: fitbenchmarking.parsing.fitting_problem.FittingProblem
        """
        self.mastsif_dir = TemporaryDirectory()

        # set the MASTSIF environment variable so that pycutest
        # can find the sif files
        os.environ["MASTSIF"] = self.mastsif_dir.name

        self._num_params = None

        # get just the short filename (minus the .SIF)
        fp = FittingProblem(self.options)

        # Collect x and create new file with blank y
        fname, fp.data_x, fp.data_y, fp.data_e = self._setup_data()

        self._p = _import_problem(fname)

        fp.name = self._p.name

        fp.function = self._function  # self._p.objcons
        fp.jacobian = self._jacobian  # self._p.lagjac
        fp.equation = None
        fp.starting_values = self._get_starting_values()
        fp.start_x = None
        fp.end_x = None
        fp.format = "cutest"

        # Create a list of x and f (function evaluation) and x and g (Jacobian
        # evaluation).
        # If a new x is given we will create and parse a new file
        self._cache_f = [(fp.data_x, self._p.objcons)]
        self._cache_g = [(fp.data_x, self._p.lagjac)]

        return fp
    def test_eval_model_correct_evaluation(self):
        """
        Test that eval_model is running the correct function
        """
        fitting_problem = FittingProblem(self.options)
        fitting_problem.function = lambda x, p1: x + p1
        x_val = np.array([1, 8, 11])
        eval_result = fitting_problem.eval_model(x=x_val, params=[5])
        self.assertTrue(all(eval_result == np.array([6, 13, 16])))

        fitting_problem.data_x = np.array([20, 21, 22])
        eval_result = fitting_problem.eval_model(params=[5])
        self.assertTrue(all(eval_result == np.array([25, 26, 27])))
Пример #16
0
    def parse(self):

        fitting_problem = FittingProblem()

        equation, data, starting_values, name = self._parse_line_by_line()
        data = self._parse_data(data)

        fitting_problem.data_x = data[:, 1]
        fitting_problem.data_y = data[:, 0]
        if len(data[0, :]) > 2:
            fitting_problem.data_e = data[:, 2]

        fitting_problem.name = name

        # String containing a mathematical expression
        fitting_problem.equation = self._parse_equation(equation)

        fitting_problem.starting_values = starting_values

        fitting_problem.functions = \
            nist_func_definitions(function=fitting_problem.equation,
                                  startvals=fitting_problem.starting_values)

        return fitting_problem
 def test_eval_starting_params(self):
     """
     Test that eval_starting_params returns the correct result
     """
     fitting_problem = FittingProblem()
     self.assertRaises(exceptions.FittingProblemError,
                       fitting_problem.eval_starting_params,
                       param_set=0)
     fitting_problem.function = lambda x, p1: x + p1
     fitting_problem.starting_values = [
         OrderedDict([('p1', 3)]),
         OrderedDict([('p1', 7)])
     ]
     fitting_problem.data_x = np.array([1])
     eval_result = fitting_problem.eval_starting_params(0)
     self.assertTrue(all(eval_result == np.array([4])))
     eval_result = fitting_problem.eval_starting_params(1)
     self.assertTrue(all(eval_result == np.array([8])))
Пример #18
0
 def test_eval_starting_params(self):
     """
     Test that eval_starting_params returns the correct result
     """
     fitting_problem = FittingProblem()
     self.assertRaises(AttributeError,
                       fitting_problem.eval_starting_params,
                       function_id=0)
     fitting_problem.functions = [[lambda x, p1: x + p1, [3]],
                                  [lambda x, p1: x + p1 + 10, [7]]]
     fitting_problem.data_x = np.array([1])
     eval_result = fitting_problem.eval_starting_params(0)
     self.assertTrue(all(eval_result == np.array([4])))
     eval_result = fitting_problem.eval_starting_params(1)
     self.assertTrue(all(eval_result == np.array([18])))
    def test_eval_r_norm(self):
        """
        Test that eval_r_norm is correct
        """
        fitting_problem = FittingProblem()
        fitting_problem.function = lambda x, p1: x + p1
        x_val = np.array([1, 8, 11])
        y_val = np.array([6, 10, 20])
        e_val = np.array([0.5, 10, 0.1])

        eval_result = fitting_problem.eval_r_norm(params=[5],
                                                  x=x_val,
                                                  y=y_val,
                                                  e=e_val)
        self.assertEqual(eval_result, 1600.09)

        fitting_problem.data_x = x_val
        fitting_problem.data_y = y_val
        eval_result = fitting_problem.eval_r_norm(params=[5])
        self.assertEqual(eval_result, 25)
    def test_eval_f(self):
        """
        Test that eval_f is running the correct function
        """
        fitting_problem = FittingProblem()
        self.assertRaises(exceptions.FittingProblemError,
                          fitting_problem.eval_f,
                          x=2,
                          params=[1, 2, 3])
        fitting_problem.function = lambda x, p1: x + p1
        x_val = np.array([1, 8, 11])
        eval_result = fitting_problem.eval_f(x=x_val, params=[5])
        self.assertTrue(all(eval_result == np.array([6, 13, 16])))

        fitting_problem.data_x = np.array([20, 21, 22])
        eval_result = fitting_problem.eval_f(params=[5])
        self.assertTrue(all(eval_result == np.array([25, 26, 27])))
    def test_eval_j(self):
        """
        Test that eval_j is correct
        """
        def f(x, p1, p2):
            return p1 * np.exp(p2 * x)

        def J(x, p):
            return np.column_stack(
                (-np.exp(p[1] * x), -x * p[0] * np.exp(p[1] * x)))

        fitting_problem = FittingProblem()
        fitting_problem.function = f
        fitting_problem.data_x = np.array([1, 2, 3, 4, 5])
        fitting_problem.data_y = np.array([1, 2, 4, 8, 16])
        params = [6, 0.1]

        eval_result = fitting_problem.eval_j(params=params)
        actual = J(x=fitting_problem.data_x, p=params)
        self.assertTrue(np.isclose(actual, eval_result).all())
Пример #22
0
 def test_eval_f(self):
     """
     Test that eval_f is running the correct function
     """
     fitting_problem = FittingProblem()
     self.assertRaises(AttributeError,
                       fitting_problem.eval_f,
                       x=2,
                       params=[1, 2, 3],
                       function_id=0)
     fitting_problem.functions = [[lambda x, p1: x + p1, [3]],
                                  [lambda x, p1: x + p1 + 10, [7]]]
     x_val = np.array([1])
     eval_result = fitting_problem.eval_f(x=x_val,
                                          params=[5],
                                          function_id=0)
     self.assertTrue(all(eval_result == np.array([6])))
     eval_result = fitting_problem.eval_f(x=x_val,
                                          params=[5],
                                          function_id=1)
     self.assertTrue(all(eval_result == np.array([16])))
     fitting_problem.data_x = np.array([20, 21, 22])
     eval_result = fitting_problem.eval_f(params=[5], function_id=0)
     self.assertTrue(all(eval_result == np.array([25, 26, 27])))
    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
        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()
        self.assertTrue(
            np.isclose(fitting_problem.data_x[fitting_problem.sorted_index],
                       expected_x_data).all())
        self.assertTrue(
            np.isclose(fitting_problem.data_y[fitting_problem.sorted_index],
                       expected_y_data).all())
        self.assertTrue(
            np.isclose(fitting_problem.data_e[fitting_problem.sorted_index],
                       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())
        self.assertTrue(
            np.isclose(fitting_problem.data_y[fitting_problem.sorted_index],
                       expected_y_data).all())
        self.assertIs(fitting_problem.data_e, None)
Пример #24
0
    def parse(self):
        """
        Parse the Fitbenchmark problem file into a Fitting Problem.

        :return: The fully parsed fitting problem
        :rtype: fitbenchmarking.parsing.fitting_problem.FittingProblem
        """
        fitting_problem = FittingProblem()

        self._entries = self._get_data_problem_entries()
        software = self._entries['software'].lower()
        if not (software in import_success and import_success[software][0]):
            e = import_success[software][1]
            raise MissingSoftwareError('Requirements are missing for {} parser'
                                       ': {}'.format(software, e))

        self._parsed_func = self._parse_function()

        # NAME
        fitting_problem.name = self._entries['name']

        # DATA
        data_points = self._get_data_points()
        fitting_problem.data_x = data_points[:, 0]
        fitting_problem.data_y = data_points[:, 1]
        if data_points.shape[1] > 2:
            fitting_problem.data_e = data_points[:, 2]

        # FUNCTION
        if software == 'mantid':
            fitting_problem.function = self._create_mantid_function()
        elif software == 'sasview':
            fitting_problem.function = self._create_sasview_function()

        # EQUATION
        equation_count = len(self._parsed_func)
        if equation_count == 1:
            fitting_problem.equation = self._parsed_func[0]['name']
        else:
            fitting_problem.equation = '{} Functions'.format(equation_count)

        if software == 'mantid':
            # String containing the function name(s) and the starting parameter
            # values for each function
            fitting_problem._mantid_equation = self._entries['function']

        # STARTING VALUES
        fitting_problem.starting_values = self._get_starting_values()

        # PARAMETER RANGES
        vr = self._parse_range('parameter_ranges')
        fitting_problem.value_ranges = vr if vr != {} else None

        # FIT RANGES
        fit_ranges = self._parse_range('fit_ranges')
        try:
            fitting_problem.start_x = fit_ranges['x'][0]
            fitting_problem.end_x = fit_ranges['x'][1]
        except KeyError:
            pass

        return fitting_problem
Пример #25
0
class TestJacobianClass(TestCase):
    """
    Tests for Jacobian classes
    """
    def setUp(self):
        """
        Setting up tests
        """
        options = Options()
        options.cost_func_type = "nlls"
        self.fitting_problem = FittingProblem(options)
        self.fitting_problem.function = f
        self.fitting_problem.jacobian = J
        self.fitting_problem.data_x = np.array([1, 2, 3, 4, 5])
        self.fitting_problem.data_y = np.array([1, 2, 4, 8, 16])
        self.cost_func = NLLSCostFunc(self.fitting_problem)
        self.params = [6, 0.1]
        self.actual = J(x=self.fitting_problem.data_x, p=self.params)

    def test_scipy_two_point_eval(self):
        """
        Test for ScipyTwoPoint evaluation is correct
        """
        jac = Scipy(self.cost_func)
        jac.method = '2-point'
        eval_result = jac.eval(params=self.params)
        self.assertTrue(np.isclose(self.actual, eval_result).all())

    def test_scipy_three_point_eval(self):
        """
        Test for ScipyThreePoint evaluation is correct
        """
        jac = Scipy(self.cost_func)
        jac.method = '3-point'
        eval_result = jac.eval(params=self.params)
        self.assertTrue(np.isclose(self.actual, eval_result).all())

    def test_scipy_cs_eval(self):
        """
        Test for ScipyCS evaluation is correct
        """
        jac = Scipy(self.cost_func)
        jac.method = 'cs'
        eval_result = jac.eval(params=self.params)
        self.assertTrue(np.isclose(self.actual, eval_result).all())

    def test_analytic_cutest_no_errors(self):
        """
        Test analytic Jacobian
        """
        self.fitting_problem.options.cost_func_type = "nlls"
        self.fitting_problem.format = "cutest"
        jac = Analytic(self.cost_func)
        eval_result = jac.eval(params=self.params)
        self.assertTrue(np.isclose(self.actual, eval_result).all())

    def test_analytic_cutest_weighted(self):
        """
        Test analytic Jacobian
        """
        self.fitting_problem.options.cost_func_type = "weighted_nlls"
        e = np.array([1, 2, 1, 3, 1])
        self.fitting_problem.data_e = e
        self.fitting_problem.format = "cutest"
        jac = Analytic(self.cost_func)
        eval_result = jac.eval(params=self.params)
        scaled_actual = self.actual / e[:, None]
        self.assertTrue(np.isclose(scaled_actual, eval_result).all())

    def test_analytic_cutest_root(self):
        """
        Test analytic Jacobian
        """
        self.fitting_problem.options.cost_func_type = "root_nlls"
        self.fitting_problem.format = "cutest"
        jac = Analytic(self.cost_func)
        eval_result = jac.eval(params=self.params)
        scaled_actual = self.actual * \
            self.fitting_problem.eval_model(self.params)[:, None] / 2

        self.assertTrue(np.isclose(scaled_actual, eval_result).all())

    def test_analytic_raise_error(self):
        """
        Test analytic Jacobian raises an exception when problem.jacobian is
        not callable
        """
        self.fitting_problem.jacobian = None
        with self.assertRaises(exceptions.NoJacobianError):
            Analytic(self.cost_func)
Пример #26
0
    def parse(self):
        """
        Parse the NIST problem file into a Fitting Problem.

        :return: The fully parsed fitting problem
        :rtype: fitbenchmarking.parsing.fitting_problem.FittingProblem
        """

        fitting_problem = FittingProblem(self.options)

        equation, data, starting_values, name = self._parse_line_by_line()
        data = self._parse_data(data)

        fitting_problem.data_x = data[:, 1]
        fitting_problem.data_y = data[:, 0]
        if len(data[0, :]) > 2:
            fitting_problem.data_e = data[:, 2]

        fitting_problem.name = name

        # String containing a mathematical expression
        fitting_problem.equation = self._parse_equation(equation)

        fitting_problem.starting_values = starting_values

        fitting_problem.function = \
            nist_func_definition(function=fitting_problem.equation,
                                 param_names=starting_values[0].keys())
        fitting_problem.format = "nist"
        try:
            jacobian = self._parse_jacobian(name)
            fitting_problem.jacobian = \
                nist_jacobian_definition(jacobian=jacobian,
                                         param_names=starting_values[0].keys())
        except NoJacobianError:
            LOGGER.warn("WARNING: Could not find analytic Jacobian "
                        "information for {} problem".format(name))

        return fitting_problem
Пример #27
0
def load_expectation(filename):
    """
    Load an expected fitting problem from a json file.

    :param filename: The path to the expectation file
    :type filename: string
    :return: A fitting problem to test against
    :rtype: fitbenchmarking.parsing.FittingProblem
    """
    with open(filename, 'r') as f:
        expectation_dict = load(f)

    expectation = FittingProblem(OPTIONS)
    expectation.name = expectation_dict['name']
    expectation.start_x = expectation_dict['start_x']
    expectation.end_x = expectation_dict['end_x']
    expectation.data_x = np.array(expectation_dict['data_x'])
    expectation.data_y = np.array(expectation_dict['data_y'])
    expectation.data_e = expectation_dict['data_e']
    if expectation.data_e is not None:
        expectation.data_e = np.array(expectation.data_e)
    expectation.starting_values = expectation_dict['starting_values']
    expectation.value_ranges = expectation_dict['value_ranges']

    return expectation
    def test_correct_data_multi_fit(self):
        """
        Tests correct data on a multifit problem.
        """
        fitting_problem = FittingProblem(self.options)
        fitting_problem.multifit = True
        x_data = [
            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 = [
            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 = [
            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]
        expected_x_data = [
            np.array([0.5, 1.0, 1.5, 2.0, 2.5]),
            np.array([1.4, 2.0, 2.5]),
            np.array([0.0, 0.5, 1.0])
        ]
        expected_y_data = [
            np.array([3.0, 2.0, 4.0, 5.0, 6.0]),
            np.array([24.0, 5.0, 6.0]),
            np.array([1.0, 3.0, 2.8])
        ]
        expected_e_data = [
            np.array([40.0, 30.0, 50.0, 60.0, 1.0]),
            np.array([50.0, 60.0, 1.0]),
            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):
            self.assertTrue(
                np.isclose(
                    fitting_problem.data_x[i][fitting_problem.sorted_index[i]],
                    expected_x_data[i]).all())
            self.assertTrue(
                np.isclose(
                    fitting_problem.data_y[i][fitting_problem.sorted_index[i]],
                    expected_y_data[i]).all())
            self.assertTrue(
                np.isclose(
                    fitting_problem.data_e[i][fitting_problem.sorted_index[i]],
                    expected_e_data[i]).all())

        self.options.cost_func_type = "nlls"
        fitting_problem.correct_data()
        for i in range(3):
            self.assertTrue(
                np.isclose(
                    fitting_problem.data_x[i][fitting_problem.sorted_index[i]],
                    expected_x_data[i]).all())
            self.assertTrue(
                np.isclose(
                    fitting_problem.data_y[i][fitting_problem.sorted_index[i]],
                    expected_y_data[i]).all())
            self.assertIs(fitting_problem.data_e[i], None)
    def test_verify_problem(self):
        """
        Test that verify only passes if all required values are set.
        """
        fitting_problem = FittingProblem(self.options)
        with self.assertRaises(exceptions.FittingProblemError):
            fitting_problem.verify()
            self.fail('verify() passes when no values are set.')

        fitting_problem.starting_values = [OrderedDict([('p1', 1), ('p2', 2)])]
        with self.assertRaises(exceptions.FittingProblemError):
            fitting_problem.verify()
            self.fail('verify() passes starting values are set.')

        fitting_problem.data_x = np.array([1, 2, 3, 4, 5])
        with self.assertRaises(exceptions.FittingProblemError):
            fitting_problem.verify()
            self.fail('verify() passes when data_x is set.')

        fitting_problem.data_y = np.array([1, 2, 3, 4, 5])
        with self.assertRaises(exceptions.FittingProblemError):
            fitting_problem.verify()
            self.fail('verify() passes when data_y is set.')

        fitting_problem.function = lambda x, p1, p2: p1 + p2
        try:
            fitting_problem.verify()
        except exceptions.FittingProblemError:
            self.fail('verify() fails when all required values set.')

        fitting_problem.data_x = [1, 2, 3]
        with self.assertRaises(exceptions.FittingProblemError):
            fitting_problem.verify()
            self.fail('verify() passes for x values not numpy.')
    def parse(self):
        """
        Parse the Fitbenchmark problem file into a Fitting Problem.

        :return: The fully parsed fitting problem
        :rtype: fitbenchmarking.parsing.fitting_problem.FittingProblem
        """
        # pylint: disable=attribute-defined-outside-init
        fitting_problem = FittingProblem(self.options)

        self._entries = self._get_data_problem_entries()
        software = self._entries['software'].lower()
        if not (software in import_success and import_success[software][0]):
            error = import_success[software][1]
            raise MissingSoftwareError('Requirements are missing for {} parser'
                                       ': {}'.format(software, error))

        self._parsed_func = self._parse_function()

        if software == 'mantid' and self._entries['input_file'][0] == '[':
            fitting_problem.multifit = True

        # NAME
        fitting_problem.name = self._entries['name']

        # DATA
        data_points = [_get_data_points(p) for p in self._get_data_file()]

        # FUNCTION
        if software == 'mantid':
            fitting_problem.function = self._create_mantid_function()
            fitting_problem.format = 'mantid'
        elif software == 'sasview':
            fitting_problem.function = self._create_sasview_function()
            fitting_problem.format = 'sasview'

        # EQUATION
        equation_count = len(self._parsed_func)
        if equation_count == 1:
            fitting_problem.equation = self._parsed_func[0]['name']
        else:
            fitting_problem.equation = '{} Functions'.format(equation_count)

        # STARTING VALUES
        fitting_problem.starting_values = self._get_starting_values()

        # PARAMETER RANGES
        vr = _parse_range(self._entries.get('parameter_ranges', ''))
        fitting_problem.value_ranges = vr if vr != {} else None

        # FIT RANGES
        fit_ranges_str = self._entries.get('fit_ranges', '')
        # this creates a list of strs like '{key: val, ...}' and parses each
        fit_ranges = [
            _parse_range('{' + r.split('}')[0] + '}')
            for r in fit_ranges_str.split('{')[1:]
        ]

        if fitting_problem.multifit:
            num_files = len(data_points)
            fitting_problem.data_x = [d[:, 0] for d in data_points]
            fitting_problem.data_y = [d[:, 1] for d in data_points]
            fitting_problem.data_e = [
                d[:, 2] if d.shape[1] > 2 else None for d in data_points
            ]

            if not fit_ranges:
                fit_ranges = [{} for _ in range(num_files)]

            fitting_problem.start_x = [
                f['x'][0] if 'x' in f else None for f in fit_ranges
            ]
            fitting_problem.end_x = [
                f['x'][1] if 'x' in f else None for f in fit_ranges
            ]

        else:
            fitting_problem.data_x = data_points[0][:, 0]
            fitting_problem.data_y = data_points[0][:, 1]
            if data_points[0].shape[1] > 2:
                fitting_problem.data_e = data_points[0][:, 2]

            if fit_ranges and 'x' in fit_ranges[0]:
                fitting_problem.start_x = fit_ranges[0]['x'][0]
                fitting_problem.end_x = fit_ranges[0]['x'][1]

        if software == 'mantid':
            # String containing the function name(s) and the starting parameter
            # values for each function.
            fitting_problem.additional_info['mantid_equation'] \
                = self._entries['function']

            if fitting_problem.multifit:
                fitting_problem.additional_info['mantid_ties'] \
                    = self._parse_ties()

        return fitting_problem