File: MinimizerTestPlan.cpp

package info (click to toggle)
bornagain 23.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,936 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 318; ruby: 173; xml: 130; makefile: 51; ansic: 24
file content (91 lines) | stat: -rw-r--r-- 2,893 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
//  ************************************************************************************************
//
//  BornAgain: simulate and fit reflection and scattering
//
//! @file      Fit/TestEngine/MinimizerTestPlan.cpp
//! @brief     Implements class MinimizerTestPlan.
//!
//! @homepage  http://www.bornagainproject.org
//! @license   GNU General Public License v3 or higher (see COPYING)
//! @copyright Forschungszentrum Jülich GmbH 2018
//! @authors   Scientific Computing Group at MLZ (see CITATION, AUTHORS)
//
//  ************************************************************************************************

#include "Fit/TestEngine/MinimizerTestPlan.h"
#include "Fit/Param/Parameters.h"
#include <cmath>
#include <iostream>
#include <sstream>

namespace {

//! Returns the safe relative difference, which is 2(|a-b|)/(|a|+|b|) except in special cases.
double relativeDifference(double a, double b)
{
    constexpr double eps = std::numeric_limits<double>::epsilon();
    const double avg_abs = (std::abs(a) + std::abs(b)) / 2.0;
    // return 0.0 if relative error smaller than epsilon
    if (std::abs(a - b) <= eps * avg_abs)
        return 0.0;
    return std::abs(a - b) / avg_abs;
}

} // namespace

using namespace mumufit;

MinimizerTestPlan::~MinimizerTestPlan() = default;

void MinimizerTestPlan::addParameter(const Parameter& param, double expected_value,
                                     double tolerance)
{
    m_parameter_references.push_back({param, expected_value, tolerance});
}

//! Returns fit parameters which will be used as initial one for the minimization.

Parameters MinimizerTestPlan::parameters() const
{
    Parameters result;
    for (const auto& ref : m_parameter_references)
        result.add(ref.parameter);

    return result;
}

//! Return vector of expected parameter values.

std::vector<double> MinimizerTestPlan::expectedValues() const
{
    std::vector<double> result;
    for (const ParameterReference& ref : m_parameter_references)
        result.push_back(ref.expected_value);

    return result;
}

//! Returns true if given values coincide with expected fit parameter values.

bool MinimizerTestPlan::valuesAsExpected(const std::vector<double>& values) const
{
    bool success = true;

    if (m_parameter_references.size() != values.size())
        throw std::runtime_error("FunctionTestPlan::valuesAsExpected -> Error. Sizes differ.");

    for (size_t i = 0; i < values.size(); ++i) {
        const ParameterReference& ref = m_parameter_references[i];
        double diff = relativeDifference(values[i], ref.expected_value);

        bool ok = diff <= ref.tolerance;

        std::cout << ref.parameter.name() << " found:" << values[i]
                  << " expected:" << ref.expected_value << " diff:" << diff << " "
                  << (ok ? "OK" : "FAILED") << std::endl;

        success &= ok;
    }

    return success;
}