generate_rational_code.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. // (C) Copyright John Maddock 2007.
  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. #include <iostream>
  6. #include <iomanip>
  7. #include <fstream>
  8. #include <string>
  9. #include <sstream>
  10. int max_order = 20;
  11. const char* path_prefix = "..\\..\\..\\boost\\math\\tools\\detail\\polynomial_";
  12. const char* path_prefix2 = "..\\..\\..\\boost\\math\\tools\\detail\\rational_";
  13. const char* copyright_string =
  14. "// (C) Copyright John Maddock 2007.\n"
  15. "// Use, modification and distribution are subject to the\n"
  16. "// Boost Software License, Version 1.0. (See accompanying file\n"
  17. "// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n"
  18. "//\n"
  19. "// This file is machine generated, do not edit by hand\n\n";
  20. void print_polynomials(int max_order)
  21. {
  22. for(int i = 2; i <= max_order; ++i)
  23. {
  24. std::stringstream filename;
  25. filename << path_prefix << "horner1_" << i << ".hpp";
  26. std::ofstream ofs(filename.str().c_str());
  27. if(ofs.bad())
  28. break;
  29. //
  30. // Output the boilerplate at the top of the header:
  31. //
  32. ofs << copyright_string <<
  33. "// Polynomial evaluation using Horners rule\n"
  34. "#ifndef BOOST_MATH_TOOLS_POLY_EVAL_" << i << "_HPP\n"
  35. "#define BOOST_MATH_TOOLS_POLY_EVAL_" << i << "_HPP\n\n"
  36. "namespace boost{ namespace math{ namespace tools{ namespace detail{\n\n"
  37. "template <class T, class V>\n"
  38. "inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*)\n"
  39. "{\n"
  40. " return static_cast<V>(0);\n"
  41. "}\n"
  42. "\n"
  43. "template <class T, class V>\n"
  44. "inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*)\n"
  45. "{\n"
  46. " return static_cast<V>(a[0]);\n"
  47. "}\n\n";
  48. for(int order = 2; order <= i; ++order)
  49. {
  50. ofs <<
  51. "template <class T, class V>\n"
  52. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<" << order << ">*)\n"
  53. "{\n"
  54. " return static_cast<V>(";
  55. for(int bracket = 2; bracket < order; ++bracket)
  56. ofs << "(";
  57. ofs << "a[" << order - 1 << "] * x + a[" << order - 2 << "]" ;
  58. for(int item = order - 3; item >= 0; --item)
  59. {
  60. ofs << ") * x + a[" << item << "]";
  61. }
  62. ofs << ");\n"
  63. "}\n\n";
  64. }
  65. //
  66. // And finally the boilerplate at the end of the header:
  67. //
  68. ofs << "\n}}}} // namespaces\n\n#endif // include guard\n\n";
  69. filename.str("");
  70. filename << path_prefix << "horner2_" << i << ".hpp";
  71. ofs.close();
  72. ofs.open(filename.str().c_str());
  73. if(ofs.bad())
  74. break;
  75. //
  76. // Output the boilerplate at the top of the header:
  77. //
  78. ofs << copyright_string <<
  79. "// Polynomial evaluation using second order Horners rule\n"
  80. "#ifndef BOOST_MATH_TOOLS_POLY_EVAL_" << i << "_HPP\n"
  81. "#define BOOST_MATH_TOOLS_POLY_EVAL_" << i << "_HPP\n\n"
  82. "namespace boost{ namespace math{ namespace tools{ namespace detail{\n\n"
  83. "template <class T, class V>\n"
  84. "inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*)\n"
  85. "{\n"
  86. " return static_cast<V>(0);\n"
  87. "}\n"
  88. "\n"
  89. "template <class T, class V>\n"
  90. "inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*)\n"
  91. "{\n"
  92. " return static_cast<V>(a[0]);\n"
  93. "}\n\n"
  94. "template <class T, class V>\n"
  95. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<2>*)\n"
  96. "{\n"
  97. " return static_cast<V>(a[1] * x + a[0]);\n"
  98. "}\n\n"
  99. "template <class T, class V>\n"
  100. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<3>*)\n"
  101. "{\n"
  102. " return static_cast<V>((a[2] * x + a[1]) * x + a[0]);\n"
  103. "}\n\n"
  104. "template <class T, class V>\n"
  105. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<4>*)\n"
  106. "{\n"
  107. " return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);\n"
  108. "}\n\n";
  109. for(int order = 5; order <= i; ++order)
  110. {
  111. ofs <<
  112. "template <class T, class V>\n"
  113. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<" << order << ">*)\n"
  114. "{\n"
  115. " V x2 = x * x;\n"
  116. " return static_cast<V>(";
  117. if(order & 1)
  118. {
  119. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  120. ofs << "(";
  121. ofs << "a[" << order - 1 << "] * x2 + a[" << order - 3 << "]" ;
  122. for(int item = order - 5; item >= 0; item -= 2)
  123. {
  124. ofs << ") * x2 + a[" << item << "]";
  125. }
  126. ofs << " + ";
  127. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  128. ofs << "(";
  129. ofs << "a[" << order - 2 << "] * x2 + a[" << order - 4 << "]" ;
  130. for(int item = order - 6; item >= 0; item -= 2)
  131. {
  132. ofs << ") * x2 + a[" << item << "]";
  133. }
  134. ofs << ") * x";
  135. }
  136. else
  137. {
  138. for(int bracket = 0; bracket < (order - 1) / 2; ++bracket)
  139. ofs << "(";
  140. ofs << "a[" << order - 1 << "] * x2 + a[" << order - 3 << "]" ;
  141. for(int item = order - 5; item >= 0; item -= 2)
  142. {
  143. ofs << ") * x2 + a[" << item << "]";
  144. }
  145. ofs << ") * x + ";
  146. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  147. ofs << "(";
  148. ofs << "a[" << order - 2 << "] * x2 + a[" << order - 4 << "]" ;
  149. for(int item = order - 6; item >= 0; item -= 2)
  150. {
  151. ofs << ") * x2 + a[" << item << "]";
  152. }
  153. }
  154. ofs << ");\n"
  155. "}\n\n";
  156. }
  157. //
  158. // And finally the boilerplate at the end of the header:
  159. //
  160. ofs << "\n}}}} // namespaces\n\n#endif // include guard\n\n";
  161. filename.str("");
  162. filename << path_prefix << "horner3_" << i << ".hpp";
  163. ofs.close();
  164. ofs.open(filename.str().c_str());
  165. if(ofs.bad())
  166. break;
  167. //
  168. // Output the boilerplate at the top of the header:
  169. //
  170. ofs << copyright_string <<
  171. "// Unrolled polynomial evaluation using second order Horners rule\n"
  172. "#ifndef BOOST_MATH_TOOLS_POLY_EVAL_" << i << "_HPP\n"
  173. "#define BOOST_MATH_TOOLS_POLY_EVAL_" << i << "_HPP\n\n"
  174. "namespace boost{ namespace math{ namespace tools{ namespace detail{\n\n"
  175. "template <class T, class V>\n"
  176. "inline V evaluate_polynomial_c_imp(const T*, const V&, const mpl::int_<0>*)\n"
  177. "{\n"
  178. " return static_cast<V>(0);\n"
  179. "}\n"
  180. "\n"
  181. "template <class T, class V>\n"
  182. "inline V evaluate_polynomial_c_imp(const T* a, const V&, const mpl::int_<1>*)\n"
  183. "{\n"
  184. " return static_cast<V>(a[0]);\n"
  185. "}\n\n"
  186. "template <class T, class V>\n"
  187. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<2>*)\n"
  188. "{\n"
  189. " return static_cast<V>(a[1] * x + a[0]);\n"
  190. "}\n\n"
  191. "template <class T, class V>\n"
  192. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<3>*)\n"
  193. "{\n"
  194. " return static_cast<V>((a[2] * x + a[1]) * x + a[0]);\n"
  195. "}\n\n"
  196. "template <class T, class V>\n"
  197. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<4>*)\n"
  198. "{\n"
  199. " return static_cast<V>(((a[3] * x + a[2]) * x + a[1]) * x + a[0]);\n"
  200. "}\n\n";
  201. for(int order = 5; order <= i; ++order)
  202. {
  203. ofs <<
  204. "template <class T, class V>\n"
  205. "inline V evaluate_polynomial_c_imp(const T* a, const V& x, const mpl::int_<" << order << ">*)\n"
  206. "{\n"
  207. " V x2 = x * x;\n"
  208. " V t[2];\n";
  209. if(order & 1)
  210. {
  211. ofs << " t[0] = static_cast<V>(a[" << order - 1 << "] * x2 + a[" << order - 3 << "]);\n" ;
  212. ofs << " t[1] = static_cast<V>(a[" << order - 2 << "] * x2 + a[" << order - 4 << "]);\n" ;
  213. for(int item = order - 5; item >= 0; item -= 2)
  214. {
  215. ofs << " t[0] *= x2;\n";
  216. if(item - 1 >= 0)
  217. ofs << " t[1] *= x2;\n";
  218. ofs << " t[0] += static_cast<V>(a[" << item << "]);\n";
  219. if(item - 1 >= 0)
  220. ofs << " t[1] += static_cast<V>(a[" << item - 1 << "]);\n";
  221. }
  222. ofs <<
  223. " t[1] *= x;\n"
  224. " return t[0] + t[1];\n";
  225. }
  226. else
  227. {
  228. ofs << " t[0] = a[" << order - 1 << "] * x2 + a[" << order - 3 << "];\n" ;
  229. ofs << " t[1] = a[" << order - 2 << "] * x2 + a[" << order - 4 << "];\n" ;
  230. for(int item = order - 5; item >= 0; item -= 2)
  231. {
  232. ofs << " t[0] *= x2;\n";
  233. if(item - 1 >= 0)
  234. ofs << " t[1] *= x2;\n";
  235. ofs << " t[0] += static_cast<V>(a[" << item << "]);\n";
  236. if(item - 1 >= 0)
  237. ofs << " t[1] += static_cast<V>(a[" << item - 1 << "]);\n";
  238. }
  239. ofs << " t[0] *= x;\n";
  240. ofs << " return t[0] + t[1];\n";
  241. }
  242. ofs << "}\n\n";
  243. }
  244. //
  245. // And finally the boilerplate at the end of the header:
  246. //
  247. ofs << "\n}}}} // namespaces\n\n#endif // include guard\n\n";
  248. }
  249. }
  250. void print_rationals(int max_order)
  251. {
  252. for(int i = 2; i <= max_order; ++i)
  253. {
  254. std::stringstream filename;
  255. filename << path_prefix2 << "horner1_" << i << ".hpp";
  256. std::ofstream ofs(filename.str().c_str());
  257. if(ofs.bad())
  258. break;
  259. //
  260. // Output the boilerplate at the top of the header:
  261. //
  262. ofs << copyright_string <<
  263. "// Polynomial evaluation using Horners rule\n"
  264. "#ifndef BOOST_MATH_TOOLS_POLY_RAT_" << i << "_HPP\n"
  265. "#define BOOST_MATH_TOOLS_POLY_RAT_" << i << "_HPP\n\n"
  266. "namespace boost{ namespace math{ namespace tools{ namespace detail{\n\n"
  267. "template <class T, class U, class V>\n"
  268. "inline V evaluate_rational_c_imp(const T*, const U*, const V&, const mpl::int_<0>*)\n"
  269. "{\n"
  270. " return static_cast<V>(0);\n"
  271. "}\n"
  272. "\n"
  273. "template <class T, class U, class V>\n"
  274. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const mpl::int_<1>*)\n"
  275. "{\n"
  276. " return static_cast<V>(a[0]) / static_cast<V>(b[0]);\n"
  277. "}\n\n";
  278. for(int order = 2; order <= i; ++order)
  279. {
  280. ofs <<
  281. "template <class T, class U, class V>\n"
  282. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<" << order << ">*)\n"
  283. "{\n"
  284. " if(x <= 1)\n"
  285. " return static_cast<V>((";
  286. for(int bracket = 2; bracket < order; ++bracket)
  287. ofs << "(";
  288. ofs << "a[" << order - 1 << "] * x + a[" << order - 2 << "]" ;
  289. for(int item = order - 3; item >= 0; --item)
  290. {
  291. ofs << ") * x + a[" << item << "]";
  292. }
  293. ofs << ") / (";
  294. for(int bracket = 2; bracket < order; ++bracket)
  295. ofs << "(";
  296. ofs << "b[" << order - 1 << "] * x + b[" << order - 2 << "]" ;
  297. for(int item = order - 3; item >= 0; --item)
  298. {
  299. ofs << ") * x + b[" << item << "]";
  300. }
  301. ofs << "));\n else\n {\n V z = 1 / x;\n return static_cast<V>((";
  302. for(int bracket = order - 1; bracket > 1; --bracket)
  303. ofs << "(";
  304. ofs << "a[" << 0 << "] * z + a[" << 1 << "]" ;
  305. for(int item = 2; item <= order - 1; ++item)
  306. {
  307. ofs << ") * z + a[" << item << "]";
  308. }
  309. ofs << ") / (";
  310. for(int bracket = 2; bracket < order; ++bracket)
  311. ofs << "(";
  312. ofs << "b[" << 0 << "] * z + b[" << 1 << "]" ;
  313. for(int item = 2; item <= order - 1; ++item)
  314. {
  315. ofs << ") * z + b[" << item << "]";
  316. }
  317. ofs << "));\n }\n";
  318. ofs << "}\n\n";
  319. }
  320. //
  321. // And finally the boilerplate at the end of the header:
  322. //
  323. ofs << "\n}}}} // namespaces\n\n#endif // include guard\n\n";
  324. filename.str("");
  325. filename << path_prefix2 << "horner2_" << i << ".hpp";
  326. ofs.close();
  327. ofs.open(filename.str().c_str());
  328. if(ofs.bad())
  329. break;
  330. //
  331. // Output the boilerplate at the top of the header:
  332. //
  333. ofs << copyright_string <<
  334. "// Polynomial evaluation using second order Horners rule\n"
  335. "#ifndef BOOST_MATH_TOOLS_RAT_EVAL_" << i << "_HPP\n"
  336. "#define BOOST_MATH_TOOLS_RAT_EVAL_" << i << "_HPP\n\n"
  337. "namespace boost{ namespace math{ namespace tools{ namespace detail{\n\n"
  338. "template <class T, class U, class V>\n"
  339. "inline V evaluate_rational_c_imp(const T*, const U*, const V&, const mpl::int_<0>*)\n"
  340. "{\n"
  341. " return static_cast<V>(0);\n"
  342. "}\n"
  343. "\n"
  344. "template <class T, class U, class V>\n"
  345. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const mpl::int_<1>*)\n"
  346. "{\n"
  347. " return static_cast<V>(a[0]) / static_cast<V>(b[0]);\n"
  348. "}\n\n"
  349. "template <class T, class U, class V>\n"
  350. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<2>*)\n"
  351. "{\n"
  352. " return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));\n"
  353. "}\n\n"
  354. "template <class T, class U, class V>\n"
  355. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<3>*)\n"
  356. "{\n"
  357. " return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));\n"
  358. "}\n\n"
  359. "template <class T, class U, class V>\n"
  360. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<4>*)\n"
  361. "{\n"
  362. " return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));\n"
  363. "}\n\n";
  364. for(int order = 5; order <= i; ++order)
  365. {
  366. ofs <<
  367. "template <class T, class U, class V>\n"
  368. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<" << order << ">*)\n"
  369. "{\n"
  370. " if(x <= 1)\n {\n"
  371. " V x2 = x * x;\n"
  372. " return static_cast<V>((";
  373. if(order & 1)
  374. {
  375. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  376. ofs << "(";
  377. ofs << "a[" << order - 1 << "] * x2 + a[" << order - 3 << "]" ;
  378. for(int item = order - 5; item >= 0; item -= 2)
  379. {
  380. ofs << ") * x2 + a[" << item << "]";
  381. }
  382. ofs << " + ";
  383. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  384. ofs << "(";
  385. ofs << "a[" << order - 2 << "] * x2 + a[" << order - 4 << "]" ;
  386. for(int item = order - 6; item >= 0; item -= 2)
  387. {
  388. ofs << ") * x2 + a[" << item << "]";
  389. }
  390. ofs << ") * x";
  391. }
  392. else
  393. {
  394. for(int bracket = 0; bracket < (order - 1) / 2; ++bracket)
  395. ofs << "(";
  396. ofs << "a[" << order - 1 << "] * x2 + a[" << order - 3 << "]" ;
  397. for(int item = order - 5; item >= 0; item -= 2)
  398. {
  399. ofs << ") * x2 + a[" << item << "]";
  400. }
  401. ofs << ") * x + ";
  402. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  403. ofs << "(";
  404. ofs << "a[" << order - 2 << "] * x2 + a[" << order - 4 << "]" ;
  405. for(int item = order - 6; item >= 0; item -= 2)
  406. {
  407. ofs << ") * x2 + a[" << item << "]";
  408. }
  409. }
  410. ofs << ") / (";
  411. if(order & 1)
  412. {
  413. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  414. ofs << "(";
  415. ofs << "b[" << order - 1 << "] * x2 + b[" << order - 3 << "]" ;
  416. for(int item = order - 5; item >= 0; item -= 2)
  417. {
  418. ofs << ") * x2 + b[" << item << "]";
  419. }
  420. ofs << " + ";
  421. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  422. ofs << "(";
  423. ofs << "b[" << order - 2 << "] * x2 + b[" << order - 4 << "]" ;
  424. for(int item = order - 6; item >= 0; item -= 2)
  425. {
  426. ofs << ") * x2 + b[" << item << "]";
  427. }
  428. ofs << ") * x";
  429. }
  430. else
  431. {
  432. for(int bracket = 0; bracket < (order - 1) / 2; ++bracket)
  433. ofs << "(";
  434. ofs << "b[" << order - 1 << "] * x2 + b[" << order - 3 << "]" ;
  435. for(int item = order - 5; item >= 0; item -= 2)
  436. {
  437. ofs << ") * x2 + b[" << item << "]";
  438. }
  439. ofs << ") * x + ";
  440. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  441. ofs << "(";
  442. ofs << "b[" << order - 2 << "] * x2 + b[" << order - 4 << "]" ;
  443. for(int item = order - 6; item >= 0; item -= 2)
  444. {
  445. ofs << ") * x2 + b[" << item << "]";
  446. }
  447. }
  448. ofs << "));\n }\n else\n {\n V z = 1 / x;\n V z2 = 1 / (x * x);\n return static_cast<V>((";
  449. if(order & 1)
  450. {
  451. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  452. ofs << "(";
  453. ofs << "a[" << 0 << "] * z2 + a[" << 2 << "]" ;
  454. for(int item = 4; item < order; item += 2)
  455. {
  456. ofs << ") * z2 + a[" << item << "]";
  457. }
  458. ofs << " + ";
  459. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  460. ofs << "(";
  461. ofs << "a[" << 1 << "] * z2 + a[" << 3 << "]" ;
  462. for(int item = 5; item < order; item += 2)
  463. {
  464. ofs << ") * z2 + a[" << item << "]";
  465. }
  466. ofs << ") * z";
  467. }
  468. else
  469. {
  470. for(int bracket = 0; bracket < (order - 1) / 2; ++bracket)
  471. ofs << "(";
  472. ofs << "a[" << 0 << "] * z2 + a[" << 2 << "]" ;
  473. for(int item = 4; item < order; item += 2)
  474. {
  475. ofs << ") * z2 + a[" << item << "]";
  476. }
  477. ofs << ") * z + ";
  478. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  479. ofs << "(";
  480. ofs << "a[" << 1 << "] * z2 + a[" << 3 << "]" ;
  481. for(int item = 5; item < order; item += 2)
  482. {
  483. ofs << ") * z2 + a[" << item << "]";
  484. }
  485. }
  486. ofs << ") / (";
  487. if(order & 1)
  488. {
  489. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  490. ofs << "(";
  491. ofs << "b[" << 0 << "] * z2 + b[" << 2 << "]" ;
  492. for(int item = 4; item < order; item += 2)
  493. {
  494. ofs << ") * z2 + b[" << item << "]";
  495. }
  496. ofs << " + ";
  497. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  498. ofs << "(";
  499. ofs << "b[" << 1 << "] * z2 + b[" << 3 << "]" ;
  500. for(int item = 5; item < order; item += 2)
  501. {
  502. ofs << ") * z2 + b[" << item << "]";
  503. }
  504. ofs << ") * z";
  505. }
  506. else
  507. {
  508. for(int bracket = 0; bracket < (order - 1) / 2; ++bracket)
  509. ofs << "(";
  510. ofs << "b[" << 0 << "] * z2 + b[" << 2 << "]" ;
  511. for(int item = 4; item < order; item += 2)
  512. {
  513. ofs << ") * z2 + b[" << item << "]";
  514. }
  515. ofs << ") * z + ";
  516. for(int bracket = 0; bracket < (order - 1) / 2 - 1; ++bracket)
  517. ofs << "(";
  518. ofs << "b[" << 1 << "] * z2 + b[" << 3 << "]" ;
  519. for(int item = 5; item < order; item += 2)
  520. {
  521. ofs << ") * z2 + b[" << item << "]";
  522. }
  523. }
  524. ofs << "));\n }\n";
  525. ofs << "}\n\n";
  526. }
  527. //
  528. // And finally the boilerplate at the end of the header:
  529. //
  530. ofs << "\n}}}} // namespaces\n\n#endif // include guard\n\n";
  531. filename.str("");
  532. filename << path_prefix2 << "horner3_" << i << ".hpp";
  533. ofs.close();
  534. ofs.open(filename.str().c_str());
  535. if(ofs.bad())
  536. break;
  537. //
  538. // Output the boilerplate at the top of the header:
  539. //
  540. ofs << copyright_string <<
  541. "// Polynomial evaluation using second order Horners rule\n"
  542. "#ifndef BOOST_MATH_TOOLS_RAT_EVAL_" << i << "_HPP\n"
  543. "#define BOOST_MATH_TOOLS_RAT_EVAL_" << i << "_HPP\n\n"
  544. "namespace boost{ namespace math{ namespace tools{ namespace detail{\n\n"
  545. "template <class T, class U, class V>\n"
  546. "inline V evaluate_rational_c_imp(const T*, const U*, const V&, const mpl::int_<0>*)\n"
  547. "{\n"
  548. " return static_cast<V>(0);\n"
  549. "}\n"
  550. "\n"
  551. "template <class T, class U, class V>\n"
  552. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V&, const mpl::int_<1>*)\n"
  553. "{\n"
  554. " return static_cast<V>(a[0]) / static_cast<V>(b[0]);\n"
  555. "}\n\n"
  556. "template <class T, class U, class V>\n"
  557. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<2>*)\n"
  558. "{\n"
  559. " return static_cast<V>((a[1] * x + a[0]) / (b[1] * x + b[0]));\n"
  560. "}\n\n"
  561. "template <class T, class U, class V>\n"
  562. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<3>*)\n"
  563. "{\n"
  564. " return static_cast<V>(((a[2] * x + a[1]) * x + a[0]) / ((b[2] * x + b[1]) * x + b[0]));\n"
  565. "}\n\n"
  566. "template <class T, class U, class V>\n"
  567. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<4>*)\n"
  568. "{\n"
  569. " return static_cast<V>((((a[3] * x + a[2]) * x + a[1]) * x + a[0]) / (((b[3] * x + b[2]) * x + b[1]) * x + b[0]));\n"
  570. "}\n\n";
  571. for(int order = 5; order <= i; ++order)
  572. {
  573. ofs <<
  574. "template <class T, class U, class V>\n"
  575. "inline V evaluate_rational_c_imp(const T* a, const U* b, const V& x, const mpl::int_<" << order << ">*)\n"
  576. "{\n"
  577. " if(x <= 1)\n {\n"
  578. " V x2 = x * x;\n"
  579. " V t[4];\n";
  580. if(order & 1)
  581. {
  582. ofs << " t[0] = a[" << order - 1 << "] * x2 + a[" << order - 3 << "];\n" ;
  583. ofs << " t[1] = a[" << order - 2 << "] * x2 + a[" << order - 4 << "];\n" ;
  584. ofs << " t[2] = b[" << order - 1 << "] * x2 + b[" << order - 3 << "];\n" ;
  585. ofs << " t[3] = b[" << order - 2 << "] * x2 + b[" << order - 4 << "];\n" ;
  586. for(int item = order - 5; item >= 0; item -= 2)
  587. {
  588. ofs << " t[0] *= x2;\n";
  589. if(item - 1 >= 0)
  590. ofs << " t[1] *= x2;\n";
  591. ofs << " t[2] *= x2;\n";
  592. if(item - 1 >= 0)
  593. ofs << " t[3] *= x2;\n";
  594. ofs << " t[0] += static_cast<V>(a[" << item << "]);\n";
  595. if(item - 1 >= 0)
  596. ofs << " t[1] += static_cast<V>(a[" << item - 1 << "]);\n";
  597. ofs << " t[2] += static_cast<V>(b[" << item << "]);\n";
  598. if(item - 1 >= 0)
  599. ofs << " t[3] += static_cast<V>(b[" << item - 1 << "]);\n";
  600. }
  601. ofs << " t[1] *= x;\n";
  602. ofs << " t[3] *= x;\n";
  603. }
  604. else
  605. {
  606. ofs << " t[0] = a[" << order - 1 << "] * x2 + a[" << order - 3 << "];\n" ;
  607. ofs << " t[1] = a[" << order - 2 << "] * x2 + a[" << order - 4 << "];\n" ;
  608. ofs << " t[2] = b[" << order - 1 << "] * x2 + b[" << order - 3 << "];\n" ;
  609. ofs << " t[3] = b[" << order - 2 << "] * x2 + b[" << order - 4 << "];\n" ;
  610. for(int item = order - 5; item >= 0; item -= 2)
  611. {
  612. ofs << " t[0] *= x2;\n";
  613. if(item - 1 >= 0)
  614. ofs << " t[1] *= x2;\n";
  615. ofs << " t[2] *= x2;\n";
  616. if(item - 1 >= 0)
  617. ofs << " t[3] *= x2;\n";
  618. ofs << " t[0] += static_cast<V>(a[" << item << "]);\n";
  619. if(item - 1 >= 0)
  620. ofs << " t[1] += static_cast<V>(a[" << item - 1 << "]);\n";
  621. ofs << " t[2] += static_cast<V>(b[" << item << "]);\n";
  622. if(item - 1 >= 0)
  623. ofs << " t[3] += static_cast<V>(b[" << item - 1 << "]);\n";
  624. }
  625. ofs << " t[0] *= x;\n";
  626. ofs << " t[2] *= x;\n";
  627. }
  628. ofs << " return (t[0] + t[1]) / (t[2] + t[3]);\n";
  629. ofs << " }\n else\n {\n V z = 1 / x;\n V z2 = 1 / (x * x);\n V t[4];\n";
  630. if(order & 1)
  631. {
  632. ofs << " t[0] = a[" << 0 << "] * z2 + a[" << 2 << "];\n" ;
  633. ofs << " t[1] = a[" << 1 << "] * z2 + a[" << 3 << "];\n" ;
  634. ofs << " t[2] = b[" << 0 << "] * z2 + b[" << 2 << "];\n" ;
  635. ofs << " t[3] = b[" << 1 << "] * z2 + b[" << 3 << "];\n" ;
  636. for(int item = 4; item < order; item += 2)
  637. {
  638. ofs << " t[0] *= z2;\n";
  639. if(item + 1 < order)
  640. ofs << " t[1] *= z2;\n";
  641. ofs << " t[2] *= z2;\n";
  642. if(item + 1 < order)
  643. ofs << " t[3] *= z2;\n";
  644. ofs << " t[0] += static_cast<V>(a[" << item << "]);\n";
  645. if(item + 1 < order)
  646. ofs << " t[1] += static_cast<V>(a[" << item + 1 << "]);\n";
  647. ofs << " t[2] += static_cast<V>(b[" << item << "]);\n";
  648. if(item + 1 < order)
  649. ofs << " t[3] += static_cast<V>(b[" << item + 1 << "]);\n";
  650. }
  651. ofs << " t[1] *= z;\n";
  652. ofs << " t[3] *= z;\n";
  653. }
  654. else
  655. {
  656. ofs << " t[0] = a[" << 0 << "] * z2 + a[" << 2 << "];\n" ;
  657. ofs << " t[1] = a[" << 1 << "] * z2 + a[" << 3 << "];\n" ;
  658. ofs << " t[2] = b[" << 0 << "] * z2 + b[" << 2 << "];\n" ;
  659. ofs << " t[3] = b[" << 1 << "] * z2 + b[" << 3 << "];\n" ;
  660. for(int item = 4; item < order; item += 2)
  661. {
  662. ofs << " t[0] *= z2;\n";
  663. if(item + 1 < order)
  664. ofs << " t[1] *= z2;\n";
  665. ofs << " t[2] *= z2;\n";
  666. if(item + 1 < order)
  667. ofs << " t[3] *= z2;\n";
  668. ofs << " t[0] += static_cast<V>(a[" << item << "]);\n";
  669. if(item + 1 < order)
  670. ofs << " t[1] += static_cast<V>(a[" << item + 1 << "]);\n";
  671. ofs << " t[2] += static_cast<V>(b[" << item << "]);\n";
  672. if(item + 1 < order)
  673. ofs << " t[3] += static_cast<V>(b[" << item + 1 << "]);\n";
  674. }
  675. ofs << " t[0] *= z;\n";
  676. ofs << " t[2] *= z;\n";
  677. }
  678. ofs << " return (t[0] + t[1]) / (t[2] + t[3]);\n }\n";
  679. ofs << "}\n\n";
  680. }
  681. //
  682. // And finally the boilerplate at the end of the header:
  683. //
  684. ofs << "\n}}}} // namespaces\n\n#endif // include guard\n\n";
  685. }
  686. }
  687. int main()
  688. {
  689. for(int i = 2; i <= max_order; ++i)
  690. {
  691. print_polynomials(i);
  692. print_rationals(i);
  693. }
  694. return 0;
  695. }