1 | // Copyright John Maddock 2006, 2007. |
2 | // Copyright Paul A. Bristow 2006, 2007, 2012. |
3 | |
4 | // Use, modification and distribution are subject to the |
5 | // Boost Software License, Version 1.0. |
6 | // (See accompanying file LICENSE_1_0.txt |
7 | // or copy at http://www.boost.org/LICENSE_1_0.txt) |
8 | |
9 | #ifndef BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP |
10 | #define BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP |
11 | |
12 | #include <boost/math/policies/error_handling.hpp> |
13 | #include <boost/math/special_functions/fpclassify.hpp> |
14 | // using boost::math::isfinite; |
15 | // using boost::math::isnan; |
16 | |
17 | #ifdef BOOST_MSVC |
18 | # pragma warning(push) |
19 | # pragma warning(disable: 4702) // unreachable code (return after domain_error throw). |
20 | #endif |
21 | |
22 | namespace boost{ namespace math{ namespace detail |
23 | { |
24 | |
25 | template <class RealType, class Policy> |
26 | inline bool check_probability(const char* function, RealType const& prob, RealType* result, const Policy& pol) |
27 | { |
28 | if((prob < 0) || (prob > 1) || !(boost::math::isfinite)(prob)) |
29 | { |
30 | *result = policies::raise_domain_error<RealType>( |
31 | function, |
32 | "Probability argument is %1%, but must be >= 0 and <= 1 !" , prob, pol); |
33 | return false; |
34 | } |
35 | return true; |
36 | } |
37 | |
38 | template <class RealType, class Policy> |
39 | inline bool check_df(const char* function, RealType const& df, RealType* result, const Policy& pol) |
40 | { // df > 0 but NOT +infinity allowed. |
41 | if((df <= 0) || !(boost::math::isfinite)(df)) |
42 | { |
43 | *result = policies::raise_domain_error<RealType>( |
44 | function, |
45 | "Degrees of freedom argument is %1%, but must be > 0 !" , df, pol); |
46 | return false; |
47 | } |
48 | return true; |
49 | } |
50 | |
51 | template <class RealType, class Policy> |
52 | inline bool check_df_gt0_to_inf(const char* function, RealType const& df, RealType* result, const Policy& pol) |
53 | { // df > 0 or +infinity are allowed. |
54 | if( (df <= 0) || (boost::math::isnan)(df) ) |
55 | { // is bad df <= 0 or NaN or -infinity. |
56 | *result = policies::raise_domain_error<RealType>( |
57 | function, |
58 | "Degrees of freedom argument is %1%, but must be > 0 !" , df, pol); |
59 | return false; |
60 | } |
61 | return true; |
62 | } // check_df_gt0_to_inf |
63 | |
64 | |
65 | template <class RealType, class Policy> |
66 | inline bool check_scale( |
67 | const char* function, |
68 | RealType scale, |
69 | RealType* result, |
70 | const Policy& pol) |
71 | { |
72 | if((scale <= 0) || !(boost::math::isfinite)(scale)) |
73 | { // Assume scale == 0 is NOT valid for any distribution. |
74 | *result = policies::raise_domain_error<RealType>( |
75 | function, |
76 | "Scale parameter is %1%, but must be > 0 !" , scale, pol); |
77 | return false; |
78 | } |
79 | return true; |
80 | } |
81 | |
82 | template <class RealType, class Policy> |
83 | inline bool check_location( |
84 | const char* function, |
85 | RealType location, |
86 | RealType* result, |
87 | const Policy& pol) |
88 | { |
89 | if(!(boost::math::isfinite)(location)) |
90 | { |
91 | *result = policies::raise_domain_error<RealType>( |
92 | function, |
93 | "Location parameter is %1%, but must be finite!" , location, pol); |
94 | return false; |
95 | } |
96 | return true; |
97 | } |
98 | |
99 | template <class RealType, class Policy> |
100 | inline bool check_x( |
101 | const char* function, |
102 | RealType x, |
103 | RealType* result, |
104 | const Policy& pol) |
105 | { |
106 | // Note that this test catches both infinity and NaN. |
107 | // Some distributions permit x to be infinite, so these must be tested 1st and return, |
108 | // leaving this test to catch any NaNs. |
109 | // See Normal, Logistic, Laplace and Cauchy for example. |
110 | if(!(boost::math::isfinite)(x)) |
111 | { |
112 | *result = policies::raise_domain_error<RealType>( |
113 | function, |
114 | "Random variate x is %1%, but must be finite!" , x, pol); |
115 | return false; |
116 | } |
117 | return true; |
118 | } // bool check_x |
119 | |
120 | template <class RealType, class Policy> |
121 | inline bool check_x_not_NaN( |
122 | const char* function, |
123 | RealType x, |
124 | RealType* result, |
125 | const Policy& pol) |
126 | { |
127 | // Note that this test catches only NaN. |
128 | // Some distributions permit x to be infinite, leaving this test to catch any NaNs. |
129 | // See Normal, Logistic, Laplace and Cauchy for example. |
130 | if ((boost::math::isnan)(x)) |
131 | { |
132 | *result = policies::raise_domain_error<RealType>( |
133 | function, |
134 | "Random variate x is %1%, but must be finite or + or - infinity!" , x, pol); |
135 | return false; |
136 | } |
137 | return true; |
138 | } // bool check_x_not_NaN |
139 | |
140 | template <class RealType, class Policy> |
141 | inline bool check_x_gt0( |
142 | const char* function, |
143 | RealType x, |
144 | RealType* result, |
145 | const Policy& pol) |
146 | { |
147 | if(x <= 0) |
148 | { |
149 | *result = policies::raise_domain_error<RealType>( |
150 | function, |
151 | "Random variate x is %1%, but must be > 0!" , x, pol); |
152 | return false; |
153 | } |
154 | |
155 | return true; |
156 | // Note that this test catches both infinity and NaN. |
157 | // Some special cases permit x to be infinite, so these must be tested 1st, |
158 | // leaving this test to catch any NaNs. See Normal and cauchy for example. |
159 | } // bool check_x_gt0 |
160 | |
161 | template <class RealType, class Policy> |
162 | inline bool check_positive_x( |
163 | const char* function, |
164 | RealType x, |
165 | RealType* result, |
166 | const Policy& pol) |
167 | { |
168 | if(!(boost::math::isfinite)(x) || (x < 0)) |
169 | { |
170 | *result = policies::raise_domain_error<RealType>( |
171 | function, |
172 | "Random variate x is %1%, but must be finite and >= 0!" , x, pol); |
173 | return false; |
174 | } |
175 | return true; |
176 | // Note that this test catches both infinity and NaN. |
177 | // Some special cases permit x to be infinite, so these must be tested 1st, |
178 | // leaving this test to catch any NaNs. see Normal and cauchy for example. |
179 | } |
180 | |
181 | template <class RealType, class Policy> |
182 | inline bool check_non_centrality( |
183 | const char* function, |
184 | RealType ncp, |
185 | RealType* result, |
186 | const Policy& pol) |
187 | { |
188 | if((ncp < 0) || !(boost::math::isfinite)(ncp)) |
189 | { // Assume scale == 0 is NOT valid for any distribution. |
190 | *result = policies::raise_domain_error<RealType>( |
191 | function, |
192 | "Non centrality parameter is %1%, but must be > 0 !" , ncp, pol); |
193 | return false; |
194 | } |
195 | return true; |
196 | } |
197 | |
198 | template <class RealType, class Policy> |
199 | inline bool check_finite( |
200 | const char* function, |
201 | RealType x, |
202 | RealType* result, |
203 | const Policy& pol) |
204 | { |
205 | if(!(boost::math::isfinite)(x)) |
206 | { // Assume scale == 0 is NOT valid for any distribution. |
207 | *result = policies::raise_domain_error<RealType>( |
208 | function, |
209 | "Parameter is %1%, but must be finite !" , x, pol); |
210 | return false; |
211 | } |
212 | return true; |
213 | } |
214 | |
215 | } // namespace detail |
216 | } // namespace math |
217 | } // namespace boost |
218 | |
219 | #ifdef BOOST_MSVC |
220 | # pragma warning(pop) |
221 | #endif |
222 | |
223 | #endif // BOOST_MATH_DISTRIBUTIONS_COMMON_ERROR_HANDLING_HPP |
224 | |