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 #include <pch_light.hpp>
7 #include"test_ibeta_inv.hpp"
8
9 #if !defined(TEST_FLOAT) && !defined(TEST_DOUBLE) && !defined(TEST_LDOUBLE) && !defined(TEST_REAL_CONCEPT)
10 # define TEST_FLOAT
11 # define TEST_DOUBLE
12 # define TEST_LDOUBLE
13 # define TEST_REAL_CONCEPT
14 #endif
15
16 //
17 // DESCRIPTION:
18 // ~~~~~~~~~~~~
19 //
20 // This file tests the incomplete beta function inverses
21 // ibeta_inv and ibetac_inv. There are three sets of tests:
22 // 1) Spot tests which compare our results with selected values
23 // computed using the online special function calculator at
24 // functions.wolfram.com,
25 // 2) TODO!!!! Accuracy tests use values generated with NTL::RR at
26 // 1000-bit precision and our generic versions of these functions.
27 // 3) Round trip sanity checks, use the test data for the forward
28 // functions, and verify that we can get (approximately) back
29 // where we started.
30 //
31 // Note that when this file is first run on a new platform many of
32 // these tests will fail: the default accuracy is 1 epsilon which
33 // is too tight for most platforms. In this situation you will
34 // need to cast a human eye over the error rates reported and make
35 // a judgement as to whether they are acceptable. Either way please
36 // report the results to the Boost mailing list. Acceptable rates of
37 // error are marked up below as a series of regular expressions that
38 // identify the compiler/stdlib/platform/data-type/test-data/test-function
39 // along with the maximum expected peek and RMS mean errors for that
40 // test.
41 //
42
expected_results()43 void expected_results()
44 {
45 //
46 // Define the max and mean errors expected for
47 // various compilers and platforms.
48 //
49 // Note that permitted max errors are really pretty high
50 // at around 10000eps. The reason for this is that even
51 // if the forward function is off by 1eps, it's enough to
52 // throw out the inverse by ~7000eps. In other words the
53 // forward function may flatline, so that many x-values
54 // all map to about the same p. Trying to invert in this
55 // region is almost futile.
56 //
57 const char* largest_type;
58 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
59 if(boost::math::policies::digits<double, boost::math::policies::policy<> >() == boost::math::policies::digits<long double, boost::math::policies::policy<> >())
60 {
61 largest_type = "(long\\s+)?double";
62 }
63 else
64 {
65 largest_type = "long double";
66 }
67 #else
68 largest_type = "(long\\s+)?double";
69 #endif
70
71 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
72 //
73 // Linux etc,
74 // Extended exponent range of long double
75 // causes more extreme test cases to be executed:
76 //
77 if(std::numeric_limits<long double>::digits == 64)
78 {
79 add_expected_result(
80 ".*", // compiler
81 ".*", // stdlib
82 ".*", // platform
83 "double", // test type(s)
84 ".*", // test data group
85 ".*", 20, 10); // test function
86 add_expected_result(
87 ".*", // compiler
88 ".*", // stdlib
89 ".*", // platform
90 "long double", // test type(s)
91 ".*", // test data group
92 ".*", 200000, 100000); // test function
93 add_expected_result(
94 ".*", // compiler
95 ".*", // stdlib
96 ".*", // platform
97 "real_concept", // test type(s)
98 ".*", // test data group
99 ".*", 5000000L, 500000); // test function
100 }
101 #endif
102 //
103 // MinGW,
104 // Extended exponent range of long double
105 // causes more extreme test cases to be executed:
106 //
107 add_expected_result(
108 "GNU.*", // compiler
109 ".*", // stdlib
110 "Win32.*", // platform
111 "double", // test type(s)
112 ".*", // test data group
113 ".*", 10, 10); // test function
114 add_expected_result(
115 "GNU.*", // compiler
116 ".*", // stdlib
117 "Win32.*", // platform
118 largest_type, // test type(s)
119 ".*", // test data group
120 ".*", 300000, 20000); // test function
121
122 //
123 // HP-UX and Solaris:
124 // Extended exponent range of long double
125 // causes more extreme test cases to be executed:
126 //
127 add_expected_result(
128 ".*", // compiler
129 ".*", // stdlib
130 "HP-UX|Sun Solaris", // platform
131 "long double", // test type(s)
132 ".*", // test data group
133 ".*", 200000, 100000); // test function
134
135 //
136 // HP Tru64:
137 // Extended exponent range of long double
138 // causes more extreme test cases to be executed:
139 //
140 add_expected_result(
141 "HP Tru64.*", // compiler
142 ".*", // stdlib
143 ".*", // platform
144 "long double", // test type(s)
145 ".*", // test data group
146 ".*", 200000, 100000); // test function
147
148 //
149 // Catch all cases come last:
150 //
151 add_expected_result(
152 ".*", // compiler
153 ".*", // stdlib
154 ".*", // platform
155 largest_type, // test type(s)
156 ".*", // test data group
157 ".*", 10000, 1000); // test function
158 add_expected_result(
159 ".*", // compiler
160 ".*", // stdlib
161 ".*", // platform
162 "real_concept", // test type(s)
163 ".*", // test data group
164 ".*", 500000, 500000); // test function
165
166 //
167 // Finish off by printing out the compiler/stdlib/platform names,
168 // we do this to make it easier to mark up expected error rates.
169 //
170 std::cout << "Tests run with " << BOOST_COMPILER << ", "
171 << BOOST_STDLIB << ", " << BOOST_PLATFORM << std::endl;
172 }
173
BOOST_AUTO_TEST_CASE(test_main)174 BOOST_AUTO_TEST_CASE( test_main )
175 {
176 BOOST_MATH_CONTROL_FP;
177 expected_results();
178 #ifdef TEST_GSL
179 gsl_set_error_handler_off();
180 #endif
181 #ifdef TEST_FLOAT
182 test_spots(0.0F);
183 #endif
184 #ifdef TEST_DOUBLE
185 test_spots(0.0);
186 #endif
187 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
188 #ifdef TEST_LDOUBLE
189 test_spots(0.0L);
190 #endif
191 #ifdef TEST_REAL_CONCEPT
192 test_spots(boost::math::concepts::real_concept(0.1));
193 #endif
194 #endif
195
196 #ifdef TEST_FLOAT
197 test_beta(0.1F, "float");
198 #endif
199 #ifdef TEST_DOUBLE
200 test_beta(0.1, "double");
201 #endif
202 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
203 #ifdef TEST_LDOUBLE
204 test_beta(0.1L, "long double");
205 #endif
206 #ifndef BOOST_MATH_NO_REAL_CONCEPT_TESTS
207 #ifdef TEST_REAL_CONCEPT
208 test_beta(boost::math::concepts::real_concept(0.1), "real_concept");
209 #endif
210 #endif
211 #else
212 std::cout << "<note>The long double tests have been disabled on this platform "
213 "either because the long double overloads of the usual math functions are "
214 "not available at all, or because they are too inaccurate for these tests "
215 "to pass.</note>" << std::endl;
216 #endif
217
218 }
219
220
221
222
223