]>
Commit | Line | Data |
---|---|---|
20effc67 TL |
1 | // Copyright Evan Miller 2020 |
2 | // Use, modification and distribution are subject to the | |
3 | // Boost Software License, Version 1.0. | |
4 | // (See accompanying file LICENSE_1_0.txt | |
5 | // or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | #include <pch_light.hpp> | |
8 | #include <boost/math/concepts/real_concept.hpp> | |
9 | ||
10 | #define BOOST_TEST_MAIN | |
11 | #include <boost/test/unit_test.hpp> // for test_main | |
12 | #include <boost/test/tools/floating_point_comparison.hpp> // for BOOST_CHECK_CLOSE | |
13 | #include <boost/math/distributions/kolmogorov_smirnov.hpp> | |
14 | #include <boost/math/quadrature/exp_sinh.hpp> | |
15 | ||
16 | template <typename RealType> // Any floating-point type RealType. | |
17 | void test_spots(RealType) | |
18 | { | |
19 | using namespace boost::math; | |
20 | // Test quantiles, CDFs, and complements | |
21 | RealType eps = tools::epsilon<RealType>(); | |
22 | RealType tol = tools::epsilon<RealType>() * 25; | |
23 | for (int n=10; n<100; n += 10) { | |
24 | kolmogorov_smirnov_distribution<RealType> dist(n); | |
25 | for (int i=0; i<1000; i++) { | |
26 | RealType p = 1.0 * (i+1) / 1001; | |
27 | RealType crit1 = quantile(dist, 1 - p); | |
28 | RealType crit2 = quantile(complement(dist, p)); | |
29 | RealType p1 = cdf(dist, crit1); | |
30 | BOOST_CHECK_CLOSE_FRACTION(crit1, crit2, tol); | |
31 | BOOST_CHECK_CLOSE_FRACTION(1 - p, p1, tol); | |
32 | } | |
33 | ||
34 | for (int i=0; i<1000; i++) { | |
35 | RealType x = 1.0 * (i+1) / 1001; | |
36 | RealType p = cdf(dist, x); | |
37 | RealType p1 = cdf(complement(dist, x)); | |
38 | RealType x1; | |
39 | if (p < 0.5) | |
40 | x1 = quantile(dist, p); | |
41 | else | |
42 | x1 = quantile(complement(dist, p1)); | |
43 | if (p > tol && p1 > tol) // skip the extreme tails | |
44 | BOOST_CHECK_CLOSE_FRACTION(x, x1, tol); | |
45 | } | |
46 | } | |
47 | ||
48 | kolmogorov_smirnov_distribution<RealType> dist(100); | |
49 | ||
50 | // Basics | |
51 | BOOST_CHECK_THROW(pdf(dist, RealType(-1.0)), std::domain_error); | |
52 | BOOST_CHECK_THROW(cdf(dist, RealType(-1.0)), std::domain_error); | |
53 | BOOST_CHECK_THROW(quantile(dist, RealType(-1.0)), std::domain_error); | |
54 | BOOST_CHECK_THROW(quantile(dist, RealType(2.0)), std::domain_error); | |
55 | ||
56 | // Confirm mode is at least a local minimum | |
57 | RealType mode = boost::math::mode(dist); | |
58 | ||
59 | using std::sqrt; | |
60 | BOOST_TEST_CHECK(pdf(dist, mode) >= pdf(dist, RealType(mode - sqrt(eps)))); | |
61 | BOOST_TEST_CHECK(pdf(dist, mode) >= pdf(dist, RealType(mode + sqrt(eps)))); | |
62 | ||
63 | // Test the moments - each one integrates the entire distribution | |
64 | quadrature::exp_sinh<RealType> integrator; | |
65 | ||
66 | auto f_one = [&, dist](RealType t) { return pdf(dist, t); }; | |
67 | BOOST_CHECK_CLOSE_FRACTION(integrator.integrate(f_one, eps), RealType(1), tol); | |
68 | ||
69 | RealType mean = boost::math::mean(dist); | |
70 | auto f_mean = [&, dist](RealType t) { return pdf(dist, t) * t; }; | |
71 | BOOST_CHECK_CLOSE_FRACTION(integrator.integrate(f_mean, eps), mean, tol); | |
72 | ||
73 | RealType var = variance(dist); | |
74 | auto f_var = [&, dist, mean](RealType t) { return pdf(dist, t) * (t - mean) * (t - mean); }; | |
75 | BOOST_CHECK_CLOSE_FRACTION(integrator.integrate(f_var, eps), var, tol); | |
76 | ||
77 | RealType skew = skewness(dist); | |
78 | auto f_skew = [&, dist, mean, var](RealType t) { return pdf(dist, t) | |
79 | * (t - mean) * (t - mean) * (t - mean) / var / sqrt(var); }; | |
80 | BOOST_CHECK_CLOSE_FRACTION(integrator.integrate(f_skew, eps), skew, 10*tol); | |
81 | ||
82 | RealType kurt = kurtosis(dist); | |
83 | auto f_kurt= [&, dist, mean, var](RealType t) { return pdf(dist, t) | |
84 | * (t - mean) * (t - mean) * (t - mean) * (t - mean) / var / var; }; | |
85 | BOOST_CHECK_CLOSE_FRACTION(integrator.integrate(f_kurt, eps), kurt, 5*tol); | |
86 | ||
87 | BOOST_CHECK_CLOSE_FRACTION(kurt, kurtosis_excess(dist) + 3, eps); | |
88 | } | |
89 | ||
90 | BOOST_AUTO_TEST_CASE( test_main ) | |
91 | { | |
92 | BOOST_MATH_CONTROL_FP; | |
93 | ||
94 | // (Parameter value, arbitrarily zero, only communicates the floating point type). | |
95 | test_spots(0.0F); // Test float. | |
96 | test_spots(0.0); // Test double. | |
97 | #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS | |
98 | test_spots(0.0L); // Test long double. | |
99 | #if !defined(BOOST_MATH_NO_REAL_CONCEPT_TESTS) | |
100 | test_spots(boost::math::concepts::real_concept(0.)); // Test real concept. | |
101 | #endif | |
102 | #endif | |
103 | } |