]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/math/test/test_out_of_range.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / math / test / test_out_of_range.hpp
1 // Copyright John Maddock 2012.
2
3 // Use, modification and distribution are subject to the
4 // Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
7
8 #ifndef BOOST_MATH_TEST_OUT_OF_RANGE_HPP
9 #define BOOST_MATH_TEST_OUT_OF_RANGE_HPP
10
11 #include <boost/math/special_functions/next.hpp>
12 #include <boost/test/test_tools.hpp>
13
14 /*` check_out_of_range functions check that bad parameters
15 passed to constructors and functions throw domain_error exceptions.
16
17 Usage is `check_out_of_range<DistributionType >(list-of-params);`
18 Where list-of-params is a list of *valid* parameters from which the distribution can be constructed
19 - ie the same number of args are passed to the function,
20 as are passed to the distribution constructor.
21
22 Checks:
23
24 * Infinity or NaN passed in place of each of the valid params.
25 * Infinity or NaN as a random variable.
26 * Out-of-range random variable passed to pdf and cdf (ie outside of "range(distro)").
27 * Out-of-range probability passed to quantile function and complement.
28
29 but does *not* check finite but out-of-range parameters to the constructor
30 because these are specific to each distribution.
31 */
32
33 #ifdef BOOST_MSVC
34 #pragma warning(push)
35 #pragma warning(disable:4127)
36 #endif
37
38 template <class Distro>
39 void check_support(const Distro& d)
40 { // Checks that
41 typedef typename Distro::value_type value_type;
42 if((boost::math::isfinite)(range(d).first) && (range(d).first != -boost::math::tools::max_value<value_type>()))
43 { // If possible, check that a random variable value just less than the bottom of the supported range throws domain errors.
44 value_type m = (range(d).first == 0) ? -boost::math::tools::min_value<value_type>() : boost::math::float_prior(range(d).first);
45 BOOST_ASSERT(m != range(d).first);
46 BOOST_ASSERT(m < range(d).first);
47 BOOST_MATH_CHECK_THROW(pdf(d, m), std::domain_error);
48 BOOST_MATH_CHECK_THROW(cdf(d, m), std::domain_error);
49 BOOST_MATH_CHECK_THROW(cdf(complement(d, m)), std::domain_error);
50 }
51 if((boost::math::isfinite)(range(d).second) && (range(d).second != boost::math::tools::max_value<value_type>()))
52 { // If possible, check that a random variable value just more than the top of the supported range throws domain errors.
53 value_type m = (range(d).second == 0) ? boost::math::tools::min_value<value_type>() : boost::math::float_next(range(d).second);
54 BOOST_ASSERT(m != range(d).first);
55 BOOST_ASSERT(m > range(d).first);
56 BOOST_MATH_CHECK_THROW(pdf(d, m), std::domain_error);
57 BOOST_MATH_CHECK_THROW(cdf(d, m), std::domain_error);
58 BOOST_MATH_CHECK_THROW(cdf(complement(d, m)), std::domain_error);
59 }
60 if(std::numeric_limits<value_type>::has_infinity)
61 { // Infinity is available,
62 if((boost::math::isfinite)(range(d).second))
63 { // and top of range doesn't include infinity,
64 // check that using infinity throws domain errors.
65 BOOST_MATH_CHECK_THROW(pdf(d, std::numeric_limits<value_type>::infinity()), std::domain_error);
66 BOOST_MATH_CHECK_THROW(cdf(d, std::numeric_limits<value_type>::infinity()), std::domain_error);
67 BOOST_MATH_CHECK_THROW(cdf(complement(d, std::numeric_limits<value_type>::infinity())), std::domain_error);
68 }
69 if((boost::math::isfinite)(range(d).first))
70 { // and bottom of range doesn't include infinity,
71 // check that using infinity throws domain_error exception.
72 BOOST_MATH_CHECK_THROW(pdf(d, -std::numeric_limits<value_type>::infinity()), std::domain_error);
73 BOOST_MATH_CHECK_THROW(cdf(d, -std::numeric_limits<value_type>::infinity()), std::domain_error);
74 BOOST_MATH_CHECK_THROW(cdf(complement(d, -std::numeric_limits<value_type>::infinity())), std::domain_error);
75 }
76 // Check that using infinity with quantiles always throws domain_error exception.
77 BOOST_MATH_CHECK_THROW(quantile(d, std::numeric_limits<value_type>::infinity()), std::domain_error);
78 BOOST_MATH_CHECK_THROW(quantile(d, -std::numeric_limits<value_type>::infinity()), std::domain_error);
79 BOOST_MATH_CHECK_THROW(quantile(complement(d, std::numeric_limits<value_type>::infinity())), std::domain_error);
80 BOOST_MATH_CHECK_THROW(quantile(complement(d, -std::numeric_limits<value_type>::infinity())), std::domain_error);
81 }
82 if(std::numeric_limits<value_type>::has_quiet_NaN)
83 { // NaN is available.
84 BOOST_MATH_CHECK_THROW(pdf(d, std::numeric_limits<value_type>::quiet_NaN()), std::domain_error);
85 BOOST_MATH_CHECK_THROW(cdf(d, std::numeric_limits<value_type>::quiet_NaN()), std::domain_error);
86 BOOST_MATH_CHECK_THROW(cdf(complement(d, std::numeric_limits<value_type>::quiet_NaN())), std::domain_error);
87 BOOST_MATH_CHECK_THROW(pdf(d, -std::numeric_limits<value_type>::quiet_NaN()), std::domain_error);
88 BOOST_MATH_CHECK_THROW(cdf(d, -std::numeric_limits<value_type>::quiet_NaN()), std::domain_error);
89 BOOST_MATH_CHECK_THROW(cdf(complement(d, -std::numeric_limits<value_type>::quiet_NaN())), std::domain_error);
90 BOOST_MATH_CHECK_THROW(quantile(d, std::numeric_limits<value_type>::quiet_NaN()), std::domain_error);
91 BOOST_MATH_CHECK_THROW(quantile(d, -std::numeric_limits<value_type>::quiet_NaN()), std::domain_error);
92 BOOST_MATH_CHECK_THROW(quantile(complement(d, std::numeric_limits<value_type>::quiet_NaN())), std::domain_error);
93 BOOST_MATH_CHECK_THROW(quantile(complement(d, -std::numeric_limits<value_type>::quiet_NaN())), std::domain_error);
94 }
95 // Check that using probability outside [0,1] with quantiles always throws domain_error exception.
96 BOOST_MATH_CHECK_THROW(quantile(d, -1), std::domain_error);
97 BOOST_MATH_CHECK_THROW(quantile(d, 2), std::domain_error);
98 BOOST_MATH_CHECK_THROW(quantile(complement(d, -1)), std::domain_error);
99 BOOST_MATH_CHECK_THROW(quantile(complement(d, 2)), std::domain_error);
100 }
101
102 // Four check_out_of_range versions for distributions with zero to 3 constructor parameters.
103
104 template <class Distro>
105 void check_out_of_range()
106 {
107 Distro d;
108 check_support(d);
109 }
110
111 template <class Distro>
112 void check_out_of_range(typename Distro::value_type p1)
113 {
114 typedef typename Distro::value_type value_type;
115 Distro d(p1);
116 check_support(d);
117 if(std::numeric_limits<value_type>::has_infinity)
118 {
119 BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::infinity()), range(d).first), std::domain_error);
120 // BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::infinity()), range(d).second), std::domain_error);
121 }
122 if(std::numeric_limits<value_type>::has_quiet_NaN)
123 {
124 BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::quiet_NaN()), range(d).first), std::domain_error);
125 }
126 }
127
128 template <class Distro>
129 void check_out_of_range(typename Distro::value_type p1, typename Distro::value_type p2)
130 {
131 typedef typename Distro::value_type value_type;
132 Distro d(p1, p2);
133 check_support(d);
134 if(std::numeric_limits<value_type>::has_infinity)
135 {
136 BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::infinity(), p2), range(d).first), std::domain_error);
137 BOOST_MATH_CHECK_THROW(pdf(Distro(p1, std::numeric_limits<value_type>::infinity()), range(d).first), std::domain_error);
138 }
139 if(std::numeric_limits<value_type>::has_quiet_NaN)
140 {
141 BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::quiet_NaN(), p2), range(d).first), std::domain_error);
142 BOOST_MATH_CHECK_THROW(pdf(Distro(p1, std::numeric_limits<value_type>::quiet_NaN()), range(d).first), std::domain_error);
143 }
144 }
145
146 template <class Distro>
147 void check_out_of_range(typename Distro::value_type p1, typename Distro::value_type p2, typename Distro::value_type p3)
148 {
149 typedef typename Distro::value_type value_type;
150 Distro d(p1, p2, p3);
151 check_support(d);
152 if(std::numeric_limits<value_type>::has_infinity)
153 {
154 BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::infinity(), p2, p3), range(d).first), std::domain_error);
155 BOOST_MATH_CHECK_THROW(pdf(Distro(p1, std::numeric_limits<value_type>::infinity(), p3), range(d).first), std::domain_error);
156 BOOST_MATH_CHECK_THROW(pdf(Distro(p1, p2, std::numeric_limits<value_type>::infinity()), range(d).first), std::domain_error);
157 }
158 if(std::numeric_limits<value_type>::has_quiet_NaN)
159 {
160 BOOST_MATH_CHECK_THROW(pdf(Distro(std::numeric_limits<value_type>::quiet_NaN(), p2, p3), range(d).first), std::domain_error);
161 BOOST_MATH_CHECK_THROW(pdf(Distro(p1, std::numeric_limits<value_type>::quiet_NaN(), p3), range(d).first), std::domain_error);
162 BOOST_MATH_CHECK_THROW(pdf(Distro(p1, p2, std::numeric_limits<value_type>::quiet_NaN()), range(d).first), std::domain_error);
163 }
164 }
165
166 #ifdef BOOST_MSVC
167 #pragma warning(pop)
168 #endif
169
170 #endif // BOOST_MATH_TEST_OUT_OF_RANGE_HPP