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