]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/formulas/test_formula.hpp
09f780163db85feac2fe2c037ddacd689e44e208
[ceph.git] / ceph / src / boost / 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/formulas/result_inverse.hpp>
18 #include <boost/geometry/util/math.hpp>
19
20 void normalize_deg(double & deg)
21 {
22 while (deg > 180.0)
23 deg -= 360.0;
24 while (deg <= -180.0)
25 deg += 360.0;
26 }
27
28
29 #define BOOST_GEOMETRY_CHECK_CLOSE( L, R, T, M ) BOOST_TEST_TOOL_IMPL( 0, \
30 ::boost::test_tools::check_is_close_t(), M, CHECK, CHECK_MSG, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
31
32
33 void check_one(std::string const& name, double result, double expected)
34 {
35 std::string id = name.empty() ? "" : (name + " : ");
36
37 double eps = std::numeric_limits<double>::epsilon();
38 double abs_result = bg::math::abs(result);
39 double abs_expected = bg::math::abs(expected);
40 double res_max = (std::max)(abs_result, abs_expected);
41 double res_min = (std::min)(abs_result, abs_expected);
42 if (res_min <= eps) // including 0
43 {
44 bool is_close = abs_result <= 30 * eps && abs_expected <= 30 * eps;
45 BOOST_CHECK_MESSAGE((is_close),
46 id << std::setprecision(20) << "result {" << result
47 << "} different than expected {" << expected << "}.");
48 }
49 else if (res_max > 100 * eps)
50 {
51 BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 0.1,
52 id << std::setprecision(20) << "result {" << result
53 << "} different than expected {" << expected << "}.");
54 }
55 else if (res_max > 10 * eps)
56 {
57 BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 10,
58 id << std::setprecision(20) << "result {" << result
59 << "} different than expected {" << expected << "}.");
60 }
61 else if (res_max > eps)
62 {
63 BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 1000,
64 id << std::setprecision(20) << "result {" << result
65 << "} different than expected {" << expected << "}.");
66 }
67 }
68
69 void check_one(std::string const& name,
70 double result, double expected, double reference, double reference_error,
71 bool normalize = false, bool check_reference_only = false)
72 {
73 std::string id = name.empty() ? "" : (name + " : ");
74
75 if (normalize)
76 {
77 normalize_deg(result);
78 normalize_deg(expected);
79 normalize_deg(reference);
80 }
81
82 if (! check_reference_only)
83 {
84 check_one(name, result, expected);
85 }
86
87 // NOTE: in some cases it probably will be necessary to normalize
88 // the differences between the result and expected result
89 double ref_diff = bg::math::abs(result - reference);
90 double ref_max = (std::max)(bg::math::abs(result), bg::math::abs(reference));
91 bool is_ref_close = ref_diff <= reference_error || ref_diff <= reference_error * ref_max;
92 BOOST_CHECK_MESSAGE((is_ref_close),
93 id << std::setprecision(20) << "result {" << result << "} and reference {"
94 << reference << "} not close enough.");
95 }
96
97 void check_one(double result, double expected, double reference, double reference_error,
98 bool normalize = false, bool check_reference_only = false)
99 {
100 check_one("", result, expected, reference, reference_error, normalize,
101 check_reference_only);
102 }
103
104 template <typename Result, typename ExpectedResult>
105 void check_inverse(std::string const& name,
106 Result const& results,
107 boost::geometry::formula::result_inverse<double> const& result,
108 ExpectedResult const& expected,
109 ExpectedResult const& reference,
110 double reference_error)
111 {
112 std::stringstream ss;
113 ss << "(" << results.p1.lon << " " << results.p1.lat << ")->("
114 << results.p2.lon << " " << results.p2.lat << ")";
115
116 check_one(name + "_d " + ss.str(),
117 result.distance, expected.distance, reference.distance, reference_error);
118 check_one(name + "_a " + ss.str(),
119 result.azimuth, expected.azimuth, reference.azimuth, reference_error, true);
120 check_one(name + "_ra " + ss.str(),
121 result.reverse_azimuth, expected.reverse_azimuth, reference.reverse_azimuth,
122 reference_error, true);
123 check_one(name + "_rl " + ss.str(),
124 result.reduced_length, expected.reduced_length, reference.reduced_length,
125 reference_error);
126 check_one(name + "_gs " + ss.str(),
127 result.geodesic_scale, expected.geodesic_scale, reference.geodesic_scale,
128 reference_error);
129 }
130
131 #endif // BOOST_GEOMETRY_TEST_FORMULA_HPP