carlson_ellint_data.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. // Copyright John Maddock 2006.
  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. #include <boost/math/tools/test_data.hpp>
  7. #include <boost/test/included/prg_exec_monitor.hpp>
  8. #include <boost/math/special_functions/ellint_rj.hpp>
  9. #include <boost/math/special_functions/ellint_rd.hpp>
  10. #include <fstream>
  11. #include <boost/math/tools/test_data.hpp>
  12. #include <boost/random.hpp>
  13. #include "mp_t.hpp"
  14. float extern_val;
  15. // confuse the compilers optimiser, and force a truncation to float precision:
  16. float truncate_to_float(float const * pf)
  17. {
  18. extern_val = *pf;
  19. return *pf;
  20. }
  21. //
  22. // Archived here is the original implementation of this
  23. // function by Xiaogang Zhang, we can use this to
  24. // generate special test cases for the new version:
  25. //
  26. template <typename T, typename Policy>
  27. T ellint_rj_old(T x, T y, T z, T p, const Policy& pol)
  28. {
  29. T value, u, lambda, alpha, beta, sigma, factor, tolerance;
  30. T X, Y, Z, P, EA, EB, EC, E2, E3, S1, S2, S3;
  31. unsigned long k;
  32. BOOST_MATH_STD_USING
  33. using namespace boost::math;
  34. static const char* function = "boost::math::ellint_rj<%1%>(%1%,%1%,%1%)";
  35. if(x < 0)
  36. {
  37. return policies::raise_domain_error<T>(function,
  38. "Argument x must be non-negative, but got x = %1%", x, pol);
  39. }
  40. if(y < 0)
  41. {
  42. return policies::raise_domain_error<T>(function,
  43. "Argument y must be non-negative, but got y = %1%", y, pol);
  44. }
  45. if(z < 0)
  46. {
  47. return policies::raise_domain_error<T>(function,
  48. "Argument z must be non-negative, but got z = %1%", z, pol);
  49. }
  50. if(p == 0)
  51. {
  52. return policies::raise_domain_error<T>(function,
  53. "Argument p must not be zero, but got p = %1%", p, pol);
  54. }
  55. if(x + y == 0 || y + z == 0 || z + x == 0)
  56. {
  57. return policies::raise_domain_error<T>(function,
  58. "At most one argument can be zero, "
  59. "only possible result is %1%.", std::numeric_limits<T>::quiet_NaN(), pol);
  60. }
  61. // error scales as the 6th power of tolerance
  62. tolerance = pow(T(1) * tools::epsilon<T>() / 3, T(1) / 6);
  63. // for p < 0, the integral is singular, return Cauchy principal value
  64. if(p < 0)
  65. {
  66. //
  67. // We must ensure that (z - y) * (y - x) is positive.
  68. // Since the integral is symmetrical in x, y and z
  69. // we can just permute the values:
  70. //
  71. if(x > y)
  72. std::swap(x, y);
  73. if(y > z)
  74. std::swap(y, z);
  75. if(x > y)
  76. std::swap(x, y);
  77. T q = -p;
  78. T pmy = (z - y) * (y - x) / (y + q); // p - y
  79. BOOST_ASSERT(pmy >= 0);
  80. p = pmy + y;
  81. value = ellint_rj_old(x, y, z, p, pol);
  82. value *= pmy;
  83. value -= 3 * boost::math::ellint_rf(x, y, z, pol);
  84. value += 3 * sqrt((x * y * z) / (x * z + p * q)) * boost::math::ellint_rc(x * z + p * q, p * q, pol);
  85. value /= (y + q);
  86. return value;
  87. }
  88. // duplication
  89. sigma = 0;
  90. factor = 1;
  91. k = 1;
  92. do
  93. {
  94. u = (x + y + z + p + p) / 5;
  95. X = (u - x) / u;
  96. Y = (u - y) / u;
  97. Z = (u - z) / u;
  98. P = (u - p) / u;
  99. if((tools::max)(abs(X), abs(Y), abs(Z), abs(P)) < tolerance)
  100. break;
  101. T sx = sqrt(x);
  102. T sy = sqrt(y);
  103. T sz = sqrt(z);
  104. lambda = sy * (sx + sz) + sz * sx;
  105. alpha = p * (sx + sy + sz) + sx * sy * sz;
  106. alpha *= alpha;
  107. beta = p * (p + lambda) * (p + lambda);
  108. sigma += factor * boost::math::ellint_rc(alpha, beta, pol);
  109. factor /= 4;
  110. x = (x + lambda) / 4;
  111. y = (y + lambda) / 4;
  112. z = (z + lambda) / 4;
  113. p = (p + lambda) / 4;
  114. ++k;
  115. } while(k < policies::get_max_series_iterations<Policy>());
  116. // Check to see if we gave up too soon:
  117. policies::check_series_iterations<T>(function, k, pol);
  118. // Taylor series expansion to the 5th order
  119. EA = X * Y + Y * Z + Z * X;
  120. EB = X * Y * Z;
  121. EC = P * P;
  122. E2 = EA - 3 * EC;
  123. E3 = EB + 2 * P * (EA - EC);
  124. S1 = 1 + E2 * (E2 * T(9) / 88 - E3 * T(9) / 52 - T(3) / 14);
  125. S2 = EB * (T(1) / 6 + P * (T(-6) / 22 + P * T(3) / 26));
  126. S3 = P * ((EA - EC) / 3 - P * EA * T(3) / 22);
  127. value = 3 * sigma + factor * (S1 + S2 + S3) / (u * sqrt(u));
  128. return value;
  129. }
  130. template <typename T, typename Policy>
  131. T ellint_rd_imp_old(T x, T y, T z, const Policy& pol)
  132. {
  133. T value, u, lambda, sigma, factor, tolerance;
  134. T X, Y, Z, EA, EB, EC, ED, EE, S1, S2;
  135. unsigned long k;
  136. BOOST_MATH_STD_USING
  137. using namespace boost::math;
  138. static const char* function = "boost::math::ellint_rd<%1%>(%1%,%1%,%1%)";
  139. if(x < 0)
  140. {
  141. return policies::raise_domain_error<T>(function,
  142. "Argument x must be >= 0, but got %1%", x, pol);
  143. }
  144. if(y < 0)
  145. {
  146. return policies::raise_domain_error<T>(function,
  147. "Argument y must be >= 0, but got %1%", y, pol);
  148. }
  149. if(z <= 0)
  150. {
  151. return policies::raise_domain_error<T>(function,
  152. "Argument z must be > 0, but got %1%", z, pol);
  153. }
  154. if(x + y == 0)
  155. {
  156. return policies::raise_domain_error<T>(function,
  157. "At most one argument can be zero, but got, x + y = %1%", x + y, pol);
  158. }
  159. // error scales as the 6th power of tolerance
  160. tolerance = pow(tools::epsilon<T>() / 3, T(1) / 6);
  161. // duplication
  162. sigma = 0;
  163. factor = 1;
  164. k = 1;
  165. do
  166. {
  167. u = (x + y + z + z + z) / 5;
  168. X = (u - x) / u;
  169. Y = (u - y) / u;
  170. Z = (u - z) / u;
  171. if((tools::max)(abs(X), abs(Y), abs(Z)) < tolerance)
  172. break;
  173. T sx = sqrt(x);
  174. T sy = sqrt(y);
  175. T sz = sqrt(z);
  176. lambda = sy * (sx + sz) + sz * sx; //sqrt(x * y) + sqrt(y * z) + sqrt(z * x);
  177. sigma += factor / (sz * (z + lambda));
  178. factor /= 4;
  179. x = (x + lambda) / 4;
  180. y = (y + lambda) / 4;
  181. z = (z + lambda) / 4;
  182. ++k;
  183. } while(k < policies::get_max_series_iterations<Policy>());
  184. // Check to see if we gave up too soon:
  185. policies::check_series_iterations<T>(function, k, pol);
  186. // Taylor series expansion to the 5th order
  187. EA = X * Y;
  188. EB = Z * Z;
  189. EC = EA - EB;
  190. ED = EA - 6 * EB;
  191. EE = ED + EC + EC;
  192. S1 = ED * (ED * T(9) / 88 - Z * EE * T(9) / 52 - T(3) / 14);
  193. S2 = Z * (EE / 6 + Z * (-EC * T(9) / 22 + Z * EA * T(3) / 26));
  194. value = 3 * sigma + factor * (1 + S1 + S2) / (u * sqrt(u));
  195. return value;
  196. }
  197. template <typename T, typename Policy>
  198. T ellint_rf_imp_old(T x, T y, T z, const Policy& pol)
  199. {
  200. T value, X, Y, Z, E2, E3, u, lambda, tolerance;
  201. unsigned long k;
  202. BOOST_MATH_STD_USING
  203. using namespace boost::math;
  204. static const char* function = "boost::math::ellint_rf<%1%>(%1%,%1%,%1%)";
  205. if(x < 0 || y < 0 || z < 0)
  206. {
  207. return policies::raise_domain_error<T>(function,
  208. "domain error, all arguments must be non-negative, "
  209. "only sensible result is %1%.",
  210. std::numeric_limits<T>::quiet_NaN(), pol);
  211. }
  212. if(x + y == 0 || y + z == 0 || z + x == 0)
  213. {
  214. return policies::raise_domain_error<T>(function,
  215. "domain error, at most one argument can be zero, "
  216. "only sensible result is %1%.",
  217. std::numeric_limits<T>::quiet_NaN(), pol);
  218. }
  219. // Carlson scales error as the 6th power of tolerance,
  220. // but this seems not to work for types larger than
  221. // 80-bit reals, this heuristic seems to work OK:
  222. if(policies::digits<T, Policy>() > 64)
  223. {
  224. tolerance = pow(tools::epsilon<T>(), T(1) / 4.25f);
  225. BOOST_MATH_INSTRUMENT_VARIABLE(tolerance);
  226. }
  227. else
  228. {
  229. tolerance = pow(4 * tools::epsilon<T>(), T(1) / 6);
  230. BOOST_MATH_INSTRUMENT_VARIABLE(tolerance);
  231. }
  232. // duplication
  233. k = 1;
  234. do
  235. {
  236. u = (x + y + z) / 3;
  237. X = (u - x) / u;
  238. Y = (u - y) / u;
  239. Z = (u - z) / u;
  240. // Termination condition:
  241. if((tools::max)(abs(X), abs(Y), abs(Z)) < tolerance)
  242. break;
  243. T sx = sqrt(x);
  244. T sy = sqrt(y);
  245. T sz = sqrt(z);
  246. lambda = sy * (sx + sz) + sz * sx;
  247. x = (x + lambda) / 4;
  248. y = (y + lambda) / 4;
  249. z = (z + lambda) / 4;
  250. ++k;
  251. } while(k < policies::get_max_series_iterations<Policy>());
  252. // Check to see if we gave up too soon:
  253. policies::check_series_iterations<T>(function, k, pol);
  254. BOOST_MATH_INSTRUMENT_VARIABLE(k);
  255. // Taylor series expansion to the 5th order
  256. E2 = X * Y - Z * Z;
  257. E3 = X * Y * Z;
  258. value = (1 + E2*(E2 / 24 - E3*T(3) / 44 - T(0.1)) + E3 / 14) / sqrt(u);
  259. BOOST_MATH_INSTRUMENT_VARIABLE(value);
  260. return value;
  261. }
  262. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rj_data_4e(mp_t n)
  263. {
  264. mp_t result = ellint_rj_old(n, n, n, n, boost::math::policies::policy<>());
  265. return boost::math::make_tuple(n, n, n, result);
  266. }
  267. boost::math::tuple<mp_t, mp_t, mp_t, mp_t, mp_t> generate_rj_data_3e(mp_t x, mp_t p)
  268. {
  269. mp_t r = ellint_rj_old(x, x, x, p, boost::math::policies::policy<>());
  270. return boost::math::make_tuple(x, x, x, p, r);
  271. }
  272. boost::math::tuple<mp_t, mp_t, mp_t, mp_t, mp_t> generate_rj_data_2e_1(mp_t x, mp_t y, mp_t p)
  273. {
  274. mp_t r = ellint_rj_old(x, x, y, p, boost::math::policies::policy<>());
  275. return boost::math::make_tuple(x, x, y, p, r);
  276. }
  277. boost::math::tuple<mp_t, mp_t, mp_t, mp_t, mp_t> generate_rj_data_2e_2(mp_t x, mp_t y, mp_t p)
  278. {
  279. mp_t r = ellint_rj_old(x, y, x, p, boost::math::policies::policy<>());
  280. return boost::math::make_tuple(x, y, x, p, r);
  281. }
  282. boost::math::tuple<mp_t, mp_t, mp_t, mp_t, mp_t> generate_rj_data_2e_3(mp_t x, mp_t y, mp_t p)
  283. {
  284. mp_t r = ellint_rj_old(y, x, x, p, boost::math::policies::policy<>());
  285. return boost::math::make_tuple(y, x, x, p, r);
  286. }
  287. boost::math::tuple<mp_t, mp_t, mp_t, mp_t, mp_t> generate_rj_data_2e_4(mp_t x, mp_t y, mp_t p)
  288. {
  289. mp_t r = ellint_rj_old(x, y, p, p, boost::math::policies::policy<>());
  290. return boost::math::make_tuple(x, y, p, p, r);
  291. }
  292. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rd_data_2e_1(mp_t x, mp_t y)
  293. {
  294. mp_t r = ellint_rd_imp_old(x, y, y, boost::math::policies::policy<>());
  295. return boost::math::make_tuple(x, y, y, r);
  296. }
  297. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rd_data_2e_2(mp_t x, mp_t y)
  298. {
  299. mp_t r = ellint_rd_imp_old(x, x, y, boost::math::policies::policy<>());
  300. return boost::math::make_tuple(x, x, y, r);
  301. }
  302. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rd_data_2e_3(mp_t x)
  303. {
  304. mp_t r = ellint_rd_imp_old(mp_t(0), x, x, boost::math::policies::policy<>());
  305. return boost::math::make_tuple(0, x, x, r);
  306. }
  307. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rd_data_3e(mp_t x)
  308. {
  309. mp_t r = ellint_rd_imp_old(x, x, x, boost::math::policies::policy<>());
  310. return boost::math::make_tuple(x, x, x, r);
  311. }
  312. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rd_data_0xy(mp_t x, mp_t y)
  313. {
  314. mp_t r = ellint_rd_imp_old(mp_t(0), x, y, boost::math::policies::policy<>());
  315. return boost::math::make_tuple(mp_t(0), x, y, r);
  316. }
  317. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data_xxx(mp_t x)
  318. {
  319. mp_t r = ellint_rf_imp_old(x, x, x, boost::math::policies::policy<>());
  320. return boost::math::make_tuple(x, x, x, r);
  321. }
  322. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data_xyy(mp_t x, mp_t y)
  323. {
  324. mp_t r = ellint_rf_imp_old(x, y, y, boost::math::policies::policy<>());
  325. return boost::math::make_tuple(x, y, y, r);
  326. }
  327. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data_xxy(mp_t x, mp_t y)
  328. {
  329. mp_t r = ellint_rf_imp_old(x, x, y, boost::math::policies::policy<>());
  330. return boost::math::make_tuple(x, x, y, r);
  331. }
  332. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data_xyx(mp_t x, mp_t y)
  333. {
  334. mp_t r = ellint_rf_imp_old(x, y, x, boost::math::policies::policy<>());
  335. return boost::math::make_tuple(x, y, x, r);
  336. }
  337. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data_0yy(mp_t y)
  338. {
  339. mp_t r = ellint_rf_imp_old(mp_t(0), y, y, boost::math::policies::policy<>());
  340. return boost::math::make_tuple(mp_t(0), y, y, r);
  341. }
  342. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data_xy0(mp_t x, mp_t y)
  343. {
  344. mp_t r = ellint_rf_imp_old(x, y, mp_t(0), boost::math::policies::policy<>());
  345. return boost::math::make_tuple(x, y, mp_t(0), r);
  346. }
  347. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rf_data(mp_t n)
  348. {
  349. static boost::mt19937 r;
  350. boost::uniform_real<float> ur(0, 1);
  351. boost::uniform_int<int> ui(-100, 100);
  352. float x = ur(r);
  353. x = ldexp(x, ui(r));
  354. mp_t xr(truncate_to_float(&x));
  355. float y = ur(r);
  356. y = ldexp(y, ui(r));
  357. mp_t yr(truncate_to_float(&y));
  358. float z = ur(r);
  359. z = ldexp(z, ui(r));
  360. mp_t zr(truncate_to_float(&z));
  361. mp_t result = boost::math::ellint_rf(xr, yr, zr);
  362. return boost::math::make_tuple(xr, yr, zr, result);
  363. }
  364. boost::math::tuple<mp_t, mp_t, mp_t> generate_rc_data(mp_t n)
  365. {
  366. static boost::mt19937 r;
  367. boost::uniform_real<float> ur(0, 1);
  368. boost::uniform_int<int> ui(-100, 100);
  369. float x = ur(r);
  370. x = ldexp(x, ui(r));
  371. mp_t xr(truncate_to_float(&x));
  372. float y = ur(r);
  373. y = ldexp(y, ui(r));
  374. mp_t yr(truncate_to_float(&y));
  375. mp_t result = boost::math::ellint_rc(xr, yr);
  376. return boost::math::make_tuple(xr, yr, result);
  377. }
  378. boost::math::tuple<mp_t, mp_t, mp_t, mp_t, mp_t> generate_rj_data(mp_t n)
  379. {
  380. static boost::mt19937 r;
  381. boost::uniform_real<float> ur(0, 1);
  382. boost::uniform_real<float> nur(-1, 1);
  383. boost::uniform_int<int> ui(-100, 100);
  384. float x = ur(r);
  385. x = ldexp(x, ui(r));
  386. mp_t xr(truncate_to_float(&x));
  387. float y = ur(r);
  388. y = ldexp(y, ui(r));
  389. mp_t yr(truncate_to_float(&y));
  390. float z = ur(r);
  391. z = ldexp(z, ui(r));
  392. mp_t zr(truncate_to_float(&z));
  393. float p = nur(r);
  394. p = ldexp(p, ui(r));
  395. mp_t pr(truncate_to_float(&p));
  396. boost::math::ellint_rj(x, y, z, p);
  397. mp_t result = boost::math::ellint_rj(xr, yr, zr, pr);
  398. return boost::math::make_tuple(xr, yr, zr, pr, result);
  399. }
  400. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rd_data(mp_t n)
  401. {
  402. static boost::mt19937 r;
  403. boost::uniform_real<float> ur(0, 1);
  404. boost::uniform_int<int> ui(-100, 100);
  405. float x = ur(r);
  406. x = ldexp(x, ui(r));
  407. mp_t xr(truncate_to_float(&x));
  408. float y = ur(r);
  409. y = ldexp(y, ui(r));
  410. mp_t yr(truncate_to_float(&y));
  411. float z = ur(r);
  412. z = ldexp(z, ui(r));
  413. mp_t zr(truncate_to_float(&z));
  414. mp_t result = boost::math::ellint_rd(xr, yr, zr);
  415. return boost::math::make_tuple(xr, yr, zr, result);
  416. }
  417. mp_t rg_imp(mp_t x, mp_t y, mp_t z)
  418. {
  419. using std::swap;
  420. // If z is zero permute so the call to RD is valid:
  421. if(z == 0)
  422. swap(x, z);
  423. return (z * ellint_rf_imp_old(x, y, z, boost::math::policies::policy<>())
  424. - (x - z) * (y - z) * ellint_rd_imp_old(x, y, z, boost::math::policies::policy<>()) / 3
  425. + sqrt(x * y / z)) / 2;
  426. }
  427. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_data(mp_t n)
  428. {
  429. static boost::mt19937 r;
  430. boost::uniform_real<float> ur(0, 1);
  431. boost::uniform_int<int> ui(-100, 100);
  432. float x = ur(r);
  433. x = ldexp(x, ui(r));
  434. mp_t xr(truncate_to_float(&x));
  435. float y = ur(r);
  436. y = ldexp(y, ui(r));
  437. mp_t yr(truncate_to_float(&y));
  438. float z = ur(r);
  439. z = ldexp(z, ui(r));
  440. mp_t zr(truncate_to_float(&z));
  441. mp_t result = rg_imp(xr, yr, zr);
  442. return boost::math::make_tuple(xr, yr, zr, result);
  443. }
  444. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_xxx(mp_t x)
  445. {
  446. mp_t result = rg_imp(x, x, x);
  447. return boost::math::make_tuple(x, x, x, result);
  448. }
  449. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_xyy(mp_t x, mp_t y)
  450. {
  451. mp_t result = rg_imp(x, y, y);
  452. return boost::math::make_tuple(x, y, y, result);
  453. }
  454. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_xxy(mp_t x, mp_t y)
  455. {
  456. mp_t result = rg_imp(x, x, y);
  457. return boost::math::make_tuple(x, x, y, result);
  458. }
  459. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_xyx(mp_t x, mp_t y)
  460. {
  461. mp_t result = rg_imp(x, y, x);
  462. return boost::math::make_tuple(x, y, x, result);
  463. }
  464. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_0xx(mp_t x)
  465. {
  466. mp_t result = rg_imp(mp_t(0), x, x);
  467. return boost::math::make_tuple(mp_t(0), x, x, result);
  468. }
  469. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_x0x(mp_t x)
  470. {
  471. mp_t result = rg_imp(x, mp_t(0), x);
  472. return boost::math::make_tuple(x, mp_t(0), x, result);
  473. }
  474. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_xx0(mp_t x)
  475. {
  476. mp_t result = rg_imp(x, x, mp_t(0));
  477. return boost::math::make_tuple(x, x, mp_t(0), result);
  478. }
  479. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_00x(mp_t x)
  480. {
  481. mp_t result = sqrt(x) / 2;
  482. return boost::math::make_tuple(mp_t(0), mp_t(0), x, result);
  483. }
  484. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_0x0(mp_t x)
  485. {
  486. mp_t result = sqrt(x) / 2;
  487. return boost::math::make_tuple(mp_t(0), x, mp_t(0), result);
  488. }
  489. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_x00(mp_t x)
  490. {
  491. mp_t result = sqrt(x) / 2;
  492. return boost::math::make_tuple(x, mp_t(0), mp_t(0), result);
  493. }
  494. boost::math::tuple<mp_t, mp_t, mp_t, mp_t> generate_rg_xy0(mp_t x, mp_t y)
  495. {
  496. mp_t result = rg_imp(x, y, mp_t(0));
  497. return boost::math::make_tuple(x, y, mp_t(0), result);
  498. }
  499. int cpp_main(int argc, char*argv[])
  500. {
  501. using namespace boost::math::tools;
  502. parameter_info<mp_t> arg1, arg2, arg3;
  503. test_data<mp_t> data;
  504. bool cont;
  505. std::string line;
  506. if(argc < 1)
  507. return 1;
  508. do{
  509. #if 0
  510. int count;
  511. std::cout << "Number of points: ";
  512. std::cin >> count;
  513. arg1 = make_periodic_param(mp_t(0), mp_t(1), count);
  514. arg1.type |= dummy_param;
  515. //
  516. // Change this next line to get the R variant you want:
  517. //
  518. data.insert(&generate_rd_data, arg1);
  519. std::cout << "Any more data [y/n]?";
  520. std::getline(std::cin, line);
  521. boost::algorithm::trim(line);
  522. cont = (line == "y");
  523. #else
  524. get_user_parameter_info(arg1, "x");
  525. get_user_parameter_info(arg2, "y");
  526. //get_user_parameter_info(arg3, "p");
  527. arg1.type |= dummy_param;
  528. arg2.type |= dummy_param;
  529. //arg3.type |= dummy_param;
  530. data.insert(generate_rd_data_0xy, arg1, arg2);
  531. std::cout << "Any more data [y/n]?";
  532. std::getline(std::cin, line);
  533. boost::algorithm::trim(line);
  534. cont = (line == "y");
  535. #endif
  536. }while(cont);
  537. std::cout << "Enter name of test data file [default=ellint_rf_data.ipp]";
  538. std::getline(std::cin, line);
  539. boost::algorithm::trim(line);
  540. if(line == "")
  541. line = "ellint_rf_data.ipp";
  542. std::ofstream ofs(line.c_str());
  543. line.erase(line.find('.'));
  544. ofs << std::scientific << std::setprecision(40);
  545. write_code(ofs, data, line.c_str());
  546. return 0;
  547. }