]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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 | ||
7 | #define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error | |
8 | ||
9 | #include <boost/math/concepts/real_concept.hpp> | |
10 | #define BOOST_TEST_MAIN | |
11 | #include <boost/test/unit_test.hpp> | |
12 | #include <boost/test/floating_point_comparison.hpp> | |
13 | #include <boost/math/special_functions/math_fwd.hpp> | |
14 | #include <boost/math/tools/stats.hpp> | |
15 | #include <boost/math/tools/test.hpp> | |
16 | #include <boost/array.hpp> | |
17 | #include "functor.hpp" | |
18 | ||
19 | #include "handle_test_result.hpp" | |
20 | #include "table_type.hpp" | |
21 | ||
22 | #ifndef SC_ | |
23 | #define SC_(x) static_cast<typename table_type<T>::type>(BOOST_JOIN(x, L)) | |
24 | #endif | |
25 | ||
26 | template <class Real> | |
27 | struct negative_tgamma_ratio | |
28 | { | |
29 | template <class Row> | |
30 | Real operator()(const Row& row) | |
31 | { | |
32 | #ifdef TGAMMA_DELTA_RATIO_FUNCTION_TO_TEST | |
33 | return TGAMMA_DELTA_RATIO_FUNCTION_TO_TEST(Real(row[0]), Real(-Real(row[1]))); | |
34 | #else | |
35 | return boost::math::tgamma_delta_ratio(Real(row[0]), Real(-Real(row[1]))); | |
36 | #endif | |
37 | } | |
38 | }; | |
39 | ||
40 | template <class Real, class T> | |
41 | void do_test_tgamma_delta_ratio(const T& data, const char* type_name, const char* test_name) | |
42 | { | |
43 | #if !(defined(ERROR_REPORTING_MODE) && !defined(TGAMMA_DELTA_RATIO_FUNCTION_TO_TEST)) | |
44 | typedef Real value_type; | |
45 | ||
46 | typedef value_type (*pg)(value_type, value_type); | |
47 | #ifdef TGAMMA_DELTA_RATIO_FUNCTION_TO_TEST | |
48 | pg funcp = TGAMMA_DELTA_RATIO_FUNCTION_TO_TEST; | |
49 | #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS) | |
50 | pg funcp = boost::math::tgamma_delta_ratio<value_type, value_type>; | |
51 | #else | |
52 | pg funcp = boost::math::tgamma_delta_ratio; | |
53 | #endif | |
54 | ||
55 | boost::math::tools::test_result<value_type> result; | |
56 | ||
57 | std::cout << "Testing " << test_name << " with type " << type_name | |
58 | << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; | |
59 | ||
60 | // | |
61 | // test tgamma_delta_ratio against data: | |
62 | // | |
63 | result = boost::math::tools::test_hetero<Real>( | |
64 | data, | |
65 | bind_func<Real>(funcp, 0, 1), | |
66 | extract_result<Real>(2)); | |
67 | handle_test_result(result, data[result.worst()], result.worst(), type_name, "tgamma_delta_ratio", test_name); | |
68 | result = boost::math::tools::test_hetero<Real>( | |
69 | data, | |
70 | negative_tgamma_ratio<Real>(), | |
71 | extract_result<Real>(3)); | |
72 | std::string s(test_name); | |
73 | s += " (negative delta)"; | |
74 | handle_test_result(result, data[result.worst()], result.worst(), type_name, "tgamma_delta_ratio", s.c_str()); | |
75 | #endif | |
76 | } | |
77 | ||
78 | template <class Real, class T> | |
79 | void do_test_tgamma_ratio(const T& data, const char* type_name, const char* test_name) | |
80 | { | |
81 | #if !(defined(ERROR_REPORTING_MODE) && !defined(TGAMMA_RATIO_FUNCTION_TO_TEST)) | |
82 | typedef Real value_type; | |
83 | ||
84 | typedef value_type (*pg)(value_type, value_type); | |
85 | #ifdef TGAMMA_RATIO_FUNCTION_TO_TEST | |
86 | pg funcp = TGAMMA_RATIO_FUNCTION_TO_TEST; | |
87 | #elif defined(BOOST_MATH_NO_DEDUCED_FUNCTION_POINTERS) | |
88 | pg funcp = boost::math::tgamma_ratio<value_type, value_type>; | |
89 | #else | |
90 | pg funcp = boost::math::tgamma_ratio; | |
91 | #endif | |
92 | ||
93 | boost::math::tools::test_result<value_type> result; | |
94 | ||
95 | std::cout << "Testing " << test_name << " with type " << type_name | |
96 | << "\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; | |
97 | ||
98 | // | |
99 | // test tgamma_ratio against data: | |
100 | // | |
101 | result = boost::math::tools::test_hetero<Real>( | |
102 | data, | |
103 | bind_func<Real>(funcp, 0, 1), | |
104 | extract_result<Real>(2)); | |
105 | handle_test_result(result, data[result.worst()], result.worst(), type_name, "tgamma_ratio", test_name); | |
106 | #endif | |
107 | } | |
108 | ||
109 | template <class T> | |
110 | void test_tgamma_ratio(T, const char* name) | |
111 | { | |
112 | // | |
113 | // The actual test data is rather verbose, so it's in a separate file | |
114 | // | |
115 | # include "tgamma_delta_ratio_data.ipp" | |
116 | ||
117 | do_test_tgamma_delta_ratio<T>(tgamma_delta_ratio_data, name, "tgamma + small delta ratios"); | |
118 | ||
119 | # include "tgamma_delta_ratio_int.ipp" | |
120 | ||
121 | do_test_tgamma_delta_ratio<T>(tgamma_delta_ratio_int, name, "tgamma + small integer ratios"); | |
122 | ||
123 | # include "tgamma_delta_ratio_int2.ipp" | |
124 | ||
125 | do_test_tgamma_delta_ratio<T>(tgamma_delta_ratio_int2, name, "integer tgamma ratios"); | |
126 | ||
127 | # include "tgamma_ratio_data.ipp" | |
128 | ||
129 | do_test_tgamma_ratio<T>(tgamma_ratio_data, name, "tgamma ratios"); | |
130 | ||
131 | } | |
132 | ||
133 | template <class T> | |
134 | void test_spots(T, const char*) | |
135 | { | |
136 | #ifdef _MSC_VER | |
137 | # pragma warning(push) | |
138 | # pragma warning(disable:4127 4756) | |
139 | #endif | |
140 | // | |
141 | // A few special spot tests: | |
142 | // | |
143 | BOOST_MATH_STD_USING | |
144 | T tol = boost::math::tools::epsilon<T>() * 20; | |
145 | if(std::numeric_limits<T>::max_exponent > 200) | |
146 | { | |
147 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -500)), T(180.25)), T(8.0113754557649679470816892372669519037339812035512e-178L), 3 * tol); | |
148 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -525)), T(192.25)), T(1.5966560279353205461166489184101261541784867035063e-197L), 3 * tol); | |
149 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(182.25), T(ldexp(T(1), -500))), T(4.077990437521002194346763299159975185747917450788e+181L), 3 * tol); | |
150 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(193.25), T(ldexp(T(1), -525))), T(1.2040790040958522422697601672703926839178050326148e+199L), 3 * tol); | |
151 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(193.25), T(194.75)), T(0.00037151765099653237632823607820104961270831942138159L), 3 * tol); | |
152 | } | |
153 | BOOST_MATH_CHECK_THROW(boost::math::tgamma_ratio(T(0), T(2)), std::domain_error); | |
154 | BOOST_MATH_CHECK_THROW(boost::math::tgamma_ratio(T(2), T(0)), std::domain_error); | |
155 | BOOST_MATH_CHECK_THROW(boost::math::tgamma_ratio(T(-1), T(2)), std::domain_error); | |
156 | BOOST_MATH_CHECK_THROW(boost::math::tgamma_ratio(T(2), T(-1)), std::domain_error); | |
157 | if(std::numeric_limits<T>::has_infinity) | |
158 | { | |
159 | BOOST_MATH_CHECK_THROW(boost::math::tgamma_ratio(std::numeric_limits<T>::infinity(), T(2)), std::domain_error); | |
160 | BOOST_MATH_CHECK_THROW(boost::math::tgamma_ratio(T(2), std::numeric_limits<T>::infinity()), std::domain_error); | |
161 | } | |
162 | // | |
163 | // Some bug cases from Rocco Romeo: | |
164 | // | |
165 | if(std::numeric_limits<T>::min_exponent < -1020) | |
166 | { | |
167 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1020)), T(100)), T(1.20390418056093374068585549133304106854441830616070800417660e151L), tol); | |
168 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1020)), T(150)), T(2.94980580122226729924781231239336413648584663386992050529324e46L), tol); | |
169 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1020)), T(180)), T(1.00669209319561468911303652019446665496398881230516805140750e-20L), tol); | |
170 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1020)), T(220)), T(1.08230263539550701700187215488533416834407799907721731317227e-112L), tol); | |
171 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1020)), T(260)), T(7.62689807594728483940172477902929825624752380292252137809206e-208L), tol); | |
172 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1020)), T(290)), T(5.40206998243175672775582485422795773284966068149812072521290e-281L), tol); | |
173 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_delta_ratio(T(ldexp(T(1), -1020)), T(ldexp(T(1), -1020))), T(2), tol); | |
174 | if(0 != ldexp(T(1), -1074)) | |
175 | { | |
176 | // This is denorm_min at double precision: | |
177 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(ldexp(T(1), -1074)), T(200)), T(5.13282785052571536804189023927976812551830809667482691717029e-50), tol * 50); | |
178 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_ratio(T(200), T(ldexp(T(1), -1074))), T(1.94824379293682687942882944294875087145333536754699303593931e49), tol * 10); | |
179 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_delta_ratio(T(ldexp(T(1), -1074)), T(200)), T(5.13282785052571536804189023927976812551830809667482691717029e-50), tol * 10); | |
180 | BOOST_CHECK_CLOSE_FRACTION(boost::math::tgamma_delta_ratio(T(200), T(ldexp(T(1), -1074))), T(1), tol); | |
181 | } | |
182 | } | |
183 | } |