root_finding_start_locations.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. // Copyright John Maddock 2015
  2. // Use, modification and distribution are subject to the
  3. // Boost Software License, Version 1.0.
  4. // (See accompanying file LICENSE_1_0.txt
  5. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. // Comparison of finding roots using TOMS748, Newton-Raphson, Halley & Schroder algorithms.
  7. // Note that this file contains Quickbook mark-up as well as code
  8. // and comments, don't change any of the special comment mark-ups!
  9. // This program also writes files in Quickbook tables mark-up format.
  10. #include <boost/cstdlib.hpp>
  11. #include <boost/config.hpp>
  12. #include <boost/array.hpp>
  13. #include <boost/math/tools/roots.hpp>
  14. #include <boost/math/special_functions/ellint_1.hpp>
  15. #include <boost/math/special_functions/ellint_2.hpp>
  16. template <class T>
  17. struct cbrt_functor_noderiv
  18. {
  19. // cube root of x using only function - no derivatives.
  20. cbrt_functor_noderiv(T const& to_find_root_of) : a(to_find_root_of)
  21. { /* Constructor just stores value a to find root of. */
  22. }
  23. T operator()(T const& x)
  24. {
  25. T fx = x*x*x - a; // Difference (estimate x^3 - a).
  26. return fx;
  27. }
  28. private:
  29. T a; // to be 'cube_rooted'.
  30. };
  31. //] [/root_finding_noderiv_1
  32. template <class T>
  33. boost::uintmax_t cbrt_noderiv(T x, T guess)
  34. {
  35. // return cube root of x using bracket_and_solve (no derivatives).
  36. using namespace std; // Help ADL of std functions.
  37. using namespace boost::math::tools; // For bracket_and_solve_root.
  38. T factor = 2; // How big steps to take when searching.
  39. const boost::uintmax_t maxit = 20; // Limit to maximum iterations.
  40. boost::uintmax_t it = maxit; // Initally our chosen max iterations, but updated with actual.
  41. bool is_rising = true; // So if result if guess^3 is too low, then try increasing guess.
  42. int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
  43. // Some fraction of digits is used to control how accurate to try to make the result.
  44. int get_digits = digits - 3; // We have to have a non-zero interval at each step, so
  45. // maximum accuracy is digits - 1. But we also have to
  46. // allow for inaccuracy in f(x), otherwise the last few
  47. // iterations just thrash around.
  48. eps_tolerance<T> tol(get_digits); // Set the tolerance.
  49. bracket_and_solve_root(cbrt_functor_noderiv<T>(x), guess, factor, is_rising, tol, it);
  50. return it;
  51. }
  52. template <class T>
  53. struct cbrt_functor_deriv
  54. { // Functor also returning 1st derivative.
  55. cbrt_functor_deriv(T const& to_find_root_of) : a(to_find_root_of)
  56. { // Constructor stores value a to find root of,
  57. // for example: calling cbrt_functor_deriv<T>(a) to use to get cube root of a.
  58. }
  59. std::pair<T, T> operator()(T const& x)
  60. {
  61. // Return both f(x) and f'(x).
  62. T fx = x*x*x - a; // Difference (estimate x^3 - value).
  63. T dx = 3 * x*x; // 1st derivative = 3x^2.
  64. return std::make_pair(fx, dx); // 'return' both fx and dx.
  65. }
  66. private:
  67. T a; // Store value to be 'cube_rooted'.
  68. };
  69. template <class T>
  70. boost::uintmax_t cbrt_deriv(T x, T guess)
  71. {
  72. // return cube root of x using 1st derivative and Newton_Raphson.
  73. using namespace boost::math::tools;
  74. T min = guess / 100; // We don't really know what this should be!
  75. T max = guess * 100; // We don't really know what this should be!
  76. const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
  77. int get_digits = static_cast<int>(digits * 0.6); // Accuracy doubles with each step, so stop when we have
  78. // just over half the digits correct.
  79. const boost::uintmax_t maxit = 20;
  80. boost::uintmax_t it = maxit;
  81. newton_raphson_iterate(cbrt_functor_deriv<T>(x), guess, min, max, get_digits, it);
  82. return it;
  83. }
  84. template <class T>
  85. struct cbrt_functor_2deriv
  86. {
  87. // Functor returning both 1st and 2nd derivatives.
  88. cbrt_functor_2deriv(T const& to_find_root_of) : a(to_find_root_of)
  89. { // Constructor stores value a to find root of, for example:
  90. // calling cbrt_functor_2deriv<T>(x) to get cube root of x,
  91. }
  92. std::tuple<T, T, T> operator()(T const& x)
  93. {
  94. // Return both f(x) and f'(x) and f''(x).
  95. T fx = x*x*x - a; // Difference (estimate x^3 - value).
  96. T dx = 3 * x*x; // 1st derivative = 3x^2.
  97. T d2x = 6 * x; // 2nd derivative = 6x.
  98. return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
  99. }
  100. private:
  101. T a; // to be 'cube_rooted'.
  102. };
  103. template <class T>
  104. boost::uintmax_t cbrt_2deriv(T x, T guess)
  105. {
  106. // return cube root of x using 1st and 2nd derivatives and Halley.
  107. //using namespace std; // Help ADL of std functions.
  108. using namespace boost::math::tools;
  109. T min = guess / 100; // We don't really know what this should be!
  110. T max = guess * 100; // We don't really know what this should be!
  111. const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
  112. // digits used to control how accurate to try to make the result.
  113. int get_digits = static_cast<int>(digits * 0.4); // Accuracy triples with each step, so stop when just
  114. // over one third of the digits are correct.
  115. boost::uintmax_t maxit = 20;
  116. halley_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, maxit);
  117. return maxit;
  118. }
  119. template <class T>
  120. boost::uintmax_t cbrt_2deriv_s(T x, T guess)
  121. {
  122. // return cube root of x using 1st and 2nd derivatives and Halley.
  123. //using namespace std; // Help ADL of std functions.
  124. using namespace boost::math::tools;
  125. T min = guess / 100; // We don't really know what this should be!
  126. T max = guess * 100; // We don't really know what this should be!
  127. const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
  128. // digits used to control how accurate to try to make the result.
  129. int get_digits = static_cast<int>(digits * 0.4); // Accuracy triples with each step, so stop when just
  130. // over one third of the digits are correct.
  131. boost::uintmax_t maxit = 20;
  132. schroder_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, maxit);
  133. return maxit;
  134. }
  135. template <typename T = double>
  136. struct elliptic_root_functor_noderiv
  137. {
  138. elliptic_root_functor_noderiv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius)
  139. { // Constructor just stores value a to find root of.
  140. }
  141. T operator()(T const& x)
  142. {
  143. // return the difference between required arc-length, and the calculated arc-length for an
  144. // ellipse with radii m_radius and x:
  145. T a = (std::max)(m_radius, x);
  146. T b = (std::min)(m_radius, x);
  147. T k = sqrt(1 - b * b / (a * a));
  148. return 4 * a * boost::math::ellint_2(k) - m_arc;
  149. }
  150. private:
  151. T m_arc; // length of arc.
  152. T m_radius; // one of the two radii of the ellipse
  153. }; // template <class T> struct elliptic_root_functor_noderiv
  154. template <class T = double>
  155. boost::uintmax_t elliptic_root_noderiv(T radius, T arc, T guess)
  156. { // return the other radius of an ellipse, given one radii and the arc-length
  157. using namespace std; // Help ADL of std functions.
  158. using namespace boost::math::tools; // For bracket_and_solve_root.
  159. T factor = 2; // How big steps to take when searching.
  160. const boost::uintmax_t maxit = 50; // Limit to maximum iterations.
  161. boost::uintmax_t it = maxit; // Initally our chosen max iterations, but updated with actual.
  162. bool is_rising = true; // arc-length increases if one radii increases, so function is rising
  163. // Define a termination condition, stop when nearly all digits are correct, but allow for
  164. // the fact that we are returning a range, and must have some inaccuracy in the elliptic integral:
  165. eps_tolerance<T> tol(std::numeric_limits<T>::digits - 2);
  166. // Call bracket_and_solve_root to find the solution, note that this is a rising function:
  167. bracket_and_solve_root(elliptic_root_functor_noderiv<T>(arc, radius), guess, factor, is_rising, tol, it);
  168. return it;
  169. }
  170. template <class T = double>
  171. struct elliptic_root_functor_1deriv
  172. { // Functor also returning 1st derviative.
  173. BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  174. elliptic_root_functor_1deriv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius)
  175. { // Constructor just stores value a to find root of.
  176. }
  177. std::pair<T, T> operator()(T const& x)
  178. {
  179. // Return the difference between required arc-length, and the calculated arc-length for an
  180. // ellipse with radii m_radius and x, plus it's derivative.
  181. // See http://www.wolframalpha.com/input/?i=d%2Fda+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]
  182. // We require two elliptic integral calls, but from these we can calculate both
  183. // the function and it's derivative:
  184. T a = (std::max)(m_radius, x);
  185. T b = (std::min)(m_radius, x);
  186. T a2 = a * a;
  187. T b2 = b * b;
  188. T k = sqrt(1 - b2 / a2);
  189. T Ek = boost::math::ellint_2(k);
  190. T Kk = boost::math::ellint_1(k);
  191. T fx = 4 * a * Ek - m_arc;
  192. T dfx = 4 * (a2 * Ek - b2 * Kk) / (a2 - b2);
  193. return std::make_pair(fx, dfx);
  194. }
  195. private:
  196. T m_arc; // length of arc.
  197. T m_radius; // one of the two radii of the ellipse
  198. }; // struct elliptic_root__functor_1deriv
  199. template <class T = double>
  200. boost::uintmax_t elliptic_root_1deriv(T radius, T arc, T guess)
  201. {
  202. using namespace std; // Help ADL of std functions.
  203. using namespace boost::math::tools; // For newton_raphson_iterate.
  204. BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  205. T min = 0; // Minimum possible value is zero.
  206. T max = arc; // Maximum possible value is the arc length.
  207. // Accuracy doubles at each step, so stop when just over half of the digits are
  208. // correct, and rely on that step to polish off the remainder:
  209. int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.6);
  210. const boost::uintmax_t maxit = 20;
  211. boost::uintmax_t it = maxit;
  212. newton_raphson_iterate(elliptic_root_functor_1deriv<T>(arc, radius), guess, min, max, get_digits, it);
  213. return it;
  214. }
  215. template <class T = double>
  216. struct elliptic_root_functor_2deriv
  217. { // Functor returning both 1st and 2nd derivatives.
  218. BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  219. elliptic_root_functor_2deriv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius) {}
  220. std::tuple<T, T, T> operator()(T const& x)
  221. {
  222. // Return the difference between required arc-length, and the calculated arc-length for an
  223. // ellipse with radii m_radius and x, plus it's derivative.
  224. // See http://www.wolframalpha.com/input/?i=d^2%2Fda^2+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]
  225. // for the second derivative.
  226. T a = (std::max)(m_radius, x);
  227. T b = (std::min)(m_radius, x);
  228. T a2 = a * a;
  229. T b2 = b * b;
  230. T k = sqrt(1 - b2 / a2);
  231. T Ek = boost::math::ellint_2(k);
  232. T Kk = boost::math::ellint_1(k);
  233. T fx = 4 * a * Ek - m_arc;
  234. T dfx = 4 * (a2 * Ek - b2 * Kk) / (a2 - b2);
  235. T dfx2 = 4 * b2 * ((a2 + b2) * Kk - 2 * a2 * Ek) / (a * (a2 - b2) * (a2 - b2));
  236. return std::make_tuple(fx, dfx, dfx2);
  237. }
  238. private:
  239. T m_arc; // length of arc.
  240. T m_radius; // one of the two radii of the ellipse
  241. };
  242. template <class T = double>
  243. boost::uintmax_t elliptic_root_2deriv(T radius, T arc, T guess)
  244. {
  245. using namespace std; // Help ADL of std functions.
  246. using namespace boost::math::tools; // For halley_iterate.
  247. BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  248. T min = 0; // Minimum possible value is zero.
  249. T max = arc; // radius can't be larger than the arc length.
  250. // Accuracy triples at each step, so stop when just over one-third of the digits
  251. // are correct, and the last iteration will polish off the remaining digits:
  252. int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
  253. const boost::uintmax_t maxit = 20;
  254. boost::uintmax_t it = maxit;
  255. halley_iterate(elliptic_root_functor_2deriv<T>(arc, radius), guess, min, max, get_digits, it);
  256. return it;
  257. } // nth_2deriv Halley
  258. //]
  259. // Using 1st and 2nd derivatives using Schroder algorithm.
  260. template <class T = double>
  261. boost::uintmax_t elliptic_root_2deriv_s(T radius, T arc, T guess)
  262. { // return nth root of x using 1st and 2nd derivatives and Schroder.
  263. using namespace std; // Help ADL of std functions.
  264. using namespace boost::math::tools; // For schroder_iterate.
  265. BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
  266. T min = 0; // Minimum possible value is zero.
  267. T max = arc; // radius can't be larger than the arc length.
  268. int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
  269. int get_digits = static_cast<int>(digits * 0.4);
  270. const boost::uintmax_t maxit = 20;
  271. boost::uintmax_t it = maxit;
  272. schroder_iterate(elliptic_root_functor_2deriv<T>(arc, radius), guess, min, max, get_digits, it);
  273. return it;
  274. } // T elliptic_root_2deriv_s Schroder
  275. int main()
  276. {
  277. try
  278. {
  279. double to_root = 500;
  280. double answer = 7.93700525984;
  281. std::cout << "[table\n"
  282. << "[[Initial Guess=][-500% ([approx]1.323)][-100% ([approx]3.97)][-50% ([approx]3.96)][-20% ([approx]6.35)][-10% ([approx]7.14)][-5% ([approx]7.54)]"
  283. "[5% ([approx]8.33)][10% ([approx]8.73)][20% ([approx]9.52)][50% ([approx]11.91)][100% ([approx]15.87)][500 ([approx]47.6)]]\n";
  284. std::cout << "[[bracket_and_solve_root]["
  285. << cbrt_noderiv(to_root, answer / 6)
  286. << "][" << cbrt_noderiv(to_root, answer / 2)
  287. << "][" << cbrt_noderiv(to_root, answer - answer * 0.5)
  288. << "][" << cbrt_noderiv(to_root, answer - answer * 0.2)
  289. << "][" << cbrt_noderiv(to_root, answer - answer * 0.1)
  290. << "][" << cbrt_noderiv(to_root, answer - answer * 0.05)
  291. << "][" << cbrt_noderiv(to_root, answer + answer * 0.05)
  292. << "][" << cbrt_noderiv(to_root, answer + answer * 0.1)
  293. << "][" << cbrt_noderiv(to_root, answer + answer * 0.2)
  294. << "][" << cbrt_noderiv(to_root, answer + answer * 0.5)
  295. << "][" << cbrt_noderiv(to_root, answer + answer)
  296. << "][" << cbrt_noderiv(to_root, answer + answer * 5) << "]]\n";
  297. std::cout << "[[newton_iterate]["
  298. << cbrt_deriv(to_root, answer / 6)
  299. << "][" << cbrt_deriv(to_root, answer / 2)
  300. << "][" << cbrt_deriv(to_root, answer - answer * 0.5)
  301. << "][" << cbrt_deriv(to_root, answer - answer * 0.2)
  302. << "][" << cbrt_deriv(to_root, answer - answer * 0.1)
  303. << "][" << cbrt_deriv(to_root, answer - answer * 0.05)
  304. << "][" << cbrt_deriv(to_root, answer + answer * 0.05)
  305. << "][" << cbrt_deriv(to_root, answer + answer * 0.1)
  306. << "][" << cbrt_deriv(to_root, answer + answer * 0.2)
  307. << "][" << cbrt_deriv(to_root, answer + answer * 0.5)
  308. << "][" << cbrt_deriv(to_root, answer + answer)
  309. << "][" << cbrt_deriv(to_root, answer + answer * 5) << "]]\n";
  310. std::cout << "[[halley_iterate]["
  311. << cbrt_2deriv(to_root, answer / 6)
  312. << "][" << cbrt_2deriv(to_root, answer / 2)
  313. << "][" << cbrt_2deriv(to_root, answer - answer * 0.5)
  314. << "][" << cbrt_2deriv(to_root, answer - answer * 0.2)
  315. << "][" << cbrt_2deriv(to_root, answer - answer * 0.1)
  316. << "][" << cbrt_2deriv(to_root, answer - answer * 0.05)
  317. << "][" << cbrt_2deriv(to_root, answer + answer * 0.05)
  318. << "][" << cbrt_2deriv(to_root, answer + answer * 0.1)
  319. << "][" << cbrt_2deriv(to_root, answer + answer * 0.2)
  320. << "][" << cbrt_2deriv(to_root, answer + answer * 0.5)
  321. << "][" << cbrt_2deriv(to_root, answer + answer)
  322. << "][" << cbrt_2deriv(to_root, answer + answer * 5) << "]]\n";
  323. std::cout << "[[schr'''&#xf6;'''der_iterate]["
  324. << cbrt_2deriv_s(to_root, answer / 6)
  325. << "][" << cbrt_2deriv_s(to_root, answer / 2)
  326. << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.5)
  327. << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.2)
  328. << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.1)
  329. << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.05)
  330. << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.05)
  331. << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.1)
  332. << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.2)
  333. << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.5)
  334. << "][" << cbrt_2deriv_s(to_root, answer + answer)
  335. << "][" << cbrt_2deriv_s(to_root, answer + answer * 5) << "]]\n]\n\n";
  336. double radius_a = 10;
  337. double arc_length = 500;
  338. double radius_b = 123.6216507967705;
  339. std::cout << std::setprecision(4) << "[table\n"
  340. << "[[Initial Guess=][-500% ([approx]" << radius_b / 6 << ")][-100% ([approx]" << radius_b / 2 << ")][-50% ([approx]"
  341. << radius_b - radius_b * 0.5 << ")][-20% ([approx]" << radius_b - radius_b * 0.2 << ")][-10% ([approx]" << radius_b - radius_b * 0.1 << ")][-5% ([approx]" << radius_b - radius_b * 0.05 << ")]"
  342. "[5% ([approx]" << radius_b + radius_b * 0.05 << ")][10% ([approx]" << radius_b + radius_b * 0.1 << ")][20% ([approx]" << radius_b + radius_b * 0.2 << ")][50% ([approx]" << radius_b + radius_b * 0.5
  343. << ")][100% ([approx]" << radius_b + radius_b << ")][500 ([approx]" << radius_b + radius_b * 5 << ")]]\n";
  344. std::cout << "[[bracket_and_solve_root]["
  345. << elliptic_root_noderiv(radius_a, arc_length, radius_b / 6)
  346. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b / 2)
  347. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.5)
  348. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.2)
  349. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.1)
  350. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.05)
  351. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.05)
  352. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.1)
  353. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.2)
  354. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.5)
  355. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b)
  356. << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n";
  357. std::cout << "[[newton_iterate]["
  358. << elliptic_root_1deriv(radius_a, arc_length, radius_b / 6)
  359. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b / 2)
  360. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.5)
  361. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.2)
  362. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.1)
  363. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.05)
  364. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.05)
  365. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.1)
  366. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.2)
  367. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.5)
  368. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b)
  369. << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n";
  370. std::cout << "[[halley_iterate]["
  371. << elliptic_root_2deriv(radius_a, arc_length, radius_b / 6)
  372. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b / 2)
  373. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.5)
  374. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.2)
  375. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.1)
  376. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.05)
  377. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.05)
  378. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.1)
  379. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.2)
  380. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.5)
  381. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b)
  382. << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n";
  383. std::cout << "[[schr'''&#xf6;'''der_iterate]["
  384. << elliptic_root_2deriv_s(radius_a, arc_length, radius_b / 6)
  385. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b / 2)
  386. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.5)
  387. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.2)
  388. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.1)
  389. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.05)
  390. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.05)
  391. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.1)
  392. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.2)
  393. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.5)
  394. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b)
  395. << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n]\n\n";
  396. return boost::exit_success;
  397. }
  398. catch(std::exception ex)
  399. {
  400. std::cout << "exception thrown: " << ex.what() << std::endl;
  401. return boost::exit_failure;
  402. }
  403. } // int main()