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