Imported Upstream version 1.72.0
[platform/upstream/boost.git] / libs / geometry / test / formulas / test_formula.hpp
1 // Boost.Geometry
2 // Unit Test
3
4 // Copyright (c) 2016-2019 Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
7
8 // Use, modification and distribution is subject to the Boost Software License,
9 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
10 // http://www.boost.org/LICENSE_1_0.txt)
11
12 #ifndef BOOST_GEOMETRY_TEST_FORMULA_HPP
13 #define BOOST_GEOMETRY_TEST_FORMULA_HPP
14
15 #include <geometry_test_common.hpp>
16
17 #include <boost/geometry/util/math.hpp>
18
19 void normalize_deg(double & deg)
20 {
21     while (deg > 180.0)
22         deg -= 360.0;
23     while (deg <= -180.0)
24         deg += 360.0;
25 }
26
27
28 #define BOOST_GEOMETRY_CHECK_CLOSE( L, R, T, M )        BOOST_TEST_TOOL_IMPL( 0, \
29     ::boost::test_tools::check_is_close_t(), M, CHECK, CHECK_MSG, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
30
31
32 void check_one(std::string const& name, double result, double expected)
33 {
34     std::string id = name.empty() ? "" : (name + " : ");
35
36     double eps = std::numeric_limits<double>::epsilon();
37     double abs_result = bg::math::abs(result);
38     double abs_expected = bg::math::abs(expected);
39     double res_max = (std::max)(abs_result, abs_expected);
40     double res_min = (std::min)(abs_result, abs_expected);
41     if (res_min <= eps) // including 0
42     {
43         bool is_close = abs_result <= 30 * eps && abs_expected <= 30 * eps;
44         BOOST_CHECK_MESSAGE((is_close),
45             id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
46     }
47     else if (res_max > 100 * eps)
48     {
49         BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 0.1,
50             id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
51     }
52     else if (res_max > 10 * eps)
53     {
54         BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 10,
55             id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
56     }
57     else if (res_max > eps)
58     {
59         BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 1000,
60             id << std::setprecision(20) << "result {" << result << "} different than expected {" << expected << "}.");
61     }
62 }
63
64 void check_one(std::string const& name,
65                double result, double expected, double reference, double reference_error,
66                bool normalize = false, bool check_reference_only = false)
67 {
68     std::string id = name.empty() ? "" : (name + " : ");
69
70     if (normalize)
71     {
72         normalize_deg(result);
73         normalize_deg(expected);
74         normalize_deg(reference);
75     }
76
77     if (! check_reference_only)
78     {
79         check_one(name, result, expected);
80     }
81
82     // NOTE: in some cases it probably will be necessary to normalize
83     //       the differences between the result and expected result
84     double ref_diff = bg::math::abs(result - reference);
85     double ref_max = (std::max)(bg::math::abs(result), bg::math::abs(reference));
86     bool is_ref_close = ref_diff <= reference_error || ref_diff <= reference_error * ref_max;
87     BOOST_CHECK_MESSAGE((is_ref_close),
88         id << std::setprecision(20) << "result {" << result << "} and reference {" << reference << "} not close enough.");
89 }
90
91 void check_one(double result, double expected, double reference, double reference_error,
92                bool normalize = false, bool check_reference_only = false)
93 {
94     check_one("", result, expected, reference, reference_error, normalize, check_reference_only);
95 }
96
97 #endif // BOOST_GEOMETRY_TEST_FORMULA_HPP