]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/test/test_root_finding_concepts.cpp
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / boost / libs / math / test / test_root_finding_concepts.cpp
1 // Copyright John Maddock 2014
2
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #define BOOST_TEST_MAIN
9 #include <boost/test/unit_test.hpp> // Boost.Test
10 #include <boost/test/results_collector.hpp>
11 #include <boost/test/unit_test.hpp>
12 #include <boost/test/tools/floating_point_comparison.hpp>
13 #include <boost/tuple/tuple.hpp>
14 #include <boost/fusion/include/tuple.hpp>
15 #include <boost/fusion/include/std_pair.hpp>
16 #include <boost/math/tools/toms748_solve.hpp>
17 #include <tuple>
18
19 #include <iostream>
20 #include <iomanip>
21 using std::cout;
22 using std::endl;
23 using std::setprecision;
24
25 #include <boost/math/tools/roots.hpp>
26
27 //
28 // We'll use cbrt as an example:
29 //
30 struct cbtr_functor_1
31 {
32 cbtr_functor_1(double x) : m_target(x) {}
33 double operator()(double x)
34 {
35 return x * x * x - m_target;
36 }
37 private:
38 double m_target;
39 };
40
41 struct cbtr_functor_2a
42 {
43 cbtr_functor_2a(double x) : m_target(x) {}
44 std::pair<double, double> operator()(double x)
45 {
46 return std::make_pair(x * x * x - m_target, 3 * x * x);
47 }
48 private:
49 double m_target;
50 };
51
52 struct cbtr_functor_2b
53 {
54 cbtr_functor_2b(double x) : m_target(x) {}
55 std::tuple<double, double> operator()(double x)
56 {
57 return std::tuple<double, double>(x * x * x - m_target, 3 * x * x);
58 }
59 private:
60 double m_target;
61 };
62 struct cbtr_functor_2c
63 {
64 cbtr_functor_2c(double x) : m_target(x) {}
65 boost::tuple<double, double> operator()(double x)
66 {
67 return boost::tuple<double, double>(x * x * x - m_target, 3 * x * x);
68 }
69 private:
70 double m_target;
71 };
72 struct cbtr_functor_2d
73 {
74 cbtr_functor_2d(double x) : m_target(x) {}
75 boost::fusion::tuple<double, double> operator()(double x)
76 {
77 return boost::fusion::tuple<double, double>(x * x * x - m_target, 3 * x * x);
78 }
79 private:
80 double m_target;
81 };
82
83 struct cbtr_functor_3b
84 {
85 cbtr_functor_3b(double x) : m_target(x) {}
86 std::tuple<double, double, double> operator()(double x)
87 {
88 return std::tuple<double, double, double>(x * x * x - m_target, 3 * x * x, 6 * x);
89 }
90 private:
91 double m_target;
92 };
93
94 struct cbtr_functor_3c
95 {
96 cbtr_functor_3c(double x) : m_target(x) {}
97 boost::tuple<double, double, double> operator()(double x)
98 {
99 return boost::tuple<double, double, double>(x * x * x - m_target, 3 * x * x, 6 * x);
100 }
101 private:
102 double m_target;
103 };
104 struct cbtr_functor_3d
105 {
106 cbtr_functor_3d(double x) : m_target(x) {}
107 boost::fusion::tuple<double, double, double> operator()(double x)
108 {
109 return boost::fusion::tuple<double, double, double>(x * x * x - m_target, 3 * x * x, 6 * x);
110 }
111 private:
112 double m_target;
113 };
114
115
116 BOOST_AUTO_TEST_CASE( test_main )
117 {
118 double x = 27;
119 double expected = 3;
120 double result;
121 double tolerance = std::numeric_limits<double>::epsilon() * 5;
122 std::pair<double, double> p;
123 //
124 // Start by trying the unary functors, bisect first:
125 //
126 cbtr_functor_1 f1(x);
127 boost::math::tools::eps_tolerance<double> t(std::numeric_limits<double>::digits - 1);
128 p = boost::math::tools::bisect(f1, 0.0, x, t);
129 result = (p.first + p.second) / 2;
130 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
131 //
132 // bracket_and_solve_root:
133 //
134 std::uintmax_t max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
135 p = boost::math::tools::bracket_and_solve_root(f1, x, 2.0, true, t, max_iter);
136 result = (p.first + p.second) / 2;
137 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
138 //
139 // toms748_solve:
140 //
141 max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
142 p = boost::math::tools::toms748_solve(f1, 0.0, x, t, max_iter);
143 result = (p.first + p.second) / 2;
144 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
145
146 //
147 // Now try again with C++11 lambda's
148 //
149 p = boost::math::tools::bisect([x](double z){ return z * z * z - x; }, 0.0, x, t);
150 result = (p.first + p.second) / 2;
151 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
152 //
153 // bracket_and_solve_root:
154 //
155 max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
156 p = boost::math::tools::bracket_and_solve_root([x](double z){ return z * z * z - x; }, x, 2.0, true, t, max_iter);
157 result = (p.first + p.second) / 2;
158 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
159 //
160 // toms748_solve:
161 //
162 max_iter = boost::math::policies::get_max_root_iterations<boost::math::policies::policy<> >();
163 p = boost::math::tools::toms748_solve([x](double z){ return z * z * z - x; }, 0.0, x, t, max_iter);
164 result = (p.first + p.second) / 2;
165 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
166
167 cbtr_functor_2a f2(x);
168 cbtr_functor_2b f3(x);
169 cbtr_functor_2c f4(x);
170 cbtr_functor_2d f5(x);
171
172 //
173 // Binary Functors - newton_raphson_iterate - test each possible tuple type:
174 //
175 result = boost::math::tools::newton_raphson_iterate(f2, x, 0.0, x, std::numeric_limits<double>::digits - 1);
176 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
177 result = boost::math::tools::newton_raphson_iterate(f3, x, 0.0, x, std::numeric_limits<double>::digits - 1);
178 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
179 result = boost::math::tools::newton_raphson_iterate(f4, x, 0.0, x, std::numeric_limits<double>::digits - 1);
180 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
181 result = boost::math::tools::newton_raphson_iterate(f5, x, 0.0, x, std::numeric_limits<double>::digits - 1);
182 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
183 //
184 // And again but with lambdas:
185 //
186 result = boost::math::tools::newton_raphson_iterate([x](double z){ return std::make_pair(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
187 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
188 result = boost::math::tools::newton_raphson_iterate([x](double z){ return std::make_tuple(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
189 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
190 result = boost::math::tools::newton_raphson_iterate([x](double z){ return boost::tuple<double, double>(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
191 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
192 result = boost::math::tools::newton_raphson_iterate([x](double z){ return boost::fusion::tuple<double, double>(z * z * z - x, 3 * z * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
193 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
194 cbtr_functor_3b f6(x);
195 cbtr_functor_3c f7(x);
196 cbtr_functor_3d f8(x);
197
198 //
199 // Ternary functors:
200 //
201 result = boost::math::tools::halley_iterate(f6, x, 0.0, x, std::numeric_limits<double>::digits - 1);
202 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
203 result = boost::math::tools::halley_iterate(f7, x, 0.0, x, std::numeric_limits<double>::digits - 1);
204 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
205 result = boost::math::tools::halley_iterate(f8, x, 0.0, x, std::numeric_limits<double>::digits - 1);
206 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
207 result = boost::math::tools::halley_iterate([x](double z){ return std::make_tuple(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
208 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
209 result = boost::math::tools::halley_iterate([x](double z){ return boost::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
210 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
211 result = boost::math::tools::halley_iterate([x](double z){ return boost::fusion::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
212 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
213 result = boost::math::tools::schroder_iterate(f6, x, 0.0, x, std::numeric_limits<double>::digits - 1);
214 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
215 result = boost::math::tools::schroder_iterate(f7, x, 0.0, x, std::numeric_limits<double>::digits - 1);
216 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
217 result = boost::math::tools::schroder_iterate(f8, x, 0.0, x, std::numeric_limits<double>::digits - 1);
218 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
219 result = boost::math::tools::schroder_iterate([x](double z){ return std::make_tuple(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
220 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
221 result = boost::math::tools::schroder_iterate([x](double z){ return boost::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
222 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
223 result = boost::math::tools::schroder_iterate([x](double z){ return boost::fusion::tuple<double, double, double>(z * z * z - x, 3 * z * z, 6 * z); }, x, 0.0, x, std::numeric_limits<double>::digits - 1);
224 BOOST_CHECK_CLOSE_FRACTION(expected, result, tolerance);
225 } // BOOST_AUTO_TEST_CASE( test_main )
226