common_error_handling.hpp 6.5 KB

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