]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // (C) Copyright John Maddock 2006. |
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 | ||
6 | #define BOOST_MATH_MAX_SERIES_ITERATION_POLICY 10000000 | |
7 | ||
20effc67 | 8 | #include "mp_t.hpp" |
92f5a8d4 TL |
9 | #include <boost/math/constants/constants.hpp> |
10 | #include <boost/lexical_cast.hpp> | |
11 | #include <fstream> | |
12 | #include <map> | |
13 | #include <boost/math/tools/test_data.hpp> | |
14 | #include <boost/random.hpp> | |
92f5a8d4 TL |
15 | |
16 | using namespace boost::math::tools; | |
17 | using namespace boost::math; | |
18 | using namespace std; | |
19 | ||
20 | struct hypergeometric_2f2_gen | |
21 | { | |
22 | mp_t operator()(mp_t a1, mp_t a2, mp_t b1, mp_t b2, mp_t z) | |
23 | { | |
24 | mp_t result = 0; | |
25 | mp_t abs_result = 0; | |
26 | mp_t term = 1; | |
27 | mp_t k = 0; | |
28 | ||
29 | do | |
30 | { | |
31 | result += term; | |
32 | abs_result += fabs(term); | |
33 | if (fabs(result) * boost::math::tools::epsilon<mp_t>() > fabs(term)) | |
34 | break; | |
35 | ++k; | |
36 | term *= a1++; | |
37 | term *= a2++; | |
38 | term /= b1++; | |
39 | term /= b2++; | |
40 | term /= k; | |
41 | term *= z; | |
42 | } while (true); | |
43 | // | |
44 | // check precision: | |
45 | // | |
46 | if (abs_result * boost::math::tools::epsilon<mp_t>() / fabs(result) > 1e-40) | |
47 | throw std::domain_error("Unable to calculate result"); | |
48 | if(fabs(result) > (std::numeric_limits<double>::max)()) | |
49 | throw std::domain_error("Unable to calculate result"); | |
50 | ||
51 | std::cout << a1 << " " << a2 << " " << b1 << " " << b2 << " " << z << " " << result << std::endl; | |
52 | return result; | |
53 | } | |
54 | }; | |
55 | ||
56 | int main(int, char* []) | |
57 | { | |
58 | parameter_info<mp_t> arg1, arg2, arg3, arg4, arg5; | |
59 | test_data<mp_t> data; | |
60 | ||
61 | std::cout << "Welcome.\n" | |
62 | "This program will generate spot tests for 2F2:\n"; | |
63 | ||
64 | std::string line; | |
65 | bool cont = true; | |
66 | ||
67 | while (cont) | |
68 | { | |
69 | float range; | |
70 | std::cout << "Enter the range to calculate over for a1, a2, b1 and b2 (single value, range will be -x to x): "; | |
71 | std::cin >> range; | |
72 | ||
73 | float z_range; | |
74 | std::cout << "Enter the range to calculate over for z (single value, range will be -x to x): "; | |
75 | std::cin >> z_range; | |
76 | ||
77 | int num_spots; | |
78 | std::cout << "Enter how many test points to calculate: "; | |
79 | std::cin >> num_spots; | |
80 | ||
81 | std::vector<mp_t> v; | |
82 | random_ns::mt19937 rnd; | |
83 | random_ns::uniform_real_distribution<float> ur_a(-range, range); | |
84 | random_ns::uniform_real_distribution<float> ur_z(-z_range, z_range); | |
85 | ||
86 | do | |
87 | { | |
88 | mp_t a1 = ur_a(rnd); | |
89 | mp_t a2 = ur_a(rnd); | |
90 | mp_t b1 = ur_a(rnd); | |
91 | mp_t b2 = ur_a(rnd); | |
92 | mp_t z = ur_z(rnd); | |
93 | ||
94 | arg1 = make_single_param(a1); | |
95 | arg2 = make_single_param(a2); | |
96 | arg3 = make_single_param(b1); | |
97 | arg4 = make_single_param(b2); | |
98 | arg5 = make_single_param(z); | |
99 | data.insert(hypergeometric_2f2_gen(), arg1, arg2, arg3, arg4, arg5); | |
100 | } while (num_spots--); | |
101 | ||
102 | std::cout << "Any more data?"; | |
103 | std::cin >> cont; | |
104 | ||
105 | } | |
106 | ||
107 | ||
108 | ||
109 | std::cout << "Enter name of test data file [default=hypergeometric_2f2.ipp]"; | |
110 | std::getline(std::cin, line); | |
111 | boost::algorithm::trim(line); | |
112 | if(line == "") | |
113 | line = "hypergeometric_2f2.ipp"; | |
114 | std::ofstream ofs(line.c_str()); | |
115 | ofs << std::scientific << std::setprecision(40); | |
116 | write_code(ofs, data, line.c_str()); | |
117 | ||
118 | return 0; | |
119 | } | |
120 | ||
121 |