]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // test_arcsine_dist.cpp |
2 | ||
3 | // Copyright John Maddock 2014. | |
4 | // Copyright Paul A. Bristow 2014. | |
5 | ||
6 | // Use, modification and distribution are subject to the | |
7 | // Boost Software License, Version 1.0. | |
8 | // (See accompanying file LICENSE_1_0.txt | |
9 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
10 | ||
11 | // Tests for the arcsine Distribution. | |
12 | ||
13 | #include <pch.hpp> // Must be 1st include, and include_directory /libs/math/src/tr1/ is needed. | |
14 | ||
15 | #ifdef _MSC_VER | |
16 | # pragma warning(disable: 4127) // Conditional expression is constant. | |
17 | # pragma warning (disable : 4996) // POSIX name for this item is deprecated. | |
18 | # pragma warning (disable : 4224) // Nonstandard extension used : formal parameter 'arg' was previously defined as a type. | |
19 | #endif | |
20 | ||
21 | #include <boost/math/concepts/real_concept.hpp> // for real_concept. | |
22 | using ::boost::math::concepts::real_concept; | |
23 | #include <boost/math/tools/test.hpp> // for real_concept. | |
24 | ||
25 | #include <boost/math/distributions/arcsine.hpp> // for arcsine_distribution. | |
26 | using boost::math::arcsine_distribution; | |
27 | ||
28 | #include <boost/math/constants/constants.hpp> | |
29 | using boost::math::constants::one_div_root_two; | |
30 | ||
31 | #define BOOST_TEST_MAIN | |
32 | #include <boost/test/unit_test.hpp> // for test_main | |
92f5a8d4 | 33 | #include <boost/test/tools/floating_point_comparison.hpp> // for BOOST_CHECK_CLOSE_FRACTION |
7c673cae FG |
34 | |
35 | #include <cmath> | |
36 | ||
37 | #include "test_out_of_range.hpp" | |
38 | ||
39 | #include <iostream> | |
40 | using std::cout; | |
41 | using std::endl; | |
42 | #include <limits> | |
43 | using std::numeric_limits; | |
44 | ||
45 | ||
46 | template <class RealType> | |
47 | void test_ignore_policy(RealType) | |
48 | { | |
49 | // Check on returns when errors are ignored. | |
50 | if ((typeid(RealType) != typeid(boost::math::concepts::real_concept)) | |
51 | && std::numeric_limits<RealType>::has_infinity | |
52 | && std::numeric_limits<RealType>::has_quiet_NaN | |
53 | ) | |
54 | { // Ordinary floats only. | |
55 | ||
56 | using namespace boost::math; | |
57 | // RealType inf = std::numeric_limits<RealType>::infinity(); | |
58 | RealType nan = std::numeric_limits<RealType>::quiet_NaN(); | |
59 | ||
60 | using boost::math::policies::policy; | |
61 | // Types of error whose action can be altered by policies:. | |
62 | //using boost::math::policies::evaluation_error; | |
63 | //using boost::math::policies::domain_error; | |
64 | //using boost::math::policies::overflow_error; | |
65 | //using boost::math::policies::underflow_error; | |
66 | //using boost::math::policies::domain_error; | |
67 | //using boost::math::policies::pole_error; | |
68 | ||
69 | //// Actions on error (in enum error_policy_type): | |
70 | //using boost::math::policies::errno_on_error; | |
71 | //using boost::math::policies::ignore_error; | |
72 | //using boost::math::policies::throw_on_error; | |
73 | //using boost::math::policies::denorm_error; | |
74 | //using boost::math::policies::pole_error; | |
75 | //using boost::math::policies::user_error; | |
76 | ||
77 | typedef policy< | |
78 | boost::math::policies::domain_error<boost::math::policies::ignore_error>, | |
79 | boost::math::policies::overflow_error<boost::math::policies::ignore_error>, | |
80 | boost::math::policies::underflow_error<boost::math::policies::ignore_error>, | |
81 | boost::math::policies::denorm_error<boost::math::policies::ignore_error>, | |
82 | boost::math::policies::pole_error<boost::math::policies::ignore_error>, | |
83 | boost::math::policies::evaluation_error<boost::math::policies::ignore_error> | |
84 | > ignore_all_policy; | |
85 | ||
86 | typedef arcsine_distribution<RealType, ignore_all_policy> ignore_error_arcsine; | |
87 | ||
88 | // Only test NaN and infinity if type has these features (realconcept returns zero). | |
89 | // Integers are always converted to RealType, | |
90 | // others requires static cast to RealType from long double. | |
91 | ||
92 | if (std::numeric_limits<RealType>::has_quiet_NaN) | |
93 | { | |
94 | // Demonstrate output of PDF with infinity, | |
f67539c2 | 95 | // but string output from NaN is platform dependent, so can't use BOOST_CHECK. |
7c673cae FG |
96 | if (std::numeric_limits<RealType>::has_infinity) |
97 | { | |
98 | //std::cout << "pdf(ignore_error_arcsine(-1, +1), std::numeric_limits<RealType>::infinity()) = " << pdf(ignore_error_arcsine(-1, +1), std::numeric_limits<RealType>::infinity()) << std::endl; | |
99 | // Outputs: pdf(ignore_error_arcsine(-1, +1), std::numeric_limits<RealType>::infinity()) = 1.#QNAN | |
100 | } | |
101 | BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), std::numeric_limits<RealType>::infinity()))); // x == infinity | |
102 | BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), std::numeric_limits<RealType>::infinity()))); // x == infinity | |
103 | BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), static_cast <RealType>(-2)))); // x < xmin | |
104 | BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), static_cast <RealType>(-2)))); // x < xmin | |
105 | BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(0, 1), static_cast <RealType>(+2)))); // x > x_max | |
106 | BOOST_CHECK((boost::math::isnan)(pdf(ignore_error_arcsine(-1, 1), static_cast <RealType>(+2)))); // x > x_max | |
107 | ||
108 | // Mean | |
109 | BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(-nan, 0)))); | |
110 | BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(+nan, 0)))); | |
111 | ||
112 | if (std::numeric_limits<RealType>::has_infinity) | |
113 | { | |
114 | //BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(-std::numeric_limits<RealType>::infinity(), 0)))); | |
115 | // std::cout << "arcsine(-inf,+1) mean " << mean(ignore_error_arcsine(-std::numeric_limits<RealType>::infinity())) << std::endl; | |
116 | //BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(std::numeric_limits<RealType>::infinity(), 0)))); | |
117 | } | |
118 | ||
119 | // NaN constructors. | |
120 | BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(2, nan)))); | |
121 | BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(nan, nan)))); | |
b32b8144 | 122 | BOOST_CHECK((boost::math::isnan)(mean(ignore_error_arcsine(nan, 2)))); |
7c673cae FG |
123 | |
124 | // Variance | |
125 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(nan, 0)))); | |
126 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(1, nan)))); | |
127 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(2, nan)))); | |
128 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(0, 0)))); | |
129 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(1, 0)))); | |
130 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(static_cast<RealType>(1.7L), 0)))); | |
131 | BOOST_CHECK((boost::math::isnan)(variance(ignore_error_arcsine(2, 0)))); | |
132 | ||
133 | // Skewness | |
134 | BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(nan, 0)))); | |
135 | BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(-1, nan)))); | |
136 | BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(0, 0)))); | |
137 | BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(1, 0)))); | |
138 | BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(2, 0)))); | |
139 | BOOST_CHECK((boost::math::isnan)(skewness(ignore_error_arcsine(3, 0)))); | |
140 | ||
b32b8144 | 141 | // Kurtosis |
7c673cae FG |
142 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(nan, 0)))); |
143 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(-1, nan)))); | |
144 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(0, 0)))); | |
145 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(1, 0)))); | |
146 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(2, 0)))); | |
147 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(static_cast<RealType>(2.0001L), 0)))); | |
148 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(3, 0)))); | |
149 | BOOST_CHECK((boost::math::isnan)(kurtosis(ignore_error_arcsine(4, 0)))); | |
150 | ||
151 | // Kurtosis excess | |
152 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(nan, 0)))); | |
153 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(-1, nan)))); | |
154 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(0, 0)))); | |
155 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(1, 0)))); | |
156 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(2, 0)))); | |
157 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(static_cast<RealType>(2.0001L), 0)))); | |
158 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(3, 0)))); | |
159 | BOOST_CHECK((boost::math::isnan)(kurtosis_excess(ignore_error_arcsine(4, 0)))); | |
160 | } // has_quiet_NaN | |
161 | ||
b32b8144 | 162 | // |
7c673cae FG |
163 | BOOST_CHECK(boost::math::isfinite(mean(ignore_error_arcsine(0, std::numeric_limits<RealType>::epsilon())))); |
164 | ||
165 | check_support<arcsine_distribution<RealType> >(arcsine_distribution<RealType>(0, 1)); | |
166 | } // ordinary floats. | |
167 | } // template <class RealType> void test_ignore_policy(RealType) | |
168 | ||
169 | ||
170 | template <class RealType> | |
171 | RealType informax() | |
172 | { //! \return Infinity else max_value. | |
173 | return ((std::numeric_limits<RealType>::has_infinity) ? | |
174 | std::numeric_limits<RealType>::infinity() : boost::math::tools::max_value<RealType>()); | |
175 | } | |
176 | ||
177 | template <class RealType> | |
178 | void test_spot( | |
179 | RealType a, // alpha a or lo or x_min | |
180 | RealType b, // arcsine b or hi or x_maz | |
181 | RealType x, // Probability | |
182 | RealType P, // CDF of arcsine(a, b) | |
183 | RealType Q, // Complement of CDF of arcsine (a, b) | |
184 | RealType tol) // Test tolerance. | |
185 | { | |
186 | boost::math::arcsine_distribution<RealType> anarcsine(a, b); | |
187 | BOOST_CHECK_CLOSE_FRACTION(cdf(anarcsine, x), P, tol); | |
188 | if ((P < 0.99) && (Q < 0.99)) | |
189 | { // We can only check this if P is not too close to 1, | |
190 | // so that we can guarantee that Q is free of error, | |
191 | // (and similarly for Q). | |
192 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(anarcsine, x)), Q, tol); | |
193 | if (x != 0) | |
194 | { | |
195 | BOOST_CHECK_CLOSE_FRACTION( | |
196 | quantile(anarcsine, P), x, tol); | |
197 | } | |
198 | else | |
199 | { | |
200 | // Just check quantile is very small: | |
201 | if ((std::numeric_limits<RealType>::max_exponent <= std::numeric_limits<double>::max_exponent) | |
202 | && (boost::is_floating_point<RealType>::value)) | |
203 | { | |
204 | // Limit where this is checked: if exponent range is very large we may | |
205 | // run out of iterations in our root finding algorithm. | |
206 | BOOST_CHECK(quantile(anarcsine, P) < boost::math::tools::epsilon<RealType>() * 10); | |
207 | } | |
208 | } // if k | |
209 | if (x != 0) | |
210 | { | |
211 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(anarcsine, Q)), x, tol * 10); | |
212 | } | |
213 | else | |
214 | { // Just check quantile is very small: | |
215 | if ((std::numeric_limits<RealType>::max_exponent <= std::numeric_limits<double>::max_exponent) && (boost::is_floating_point<RealType>::value)) | |
216 | { // Limit where this is checked: if exponent range is very large we may | |
217 | // run out of iterations in our root finding algorithm. | |
218 | BOOST_CHECK(quantile(complement(anarcsine, Q)) < boost::math::tools::epsilon<RealType>() * 10); | |
219 | } | |
220 | } // if x | |
221 | } | |
222 | } // template <class RealType> void test_spot | |
223 | ||
224 | template <class RealType> // Any floating-point type RealType. | |
225 | void test_spots(RealType) | |
226 | { | |
227 | // Basic sanity checks with 'known good' values. | |
228 | // so set tolerance to a few eps expressed as a fraction, or | |
229 | // few eps of type double expressed as a fraction, | |
230 | // whichever is the larger. | |
231 | ||
232 | RealType tolerance = (std::max) | |
233 | (boost::math::tools::epsilon<RealType>(), | |
234 | static_cast<RealType>(std::numeric_limits<double>::epsilon())); // 0 if real_concept. | |
235 | ||
7c673cae FG |
236 | tolerance *= 2; // Note: NO * 100 because tolerance is a fraction, NOT %. |
237 | cout << "tolerance = " << tolerance << endl; | |
238 | ||
239 | using boost::math::arcsine_distribution; | |
240 | using ::boost::math::cdf; | |
241 | using ::boost::math::pdf; | |
242 | using ::boost::math::complement; | |
243 | using ::boost::math::quantile; | |
244 | ||
245 | // Basic sanity-check spot values. | |
246 | ||
247 | // Test values from Wolfram alpha, for example: | |
248 | // http://www.wolframalpha.com/input/?i=+N%5BPDF%5Barcsinedistribution%5B0%2C+1%5D%2C+0.5%5D%2C+50%5D | |
249 | // N[PDF[arcsinedistribution[0, 1], 0.5], 50] | |
250 | // 0.63661977236758134307553505349005744813783858296183 | |
251 | ||
252 | arcsine_distribution<RealType> arcsine_01; // (Our) Standard arcsine. | |
253 | // Member functions. | |
254 | BOOST_CHECK_EQUAL(arcsine_01.x_min(), 0); | |
255 | BOOST_CHECK_EQUAL(arcsine_01.x_max(), 1); | |
256 | ||
257 | // Derived functions. | |
258 | BOOST_CHECK_EQUAL(mean(arcsine_01), 0.5); // 1 / (1 + 1) = 1/2 exactly. | |
259 | BOOST_CHECK_EQUAL(median(arcsine_01), 0.5); // 1 / (1 + 1) = 1/2 exactly. | |
260 | BOOST_CHECK_EQUAL(variance(arcsine_01), 0.125); // 1/8 = 0.125 | |
261 | BOOST_CHECK_CLOSE_FRACTION(standard_deviation(arcsine_01), one_div_root_two<double>() / 2, tolerance); // 1/ sqrt(s) = 0.35355339059327379 | |
262 | BOOST_CHECK_EQUAL(skewness(arcsine_01), 0); // | |
263 | BOOST_CHECK_EQUAL(kurtosis_excess(arcsine_01), -1.5); // 3/2 | |
264 | BOOST_CHECK_EQUAL(support(arcsine_01).first, 0); // | |
265 | BOOST_CHECK_EQUAL(range(arcsine_01).first, 0); // | |
266 | BOOST_MATH_CHECK_THROW(mode(arcsine_01), std::domain_error); // Two modes at x_min and x_max, so throw instead. | |
267 | ||
268 | ||
269 | // pdf of x = 1/4 is same as reflected value at x = 3/4. | |
b32b8144 | 270 | // N[PDF[arcsinedistribution[0, 1], 0.25], 50] |
7c673cae FG |
271 | // N[PDF[arcsinedistribution[0, 1], 0.75], 50] |
272 | // 0.73510519389572273268176866441729258852984864048885 | |
273 | ||
274 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.000001), static_cast<RealType>(318.31004533885312973989414360099118178698415543136L), tolerance); | |
275 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.000005), static_cast<RealType>(142.35286456604168061345817902422241622116338936911L), tolerance); | |
276 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.05), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), tolerance); | |
277 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.5), static_cast<RealType>(0.63661977236758134307553505349005744813783858296183L), tolerance); | |
278 | // Note loss of significance when x is near x_max. | |
279 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.95), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), 8 * tolerance); // Less accurate. | |
280 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.999995), static_cast<RealType>(142.35286456604168061345817902422241622116338936911L), 50000 * tolerance); // Much less accurate. | |
281 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, 0.999999), static_cast<RealType>(318.31004533885312973989414360099118178698415543136L), 100000 * tolerance);// Even less accurate. | |
282 | ||
283 | // Extreme x. | |
284 | if (std::numeric_limits<RealType>::has_infinity) | |
285 | { // | |
286 | BOOST_CHECK_EQUAL(pdf(arcsine_01, 0), informax<RealType>()); // | |
287 | BOOST_CHECK_EQUAL(pdf(arcsine_01, 1), informax<RealType>()); // | |
288 | } | |
289 | ||
290 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, tolerance), | |
291 | 1 /(sqrt(tolerance) * boost::math::constants::pi<RealType>()), 2 * tolerance); // | |
292 | BOOST_CHECK_CLOSE_FRACTION(pdf(arcsine_01, static_cast<RealType>(1) - tolerance), | |
293 | 1 /(sqrt(tolerance) * boost::math::constants::pi<RealType>()), 2 * tolerance); // | |
294 | ||
295 | // CDF | |
296 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.000001), static_cast<RealType>(0.00063661987847092448418377367957384866092127786060574L), tolerance); | |
297 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.000005), static_cast<RealType>(0.0014235262731079289297302426454125318201831474507326L), tolerance); | |
298 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.05), static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), tolerance); | |
299 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.5), static_cast<RealType>(0.5L), tolerance); // Exact. | |
300 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.95), static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), 2 * tolerance); | |
301 | // Values near unity should use the cdf complemented for better accuracy, | |
302 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.999995), static_cast<RealType>(0.99857647372689207107026975735458746817981685254927L), 100 * tolerance); // Less accurate. | |
303 | BOOST_CHECK_CLOSE_FRACTION(cdf(arcsine_01, 0.999999), static_cast<RealType>(0.99936338012152907551581622632042615133907872213939L), 1000 * tolerance); // Less accurate. | |
304 | ||
305 | // Complement CDF | |
306 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.000001)), static_cast<RealType>(1 - 0.00063661987847092448418377367957384866092127786060574L), 2 * tolerance); | |
307 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.000001)), static_cast<RealType>(0.99936338012152907551581622632043L), 2 * tolerance); // | |
308 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.05)), static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), tolerance); | |
309 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.5)), static_cast<RealType>(0.5L), tolerance); // Exact. | |
310 | // Some values near unity when complement is expected to be less accurate. | |
311 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.95)), static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), 8 * tolerance); // 2 for asin | |
312 | BOOST_CHECK_CLOSE_FRACTION(cdf(complement(arcsine_01, 0.999999)), static_cast<RealType>(1 - 0.99936338012152907551581622632042615133907872213939L), 1000000 * tolerance); // 10000 for asin, 1000000 for acos. | |
313 | ||
314 | // Quantile. | |
315 | ||
316 | // Check 1st, 2nd and 3rd quartiles. | |
317 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.25L)), static_cast<RealType>(0.14644660940672624L), tolerance); | |
318 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.5L)), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5 | |
319 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.75L)), static_cast<RealType>(0.85355339059327373L), tolerance); | |
b32b8144 | 320 | |
7c673cae FG |
321 | // N[CDF[arcsinedistribution[0, 1], 0.05], 50] == 0.14356629312870627075094188477505571882161519989741 |
322 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L)), 0.05, tolerance); | |
323 | ||
324 | // Quantile of complement. | |
325 | // N[1-CDF[arcsinedistribution[0, 1], 0.05], 50] == 0.85643370687129372924905811522494428117838480010259 | |
326 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L))), 0.05, tolerance * 2); | |
327 | // N[sin^2[0.75 * pi/2],50] == 0.85355339059327376220042218105242451964241796884424 | |
328 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.25L))), static_cast<RealType>(0.85355339059327376220042218105242451964241796884424L), tolerance); | |
329 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.5L))), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5 | |
330 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(arcsine_01, static_cast<RealType>(0.75L))), static_cast<RealType>(0.14644660940672623779957781894757548035758203115576L), 2 * tolerance); // Less accurate. | |
331 | ||
332 | // N[CDF[arcsinedistribution[0, 1], 0.25], 5 | |
333 | // 0.33333333333333333333333333333333333333333333333333 | |
334 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(1) / 3), static_cast<RealType>(0.25L), 2 * tolerance); | |
335 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(0.5L)), 0.5, 2 * tolerance); // probability = 0.5, x = 0.5 | |
336 | BOOST_CHECK_CLOSE_FRACTION(quantile(arcsine_01, static_cast<RealType>(2) / 3), static_cast<RealType>(0.75L), tolerance); | |
337 | ||
338 | // Arcsine(-1, +1) xmin = -1, x_max = +1 symmetric about zero. | |
339 | arcsine_distribution<RealType> as_m11(-1, +1); | |
340 | ||
341 | BOOST_CHECK_EQUAL(as_m11.x_min(), -1); // | |
342 | BOOST_CHECK_EQUAL(as_m11.x_max(), +1); | |
343 | BOOST_CHECK_EQUAL(mean(as_m11), 0); // | |
344 | BOOST_CHECK_EQUAL(median(as_m11), 0); // | |
345 | BOOST_CHECK_CLOSE_FRACTION(standard_deviation(as_m11), one_div_root_two<RealType>(), tolerance * 2); // | |
346 | ||
347 | BOOST_CHECK_EQUAL(variance(as_m11), 0.5); // 1 - (-1) = 2 ^ 2 = 4 /8 = 0.5 | |
348 | BOOST_CHECK_EQUAL(skewness(as_m11), 0); // | |
349 | BOOST_CHECK_EQUAL(kurtosis_excess(as_m11), -1.5); // 3/2 | |
350 | ||
351 | ||
352 | BOOST_CHECK_CLOSE_FRACTION(pdf(as_m11, 0.05), static_cast<RealType>(0.31870852113797122803869876869296281629727218095644L), tolerance); | |
353 | BOOST_CHECK_CLOSE_FRACTION(pdf(as_m11, 0.5), static_cast<RealType>(0.36755259694786136634088433220864629426492432024443L), tolerance); | |
354 | BOOST_CHECK_CLOSE_FRACTION(pdf(as_m11, 0.95), static_cast<RealType>(1.0194074882503562519812229448639426942621591013381L), 2 * tolerance); // Less accurate. | |
355 | ||
356 | BOOST_CHECK_CLOSE_FRACTION(cdf(as_m11, 0.05), static_cast<RealType>(0.51592213323666034437274347433261364289389772737836L), tolerance); | |
357 | BOOST_CHECK_CLOSE_FRACTION(cdf(as_m11, 0.5), static_cast<RealType>(0.66666666666666666666666666666666666666666666666667L), 2 * tolerance); | |
358 | BOOST_CHECK_CLOSE_FRACTION(cdf(as_m11, 0.95), static_cast<RealType>(0.89891737589574013042121018491729701360300248368629L), tolerance); // Not less accurate. | |
359 | ||
360 | // Quantile | |
361 | BOOST_CHECK_CLOSE_FRACTION(quantile(as_m11, static_cast<RealType>(1) / 3), -static_cast<RealType>(0.5L), 2 * tolerance); // p = 1/3 x = -0.5 | |
362 | BOOST_CHECK_SMALL(quantile(as_m11, static_cast<RealType>(0.5L)), 2 * tolerance); // p = 0.5, x = 0 | |
363 | BOOST_CHECK_CLOSE_FRACTION(quantile(as_m11, static_cast<RealType>(2) / 3), +static_cast<RealType>(0.5L), 4 * tolerance); // p = 2/3, x = +0.5 | |
364 | ||
365 | // Loop back tests. | |
366 | test_spot( | |
367 | static_cast<RealType>(0), // lo or a | |
368 | static_cast<RealType>(1), // hi or b | |
369 | static_cast<RealType>(0.05), // Random variate x | |
370 | static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), // Probability of result (CDF of arcsine), P | |
371 | static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), // Complement of CDF Q = 1 - P | |
372 | tolerance); // Test tolerance. | |
373 | ||
374 | test_spot( | |
375 | static_cast<RealType>(0), // lo or a | |
376 | static_cast<RealType>(1), // hi or b | |
377 | static_cast<RealType>(0.95), // Random variate x | |
378 | static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), // Probability of result (CDF of arcsine), P | |
379 | static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), // Complement of CDF Q = 1 - P | |
f67539c2 | 380 | tolerance * 4); // Test tolerance (slightly increased compared to x < 0.5 above). |
7c673cae FG |
381 | |
382 | test_spot( | |
383 | static_cast<RealType>(0), // lo or a | |
384 | static_cast<RealType>(1), // hi or b | |
385 | static_cast<RealType>(static_cast<RealType>(0.5L)), // Random variate x | |
386 | static_cast<RealType>(static_cast<RealType>(0.5L)), // Probability of result (CDF of arcsine), P | |
387 | static_cast<RealType>(static_cast<RealType>(0.5L)), // Complement of CDF Q = 1 - P | |
388 | tolerance * 4); // Test tolerance. | |
389 | ||
390 | // Arcsine(-2, -1) xmin = -2, x_max = -1 - Asymmetric both negative. | |
391 | arcsine_distribution<RealType> as_m2m1(-2, -1); | |
392 | ||
393 | BOOST_CHECK_EQUAL(as_m2m1.x_min(), -2); // | |
394 | BOOST_CHECK_EQUAL(as_m2m1.x_max(), -1); | |
395 | BOOST_CHECK_EQUAL(mean(as_m2m1), -1.5); // 1 / (1 + 1) = 1/2 exactly. | |
396 | BOOST_CHECK_EQUAL(median(as_m2m1), -1.5); // 1 / (1 + 1) = 1/2 exactly. | |
397 | BOOST_CHECK_EQUAL(variance(as_m2m1), 0.125); | |
398 | BOOST_CHECK_EQUAL(skewness(as_m2m1), 0); // | |
399 | BOOST_CHECK_EQUAL(kurtosis_excess(as_m2m1), -1.5); // 3/2 | |
400 | ||
401 | BOOST_CHECK_CLOSE_FRACTION(pdf(as_m2m1, -1.95), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), 4 * tolerance); | |
402 | BOOST_CHECK_CLOSE_FRACTION(pdf(as_m2m1, -1.5), static_cast<RealType>(0.63661977236758134307553505349005744813783858296183L), tolerance); | |
403 | BOOST_CHECK_CLOSE_FRACTION(pdf(as_m2m1, -1.05), static_cast<RealType>(1.4605059227421865250256574657088244053723856445614L), 4 * tolerance); // Less accurate. | |
404 | ||
405 | BOOST_CHECK_CLOSE_FRACTION(cdf(as_m2m1, -1.05), static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L), tolerance); | |
406 | BOOST_CHECK_CLOSE_FRACTION(cdf(as_m2m1, -1.5), static_cast<RealType>(0.5L), tolerance); | |
407 | BOOST_CHECK_CLOSE_FRACTION(cdf(as_m2m1, -1.95), static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L), 8 * tolerance); // Not much less accurate. | |
408 | ||
409 | // Quantile | |
410 | BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L)), -static_cast<RealType>(1.05L), 2 * tolerance); // | |
411 | BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.5L)), -static_cast<RealType>(1.5L), 2 * tolerance); // | |
412 | BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L)), -static_cast<RealType>(1.95L), 4 * tolerance); // | |
413 | ||
414 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(as_m2m1, static_cast<RealType>(0.14356629312870627075094188477505571882161519989741L))), -static_cast<RealType>(1.05L), 2 * tolerance); // | |
415 | BOOST_CHECK_CLOSE_FRACTION(quantile(as_m2m1, static_cast<RealType>(0.5L)), -static_cast<RealType>(1.5L), 2 * tolerance); // | |
416 | BOOST_CHECK_CLOSE_FRACTION(quantile(complement(as_m2m1, static_cast<RealType>(0.85643370687129372924905811522494428117838480010259L))), -static_cast<RealType>(1.95L), 4 * tolerance); | |
417 | ||
418 | // Tests that should throw: | |
419 | BOOST_MATH_CHECK_THROW(mode(arcsine_distribution<RealType>(static_cast<RealType>(0), static_cast<RealType>(1))), std::domain_error); | |
420 | // mode is undefined, and must throw domain_error! | |
421 | ||
422 | ||
423 | BOOST_MATH_CHECK_THROW( // For various bad arguments. | |
424 | pdf( | |
425 | arcsine_distribution<RealType>(static_cast<RealType>(+1), static_cast<RealType>(-1)), // min_x > max_x | |
426 | static_cast<RealType>(1)), std::domain_error); | |
427 | ||
428 | BOOST_MATH_CHECK_THROW( | |
429 | pdf( | |
430 | arcsine_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(0)), // bad constructor parameters. | |
431 | static_cast<RealType>(1)), std::domain_error); | |
432 | ||
433 | BOOST_MATH_CHECK_THROW( | |
434 | pdf( | |
435 | arcsine_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(-1)), // bad constructor parameters. | |
436 | static_cast<RealType>(1)), std::domain_error); | |
437 | ||
438 | BOOST_MATH_CHECK_THROW( | |
439 | pdf( | |
440 | arcsine_distribution<RealType>(static_cast<RealType>(1), static_cast<RealType>(1)), // equal constructor parameters. | |
441 | static_cast<RealType>(-1)), std::domain_error); | |
442 | ||
443 | BOOST_MATH_CHECK_THROW( | |
444 | pdf( | |
445 | arcsine_distribution<RealType>(static_cast<RealType>(0), static_cast<RealType>(1)), // bad x > 1. | |
446 | static_cast<RealType>(999)), std::domain_error); | |
447 | ||
448 | // Checks on things that are errors. | |
449 | ||
450 | // Construction with 'bad' parameters. | |
451 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(+1, -1), std::domain_error); // max < min. | |
452 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(+1, 0), std::domain_error); // max < min. | |
453 | ||
454 | arcsine_distribution<> dist; | |
455 | BOOST_MATH_CHECK_THROW(pdf(dist, -1), std::domain_error); | |
456 | BOOST_MATH_CHECK_THROW(cdf(dist, -1), std::domain_error); | |
457 | BOOST_MATH_CHECK_THROW(cdf(complement(dist, -1)), std::domain_error); | |
458 | BOOST_MATH_CHECK_THROW(quantile(dist, -1), std::domain_error); | |
459 | BOOST_MATH_CHECK_THROW(quantile(complement(dist, -1)), std::domain_error); | |
460 | BOOST_MATH_CHECK_THROW(quantile(dist, -1), std::domain_error); | |
461 | BOOST_MATH_CHECK_THROW(quantile(complement(dist, -1)), std::domain_error); | |
462 | ||
f67539c2 | 463 | // Various combinations of bad constructor and member function parameters. |
7c673cae FG |
464 | BOOST_MATH_CHECK_THROW(pdf(boost::math::arcsine_distribution<RealType>(0, 1), -1), std::domain_error); |
465 | BOOST_MATH_CHECK_THROW(pdf(boost::math::arcsine_distribution<RealType>(-1, 1), +2), std::domain_error); | |
466 | BOOST_MATH_CHECK_THROW(quantile(boost::math::arcsine_distribution<RealType>(1, 1), -1), std::domain_error); | |
467 | BOOST_MATH_CHECK_THROW(quantile(boost::math::arcsine_distribution<RealType>(1, 1), 2), std::domain_error); | |
468 | ||
469 | // No longer allow any parameter to be NaN or inf, so all these tests should throw. | |
470 | if (std::numeric_limits<RealType>::has_quiet_NaN) | |
471 | { | |
472 | // Attempt to construct from non-finite parameters should throw. | |
473 | RealType nan = std::numeric_limits<RealType>::quiet_NaN(); | |
474 | #ifndef BOOST_NO_EXCEPTIONS | |
475 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(nan), std::domain_error); | |
476 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(1, nan), std::domain_error); | |
477 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(nan, 1), std::domain_error); | |
478 | #else | |
479 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(nan), std::domain_error); | |
480 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(1, nan), std::domain_error); | |
481 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(nan, 1), std::domain_error); | |
482 | #endif | |
483 | ||
484 | arcsine_distribution<RealType> w(RealType(-1), RealType(+1)); | |
485 | // NaN parameters to member functions should throw. | |
486 | BOOST_MATH_CHECK_THROW(pdf(w, +nan), std::domain_error); // x = NaN | |
487 | BOOST_MATH_CHECK_THROW(cdf(w, +nan), std::domain_error); // x = NaN | |
488 | BOOST_MATH_CHECK_THROW(cdf(complement(w, +nan)), std::domain_error); // x = + nan | |
489 | BOOST_MATH_CHECK_THROW(quantile(w, +nan), std::domain_error); // p = + nan | |
490 | BOOST_MATH_CHECK_THROW(quantile(complement(w, +nan)), std::domain_error); // p = + nan | |
491 | } // has_quiet_NaN | |
492 | ||
493 | if (std::numeric_limits<RealType>::has_infinity) | |
494 | { | |
495 | // Attempt to construct from non-finite should throw. | |
496 | RealType inf = std::numeric_limits<RealType>::infinity(); | |
497 | #ifndef BOOST_NO_EXCEPTIONS | |
498 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(inf), std::domain_error); | |
499 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(1, inf), std::domain_error); | |
500 | #else | |
501 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(inf), std::domain_error); | |
502 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(1, inf), std::domain_error); | |
503 | #endif | |
504 | // Infinite parameters to member functions should throw. | |
505 | arcsine_distribution<RealType> w(RealType(0), RealType(1)); | |
506 | #ifndef BOOST_NO_EXCEPTIONS | |
507 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(inf), std::domain_error); | |
508 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType> w(1, inf), std::domain_error); | |
509 | #else | |
510 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(inf), std::domain_error); | |
511 | BOOST_MATH_CHECK_THROW(arcsine_distribution<RealType>(1, inf), std::domain_error); | |
512 | #endif | |
513 | BOOST_MATH_CHECK_THROW(pdf(w, +inf), std::domain_error); // x = inf | |
514 | BOOST_MATH_CHECK_THROW(cdf(w, +inf), std::domain_error); // x = inf | |
515 | BOOST_MATH_CHECK_THROW(cdf(complement(w, +inf)), std::domain_error); // x = + inf | |
516 | BOOST_MATH_CHECK_THROW(quantile(w, +inf), std::domain_error); // p = + inf | |
517 | BOOST_MATH_CHECK_THROW(quantile(complement(w, +inf)), std::domain_error); // p = + inf | |
518 | } // has_infinity | |
519 | ||
520 | // Error handling checks: | |
521 | check_out_of_range<boost::math::arcsine_distribution<RealType> >(-1, +1); // (All) valid constructor parameter values. | |
522 | // and range and non-finite. | |
523 | ||
524 | test_ignore_policy(static_cast<RealType>(0)); | |
525 | ||
526 | } // template <class RealType>void test_spots(RealType) | |
527 | ||
528 | BOOST_AUTO_TEST_CASE(test_main) | |
529 | { | |
530 | BOOST_MATH_CONTROL_FP; | |
531 | ||
532 | // Check that can generate arcsine distribution using convenience method: | |
533 | using boost::math::arcsine; | |
534 | ||
535 | arcsine_distribution<> arcsine_01; // Using default RealType double. | |
536 | // Note: NOT arcsine01() - or compiler will assume a function. | |
537 | ||
538 | arcsine as; // Using typedef for default standard arcsine. | |
539 | ||
b32b8144 | 540 | // |
7c673cae FG |
541 | BOOST_CHECK_EQUAL(as.x_min(), 0); // |
542 | BOOST_CHECK_EQUAL(as.x_max(), 1); | |
543 | BOOST_CHECK_EQUAL(mean(as), 0.5); // 1 / (1 + 1) = 1/2 exactly. | |
544 | BOOST_CHECK_EQUAL(median(as), 0.5); // 1 / (1 + 1) = 1/2 exactly. | |
545 | BOOST_CHECK_EQUAL(variance(as), 0.125); //0.125 | |
546 | BOOST_CHECK_CLOSE_FRACTION(standard_deviation(as), one_div_root_two<double>() / 2, std::numeric_limits<double>::epsilon()); // 0.353553 | |
547 | BOOST_CHECK_EQUAL(skewness(as), 0); // | |
548 | BOOST_CHECK_EQUAL(kurtosis_excess(as), -1.5); // 3/2 | |
549 | BOOST_CHECK_EQUAL(support(as).first, 0); // | |
550 | BOOST_CHECK_EQUAL(range(as).first, 0); // | |
551 | BOOST_MATH_CHECK_THROW(mode(as), std::domain_error); // Two modes at x_min and x_max, so throw instead. | |
552 | ||
553 | // (Parameter value, arbitrarily zero, only communicates the floating point type). | |
554 | test_spots(0.0F); // Test float. | |
555 | test_spots(0.0); // Test double. | |
556 | #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | |
557 | test_spots(0.0L); // Test long double. | |
558 | #if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) | |
559 | test_spots(boost::math::concepts::real_concept(0.)); // Test real concept. | |
560 | #endif | |
561 | #endif | |
562 | /* */ | |
563 | } // BOOST_AUTO_TEST_CASE( test_main ) | |
564 | ||
565 | /* | |
566 | ||
567 | ||
568 | Microsoft Visual Studio Professional 2013 | |
569 | Version 12.0.30110.00 Update 1 | |
570 | ||
571 | 1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_arcsine.exe" | |
572 | 1> Running 1 test case... | |
573 | 1> Platform: Win32 | |
b32b8144 | 574 | 1> Compiler: Microsoft Visual C++ version 12.0 ???? MSVC says 2013 |
7c673cae FG |
575 | 1> STL : Dinkumware standard library version 610 |
576 | 1> Boost : 1.56.0 | |
577 | ||
578 | Sample Output is: | |
579 | ||
580 | 1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Debug\test_arcsine.exe" | |
581 | 1> Running 1 test case... | |
582 | 1> Platform: Win32 | |
583 | 1> Compiler: Microsoft Visual C++ version 12.0 | |
584 | 1> STL : Dinkumware standard library version 610 | |
585 | 1> Boost : 1.56.0 | |
586 | 1> tolerance = 2.38419e-007 | |
587 | 1> tolerance = 4.44089e-016 | |
588 | 1> tolerance = 4.44089e-016 | |
589 | 1> tolerance = 4.44089e-016 | |
590 | 1> | |
591 | 1> *** No errors detected | |
592 | ||
593 | GCC 4.9.1 | |
594 | ||
595 | Running 1 test case... | |
596 | tolerance = 2.38419e-007 | |
597 | tolerance = 4.44089e-016 | |
598 | tolerance = 4.44089e-016 | |
599 | tolerance = 4.44089e-016 | |
600 | ||
601 | *** No errors detected | |
602 | ||
603 | RUN SUCCESSFUL (total time: 141ms) | |
604 | ||
605 | */ |