]>
Commit | Line | Data |
---|---|---|
92f5a8d4 TL |
1 | // Copyright John Maddock 2006. |
2 | // Copyright Paul A. Bristow 2007, 2009 | |
3 | // Use, modification and distribution are subject to the | |
4 | // Boost Software License, Version 1.0. (See accompanying file | |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
1e59de90 TL |
7 | #include <boost/math/tools/config.hpp> |
8 | #ifndef BOOST_MATH_NO_MP_TESTS | |
9 | ||
92f5a8d4 TL |
10 | #define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error |
11 | ||
12 | #define BOOST_TEST_MAIN | |
13 | #include <boost/test/unit_test.hpp> | |
14 | #include <boost/test/tools/floating_point_comparison.hpp> | |
15 | #include <boost/math/tools/stats.hpp> | |
16 | #include <boost/math/tools/test.hpp> | |
17 | #include <boost/math/constants/constants.hpp> | |
18 | #include <boost/math/special_functions/gamma.hpp> | |
19 | #include <boost/multiprecision/cpp_bin_float.hpp> | |
1e59de90 | 20 | #include <array> |
92f5a8d4 TL |
21 | #include "functor.hpp" |
22 | ||
23 | #include "handle_test_result.hpp" | |
24 | #include "table_type.hpp" | |
25 | ||
26 | #ifndef SC_ | |
27 | #define SC_(x) static_cast<typename table_type<T>::type>(BOOST_STRINGIZE(x)) | |
28 | #endif | |
29 | ||
30 | template <class Real, class T> | |
31 | void do_test_gamma(const T& data, const char* type_name, const char* test_name) | |
32 | { | |
33 | #if !(defined(ERROR_REPORTING_MODE) && (!defined(TGAMMA_FUNCTION_TO_TEST) || !defined(LGAMMA_FUNCTION_TO_TEST))) | |
34 | typedef Real value_type; | |
35 | ||
36 | typedef value_type (*pg)(value_type); | |
37 | #ifdef TGAMMA_FUNCTION_TO_TEST | |
38 | pg funcp = TGAMMA_FUNCTION_TO_TEST; | |
39 | #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS) | |
40 | pg funcp = boost::math::tgamma<value_type>; | |
41 | #else | |
42 | pg funcp = boost::math::tgamma; | |
43 | #endif | |
44 | ||
45 | boost::math::tools::test_result<value_type> result; | |
46 | ||
47 | std::cout << "Testing " << test_name << " with type " << type_name | |
48 | << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; | |
49 | ||
50 | // | |
51 | // test tgamma against data: | |
52 | // | |
53 | result = boost::math::tools::test_hetero<Real>( | |
54 | data, | |
55 | bind_func<Real>(funcp, 0), | |
56 | extract_result<Real>(1)); | |
57 | handle_test_result(result, data[result.worst()], result.worst(), type_name, "tgamma", test_name); | |
58 | // | |
59 | // test lgamma against data: | |
60 | // | |
61 | #ifdef LGAMMA_FUNCTION_TO_TEST | |
62 | funcp = LGAMMA_FUNCTION_TO_TEST; | |
63 | #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS) | |
64 | funcp = boost::math::lgamma<value_type>; | |
65 | #else | |
66 | funcp = boost::math::lgamma; | |
67 | #endif | |
68 | result = boost::math::tools::test_hetero<Real>( | |
69 | data, | |
70 | bind_func<Real>(funcp, 0), | |
71 | extract_result<Real>(2)); | |
72 | handle_test_result(result, data[result.worst()], result.worst(), type_name, "lgamma", test_name); | |
73 | ||
74 | std::cout << std::endl; | |
75 | #endif | |
76 | } | |
77 | ||
78 | template <class T> | |
79 | void test_gamma(T, const char* name) | |
80 | { | |
81 | // | |
82 | // The actual test data is rather verbose, so it's in a separate file | |
83 | // | |
84 | // The contents are as follows, each row of data contains | |
85 | // three items, input value, gamma and lgamma: | |
86 | // | |
87 | // gamma and lgamma at integer and half integer values: | |
1e59de90 | 88 | // std::array<std::array<T, 3>, N> factorials; |
92f5a8d4 TL |
89 | // |
90 | // gamma and lgamma for z near 0: | |
1e59de90 | 91 | // std::array<std::array<T, 3>, N> near_0; |
92f5a8d4 TL |
92 | // |
93 | // gamma and lgamma for z near 1: | |
1e59de90 | 94 | // std::array<std::array<T, 3>, N> near_1; |
92f5a8d4 TL |
95 | // |
96 | // gamma and lgamma for z near 2: | |
1e59de90 | 97 | // std::array<std::array<T, 3>, N> near_2; |
92f5a8d4 TL |
98 | // |
99 | // gamma and lgamma for z near -10: | |
1e59de90 | 100 | // std::array<std::array<T, 3>, N> near_m10; |
92f5a8d4 TL |
101 | // |
102 | // gamma and lgamma for z near -55: | |
1e59de90 | 103 | // std::array<std::array<T, 3>, N> near_m55; |
92f5a8d4 TL |
104 | // |
105 | // The last two cases are chosen more or less at random, | |
106 | // except that one is even and the other odd, and both are | |
107 | // at negative poles. The data near zero also tests near | |
108 | // a pole, the data near 1 and 2 are to probe lgamma as | |
109 | // the result -> 0. | |
110 | // | |
111 | # include "tgamma_mp_data.hpp" | |
112 | ||
113 | do_test_gamma<T>(factorials, name, "factorials"); | |
114 | do_test_gamma<T>(near_0, name, "near 0"); | |
115 | do_test_gamma<T>(near_1, name, "near 1"); | |
116 | do_test_gamma<T>(near_2, name, "near 2"); | |
117 | do_test_gamma<T>(near_m10, name, "near -10"); | |
118 | do_test_gamma<T>(near_m55, name, "near -55"); | |
119 | } | |
120 | ||
121 | void expected_results() | |
122 | { | |
123 | // | |
124 | // Define the max and mean errors expected for | |
125 | // various compilers and platforms. | |
126 | // | |
127 | add_expected_result( | |
128 | ".*", // compiler | |
129 | ".*", // stdlib | |
130 | ".*", // platform | |
1e59de90 | 131 | "cpp_bin_float_100|number<cpp_bin_float<85> >", // test type(s) |
92f5a8d4 | 132 | ".*", // test data group |
1e59de90 | 133 | "lgamma", 600000, 300000); // test function |
92f5a8d4 TL |
134 | add_expected_result( |
135 | ".*", // compiler | |
136 | ".*", // stdlib | |
137 | ".*", // platform | |
1e59de90 | 138 | "number<cpp_bin_float<[56]5> >", // test type(s) |
92f5a8d4 | 139 | ".*", // test data group |
1e59de90 | 140 | "lgamma", 7000, 3000); // test function |
92f5a8d4 TL |
141 | add_expected_result( |
142 | ".*", // compiler | |
143 | ".*", // stdlib | |
144 | ".*", // platform | |
1e59de90 | 145 | "number<cpp_bin_float<75> >", // test type(s) |
92f5a8d4 | 146 | ".*", // test data group |
1e59de90 | 147 | "lgamma", 40000, 15000); // test function |
92f5a8d4 TL |
148 | add_expected_result( |
149 | ".*", // compiler | |
150 | ".*", // stdlib | |
151 | ".*", // platform | |
152 | ".*", // test type(s) | |
153 | ".*", // test data group | |
1e59de90 | 154 | "lgamma", 600, 200); // test function |
92f5a8d4 TL |
155 | add_expected_result( |
156 | ".*", // compiler | |
157 | ".*", // stdlib | |
158 | ".*", // platform | |
159 | ".*", // test type(s) | |
160 | ".*", // test data group | |
1e59de90 | 161 | "[tl]gamma", 120, 50); // test function |
92f5a8d4 TL |
162 | // |
163 | // Finish off by printing out the compiler/stdlib/platform names, | |
164 | // we do this to make it easier to mark up expected error rates. | |
165 | // | |
166 | std::cout << "Tests run with " << BOOST_COMPILER << ", " | |
167 | << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl; | |
168 | } | |
169 | ||
170 | BOOST_AUTO_TEST_CASE(test_main) | |
171 | { | |
172 | expected_results(); | |
173 | using namespace boost::multiprecision; | |
1e59de90 | 174 | #if !defined(TEST) || (TEST == 1) |
92f5a8d4 TL |
175 | test_gamma(number<cpp_bin_float<38> >(0), "number<cpp_bin_float<38> >"); |
176 | test_gamma(number<cpp_bin_float<45> >(0), "number<cpp_bin_float<45> >"); | |
1e59de90 TL |
177 | #endif |
178 | #if !defined(TEST) || (TEST == 2) | |
92f5a8d4 TL |
179 | test_gamma(cpp_bin_float_50(0), "cpp_bin_float_50"); |
180 | test_gamma(number<cpp_bin_float<55> >(0), "number<cpp_bin_float<55> >"); | |
181 | test_gamma(number<cpp_bin_float<65> >(0), "number<cpp_bin_float<65> >"); | |
1e59de90 TL |
182 | #endif |
183 | #if !defined(TEST) || (TEST == 3) | |
92f5a8d4 TL |
184 | test_gamma(number<cpp_bin_float<75> >(0), "number<cpp_bin_float<75> >"); |
185 | test_gamma(number<cpp_bin_float<85> >(0), "number<cpp_bin_float<85> >"); | |
186 | test_gamma(cpp_bin_float_100(0), "cpp_bin_float_100"); | |
1e59de90 | 187 | #endif |
92f5a8d4 | 188 | } |
1e59de90 TL |
189 | #else // No mp tests |
190 | int main(void) { return 0; } | |
191 | #endif |