1 #ifndef STAN_MATH_PRIM_SCAL_ERR_CHECK_FINITE_HPP
2 #define STAN_MATH_PRIM_SCAL_ERR_CHECK_FINITE_HPP
3 
4 #include <stan/math/prim/scal/err/domain_error.hpp>
5 #include <stan/math/prim/scal/err/domain_error_vec.hpp>
6 #include <stan/math/prim/scal/meta/length.hpp>
7 #include <stan/math/prim/scal/meta/is_vector_like.hpp>
8 #include <stan/math/prim/scal/fun/value_of_rec.hpp>
9 #include <boost/math/special_functions/fpclassify.hpp>
10 
11 namespace stan {
12 namespace math {
13 
14 namespace internal {
15 template <typename T_y, bool is_vec>
16 struct finite {
checkstan::math::internal::finite17   static void check(const char* function, const char* name, const T_y& y) {
18     if (!(boost::math::isfinite)(value_of_rec(y)))
19       domain_error(function, name, y, "is ", ", but must be finite!");
20   }
21 };
22 
23 template <typename T_y>
24 struct finite<T_y, true> {
checkstan::math::internal::finite25   static void check(const char* function, const char* name, const T_y& y) {
26     using stan::length;
27     for (size_t n = 0; n < length(y); n++) {
28       if (!(boost::math::isfinite)(value_of_rec(stan::get(y, n))))
29         domain_error_vec(function, name, y, n, "is ", ", but must be finite!");
30     }
31   }
32 };
33 }  // namespace internal
34 
35 /**
36  * Check if <code>y</code> is finite.
37  *
38  * This function is vectorized and will check each element of
39  * <code>y</code>.
40  *
41  * @tparam T_y Type of y
42  *
43  * @param function Function name (for error messages)
44  * @param name Variable name (for error messages)
45  * @param y Variable to check
46  *
47  * @throw <code>domain_error</code> if y is infinity, -infinity, or
48  *   NaN.
49  */
50 template <typename T_y>
check_finite(const char * function,const char * name,const T_y & y)51 inline void check_finite(const char* function, const char* name, const T_y& y) {
52   internal::finite<T_y, is_vector_like<T_y>::value>::check(function, name, y);
53 }
54 }  // namespace math
55 }  // namespace stan
56 #endif
57