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