test_poly_method.cpp 14 KB

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