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>
check_probability(const char * function,RealType const & prob,RealType * result,const Policy & pol)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>
check_df(const char * function,RealType const & df,RealType * result,const Policy & pol)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>
check_df_gt0_to_inf(const char * function,RealType const & df,RealType * result,const Policy & pol)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>
check_scale(const char * function,RealType scale,RealType * result,const Policy & pol)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>
check_location(const char * function,RealType location,RealType * result,const Policy & pol)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>
check_x(const char * function,RealType x,RealType * result,const Policy & pol)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>
check_x_not_NaN(const char * function,RealType x,RealType * result,const Policy & pol)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>
check_x_gt0(const char * function,RealType x,RealType * result,const Policy & pol)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>
check_positive_x(const char * function,RealType x,RealType * result,const Policy & pol)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>
check_non_centrality(const char * function,RealType ncp,RealType * result,const Policy & pol)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>
check_finite(const char * function,RealType x,RealType * result,const Policy & pol)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