]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Copyright John Maddock 2015. |
2 | // Use, modification and distribution are subject to the | |
3 | // Boost Software License, Version 1.0. (See accompanying file | |
4 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
5 | ||
6 | #ifdef _MSC_VER | |
7 | # pragma warning (disable : 4224) | |
8 | #endif | |
9 | ||
10 | #include <boost/array.hpp> | |
11 | #include <boost/lexical_cast.hpp> | |
12 | #include "../../test/table_type.hpp" | |
13 | #include "table_helper.hpp" | |
14 | #include "performance.hpp" | |
15 | #include <iostream> | |
16 | ||
17 | #define evaluate_polynomial_c_imp evaluate_polynomial_c_imp_1 | |
18 | #undef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP | |
19 | #include <boost/math/tools/detail/polynomial_horner1_20.hpp> | |
20 | #undef evaluate_polynomial_c_imp | |
21 | #undef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP | |
22 | #define evaluate_polynomial_c_imp evaluate_polynomial_c_imp_2 | |
23 | #include <boost/math/tools/detail/polynomial_horner2_20.hpp> | |
24 | #undef evaluate_polynomial_c_imp | |
25 | #undef BOOST_MATH_TOOLS_POLY_EVAL_20_HPP | |
26 | #define evaluate_polynomial_c_imp evaluate_polynomial_c_imp_3 | |
27 | #include <boost/math/tools/detail/polynomial_horner3_20.hpp> | |
28 | #undef evaluate_polynomial_c_imp | |
29 | ||
30 | #undef BOOST_MATH_TOOLS_POLY_RAT_20_HPP | |
31 | #define evaluate_rational_c_imp evaluate_rational_c_imp_1 | |
32 | #include <boost/math/tools/detail/rational_horner1_20.hpp> | |
33 | #undef evaluate_rational_c_imp | |
34 | #undef BOOST_MATH_TOOLS_POLY_RAT_20_HPP | |
35 | #define evaluate_rational_c_imp evaluate_rational_c_imp_2 | |
36 | #include <boost/math/tools/detail/rational_horner2_20.hpp> | |
37 | #undef evaluate_rational_c_imp | |
38 | #undef BOOST_MATH_TOOLS_RAT_EVAL_20_HPP | |
39 | #define evaluate_rational_c_imp evaluate_rational_c_imp_3 | |
40 | #include <boost/math/tools/detail/rational_horner3_20.hpp> | |
41 | #undef evaluate_rational_c_imp | |
42 | #undef BOOST_MATH_TOOLS_POLY_RAT_20_HPP | |
43 | ||
44 | static const double num[21] = { | |
45 | static_cast<double>(56906521.91347156388090791033559122686859L), | |
46 | static_cast<double>(103794043.1163445451906271053616070238554L), | |
47 | static_cast<double>(86363131.28813859145546927288977868422342L), | |
48 | static_cast<double>(43338889.32467613834773723740590533316085L), | |
49 | static_cast<double>(14605578.08768506808414169982791359218571L), | |
50 | static_cast<double>(3481712.15498064590882071018964774556468L), | |
51 | static_cast<double>(601859.6171681098786670226533699352302507L), | |
52 | static_cast<double>(75999.29304014542649875303443598909137092L), | |
53 | static_cast<double>(6955.999602515376140356310115515198987526L), | |
54 | static_cast<double>(449.9445569063168119446858607650988409623L), | |
55 | static_cast<double>(19.51992788247617482847860966235652136208L), | |
56 | static_cast<double>(0.5098416655656676188125178644804694509993L), | |
57 | static_cast<double>(0.006061842346248906525783753964555936883222L), | |
58 | 0.0 | |
59 | }; | |
60 | static const double denom[20] = { | |
61 | static_cast<double>(0u), | |
62 | static_cast<double>(39916800u), | |
63 | static_cast<double>(120543840u), | |
64 | static_cast<double>(150917976u), | |
65 | static_cast<double>(105258076u), | |
66 | static_cast<double>(45995730u), | |
67 | static_cast<double>(13339535u), | |
68 | static_cast<double>(2637558u), | |
69 | static_cast<double>(357423u), | |
70 | static_cast<double>(32670u), | |
71 | static_cast<double>(1925u), | |
72 | static_cast<double>(66u), | |
73 | static_cast<double>(1u), | |
74 | 0.0 | |
75 | }; | |
76 | static const boost::uint32_t denom_int[20] = { | |
77 | static_cast<boost::uint32_t>(0u), | |
78 | static_cast<boost::uint32_t>(39916800u), | |
79 | static_cast<boost::uint32_t>(120543840u), | |
80 | static_cast<boost::uint32_t>(150917976u), | |
81 | static_cast<boost::uint32_t>(105258076u), | |
82 | static_cast<boost::uint32_t>(45995730u), | |
83 | static_cast<boost::uint32_t>(13339535u), | |
84 | static_cast<boost::uint32_t>(2637558u), | |
85 | static_cast<boost::uint32_t>(357423u), | |
86 | static_cast<boost::uint32_t>(32670u), | |
87 | static_cast<boost::uint32_t>(1925u), | |
88 | static_cast<boost::uint32_t>(66u), | |
89 | static_cast<boost::uint32_t>(1u), | |
90 | 0 | |
91 | }; | |
92 | ||
93 | std::string make_order_string(int n) | |
94 | { | |
95 | std::string result = boost::lexical_cast<std::string>(n); | |
96 | if (result.size() < 2) | |
97 | result.insert(result.begin(), ' '); | |
98 | return result; | |
99 | } | |
100 | ||
f67539c2 | 101 | void test_poly_1(const boost::integral_constant<int, 1>&) |
7c673cae FG |
102 | { |
103 | } | |
104 | ||
105 | template <int N> | |
f67539c2 | 106 | void test_poly_1(const boost::integral_constant<int, N>&) |
7c673cae | 107 | { |
f67539c2 | 108 | test_poly_1(boost::integral_constant<int, N - 1>()); |
7c673cae FG |
109 | |
110 | double time = exec_timed_test([](const std::vector<double>& v) | |
111 | { | |
112 | double result = 0; | |
113 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 114 | result += boost::math::tools::detail::evaluate_polynomial_c_imp_1(denom, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
115 | return result; |
116 | }); | |
117 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Double Coefficients)"); | |
118 | ||
119 | time = exec_timed_test([](const std::vector<double>& v) | |
120 | { | |
121 | double result = 0; | |
122 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 123 | result += boost::math::tools::detail::evaluate_polynomial_c_imp_1(denom_int, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
124 | return result; |
125 | }); | |
126 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Integer Coefficients)"); | |
127 | } | |
128 | ||
129 | ||
f67539c2 | 130 | void test_poly_2(const boost::integral_constant<int, 1>&) |
7c673cae FG |
131 | { |
132 | } | |
133 | ||
134 | template <int N> | |
f67539c2 | 135 | void test_poly_2(const boost::integral_constant<int, N>&) |
7c673cae | 136 | { |
f67539c2 | 137 | test_poly_2(boost::integral_constant<int, N - 1>()); |
7c673cae FG |
138 | |
139 | double time = exec_timed_test([](const std::vector<double>& v) | |
140 | { | |
141 | double result = 0; | |
142 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 143 | result += boost::math::tools::detail::evaluate_polynomial_c_imp_2(denom, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
144 | return result; |
145 | }); | |
146 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Double Coefficients)"); | |
147 | ||
148 | time = exec_timed_test([](const std::vector<double>& v) | |
149 | { | |
150 | double result = 0; | |
151 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 152 | result += boost::math::tools::detail::evaluate_polynomial_c_imp_2(denom_int, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
153 | return result; |
154 | }); | |
155 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Integer Coefficients)"); | |
156 | } | |
157 | ||
f67539c2 | 158 | void test_poly_3(const boost::integral_constant<int, 1>&) |
7c673cae FG |
159 | { |
160 | } | |
161 | ||
162 | template <int N> | |
f67539c2 | 163 | void test_poly_3(const boost::integral_constant<int, N>&) |
7c673cae | 164 | { |
f67539c2 | 165 | test_poly_3(boost::integral_constant<int, N - 1>()); |
7c673cae FG |
166 | |
167 | double time = exec_timed_test([](const std::vector<double>& v) { double result = 0; | |
168 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 169 | result += boost::math::tools::detail::evaluate_polynomial_c_imp_3(denom, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
170 | return result; |
171 | }); | |
172 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Double Coefficients)"); | |
173 | ||
174 | time = exec_timed_test([](const std::vector<double>& v) { double result = 0; | |
175 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 176 | result += boost::math::tools::detail::evaluate_polynomial_c_imp_3(denom_int, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
177 | return result; |
178 | }); | |
179 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Integer Coefficients)"); | |
180 | } | |
181 | ||
182 | template <class T, class U> | |
183 | U evaluate_polynomial_0(const T* poly, U const& z, std::size_t count) | |
184 | { | |
185 | U sum = static_cast<U>(poly[count - 1]); | |
186 | for (int i = static_cast<int>(count) - 2; i >= 0; --i) | |
187 | { | |
188 | sum *= z; | |
189 | sum += static_cast<U>(poly[i]); | |
190 | } | |
191 | return sum; | |
192 | } | |
193 | ||
f67539c2 | 194 | void test_rat_1(const boost::integral_constant<int, 1>&) |
7c673cae FG |
195 | { |
196 | } | |
197 | ||
198 | template <int N> | |
f67539c2 | 199 | void test_rat_1(const boost::integral_constant<int, N>&) |
7c673cae | 200 | { |
f67539c2 | 201 | test_rat_1(boost::integral_constant<int, N - 1>()); |
7c673cae FG |
202 | |
203 | double time = exec_timed_test([](const std::vector<double>& v) | |
204 | { | |
205 | double result = 0; | |
206 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 207 | result += boost::math::tools::detail::evaluate_rational_c_imp_1(num, denom, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
208 | return result; |
209 | }); | |
210 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Double Coefficients)"); | |
211 | ||
212 | time = exec_timed_test([](const std::vector<double>& v) | |
213 | { | |
214 | double result = 0; | |
215 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 216 | result += boost::math::tools::detail::evaluate_rational_c_imp_1(num, denom_int, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
217 | return result; |
218 | }); | |
219 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 1[br](Integer Coefficients)"); | |
220 | } | |
221 | ||
f67539c2 | 222 | void test_rat_2(const boost::integral_constant<int, 1>&) |
7c673cae FG |
223 | { |
224 | } | |
225 | ||
226 | template <int N> | |
f67539c2 | 227 | void test_rat_2(const boost::integral_constant<int, N>&) |
7c673cae | 228 | { |
f67539c2 | 229 | test_rat_2(boost::integral_constant<int, N - 1>()); |
7c673cae FG |
230 | |
231 | double time = exec_timed_test([](const std::vector<double>& v) | |
232 | { | |
233 | double result = 0; | |
234 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 235 | result += boost::math::tools::detail::evaluate_rational_c_imp_2(num, denom, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
236 | return result; |
237 | }); | |
238 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Double Coefficients)"); | |
239 | ||
240 | time = exec_timed_test([](const std::vector<double>& v) | |
241 | { | |
242 | double result = 0; | |
243 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 244 | result += boost::math::tools::detail::evaluate_rational_c_imp_2(num, denom_int, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
245 | return result; |
246 | }); | |
247 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 2[br](Integer Coefficients)"); | |
248 | } | |
249 | ||
f67539c2 | 250 | void test_rat_3(const boost::integral_constant<int, 1>&) |
7c673cae FG |
251 | { |
252 | } | |
253 | ||
254 | template <int N> | |
f67539c2 | 255 | void test_rat_3(const boost::integral_constant<int, N>&) |
7c673cae | 256 | { |
f67539c2 | 257 | test_rat_3(boost::integral_constant<int, N - 1>()); |
7c673cae FG |
258 | |
259 | double time = exec_timed_test([](const std::vector<double>& v) | |
260 | { | |
261 | double result = 0; | |
262 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 263 | result += boost::math::tools::detail::evaluate_rational_c_imp_3(num, denom, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
264 | return result; |
265 | }); | |
266 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Double Coefficients)"); | |
267 | ||
268 | time = exec_timed_test([](const std::vector<double>& v) | |
269 | { | |
270 | double result = 0; | |
271 | for (unsigned i = 0; i < 10; ++i) | |
f67539c2 | 272 | result += boost::math::tools::detail::evaluate_rational_c_imp_3(num, denom_int, v[0] + i, static_cast<boost::integral_constant<int, N>*>(0)); |
7c673cae FG |
273 | return result; |
274 | }); | |
275 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(N), "Method 3[br](Integer Coefficients)"); | |
276 | } | |
277 | ||
278 | template <class T, class U, class V> | |
279 | V evaluate_rational_0(const T* num, const U* denom, const V& z_, std::size_t count) | |
280 | { | |
281 | V z(z_); | |
282 | V s1, s2; | |
283 | if (z <= 1) | |
284 | { | |
285 | s1 = static_cast<V>(num[count - 1]); | |
286 | s2 = static_cast<V>(denom[count - 1]); | |
287 | for (int i = (int)count - 2; i >= 0; --i) | |
288 | { | |
289 | s1 *= z; | |
290 | s2 *= z; | |
291 | s1 += num[i]; | |
292 | s2 += denom[i]; | |
293 | } | |
294 | } | |
295 | else | |
296 | { | |
297 | z = 1 / z; | |
298 | s1 = static_cast<V>(num[0]); | |
299 | s2 = static_cast<V>(denom[0]); | |
300 | for (unsigned i = 1; i < count; ++i) | |
301 | { | |
302 | s1 *= z; | |
303 | s2 *= z; | |
304 | s1 += num[i]; | |
305 | s2 += denom[i]; | |
306 | } | |
307 | } | |
308 | return s1 / s2; | |
309 | } | |
310 | ||
311 | ||
312 | int main() | |
313 | { | |
314 | double val = 0.001; | |
315 | while (val < 1) | |
316 | { | |
317 | std::vector<double> v; | |
318 | v.push_back(val); | |
319 | data.push_back(v); | |
320 | val *= 1.1; | |
321 | } | |
322 | ||
323 | for (unsigned i = 3; i <= 20; ++i) | |
324 | { | |
325 | double time = exec_timed_test([&](const std::vector<double>& v) { | |
326 | double result = 0; | |
327 | for (unsigned j = 0; j < 10; ++j) | |
328 | result += evaluate_polynomial_0(denom, v[0] + j, i); | |
329 | return result; | |
330 | }); | |
331 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(i), "Method 0[br](Double Coefficients)"); | |
332 | ||
333 | time = exec_timed_test([&](const std::vector<double>& v) { | |
334 | double result = 0; | |
335 | for (unsigned j = 0; j < 10; ++j) | |
336 | result += evaluate_polynomial_0(denom_int, v[0] + j, i); | |
337 | return result; | |
338 | }); | |
339 | report_execution_time(time, std::string("Polynomial Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(i), "Method 0[br](Integer Coefficients)"); | |
340 | } | |
341 | ||
f67539c2 TL |
342 | test_poly_1(boost::integral_constant<int, 20>()); |
343 | test_poly_2(boost::integral_constant<int, 20>()); | |
344 | test_poly_3(boost::integral_constant<int, 20>()); | |
7c673cae FG |
345 | |
346 | for (unsigned i = 3; i <= 20; ++i) | |
347 | { | |
348 | double time = exec_timed_test([&](const std::vector<double>& v) { | |
349 | double result = 0; | |
350 | for (unsigned j = 0; j < 10; ++j) | |
351 | result += evaluate_rational_0(num, denom, v[0] + j, i); | |
352 | return result; | |
353 | }); | |
354 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(i), "Method 0[br](Double Coefficients)"); | |
355 | ||
356 | time = exec_timed_test([&](const std::vector<double>& v) { | |
357 | double result = 0; | |
358 | for (unsigned j = 0; j < 10; ++j) | |
359 | result += evaluate_rational_0(num, denom_int, v[0] + j, i); | |
360 | return result; | |
361 | }); | |
362 | report_execution_time(time, std::string("Rational Method Comparison with ") + compiler_name() + std::string(" on ") + platform_name(), "Order " + make_order_string(i), "Method 0[br](Integer Coefficients)"); | |
363 | } | |
364 | ||
f67539c2 TL |
365 | test_rat_1(boost::integral_constant<int, 20>()); |
366 | test_rat_2(boost::integral_constant<int, 20>()); | |
367 | test_rat_3(boost::integral_constant<int, 20>()); | |
7c673cae FG |
368 | |
369 | return 0; | |
370 | } | |
371 |