From 9ab06f1ccfc5575a88d80dc23e5bad33af3bdae7 Mon Sep 17 00:00:00 2001 From: Peter Wicks Stringfield Date: Fri, 13 Mar 2020 15:01:15 -0500 Subject: [PATCH 1/5] Elementwise scalar error checks for deeply nested containers. Implement is_nonnegative and is_positive_finite. Fix error behavior for csr_u_to_z with out of range indices. Fix check_positive at 0. 0 is not positive. --- RELEASE-NOTES.txt | 10 +++ stan/math/prim/err/check_finite.hpp | 74 ++----------------- stan/math/prim/err/check_nonnegative.hpp | 38 +--------- stan/math/prim/err/check_not_nan.hpp | 34 +-------- stan/math/prim/err/check_positive.hpp | 39 +--------- stan/math/prim/err/check_positive_finite.hpp | 13 ++-- stan/math/prim/err/is_nonnegative.hpp | 24 ++++++ stan/math/prim/err/is_not_nan.hpp | 17 ++--- stan/math/prim/err/is_positive.hpp | 14 +--- stan/math/prim/err/is_positive_finite.hpp | 25 +++++++ stan/math/prim/err/is_scal_finite.hpp | 16 +--- stan/math/prim/fun/csr_u_to_z.hpp | 6 +- test/unit/math/prim/err/check_finite_test.cpp | 12 +++ .../math/prim/err/check_nonnegative_test.cpp | 25 +++++-- .../unit/math/prim/err/check_not_nan_test.cpp | 12 +++ .../math/prim/err/check_pos_definite_test.cpp | 17 +---- .../prim/err/check_pos_semidefinite_test.cpp | 2 +- .../prim/err/check_positive_finite_test.cpp | 16 ++++ .../math/prim/err/check_positive_test.cpp | 40 +++++----- .../math/prim/err/is_nonnegative_test.cpp | 29 ++++++++ test/unit/math/prim/err/is_not_nan_test.cpp | 35 +++++---- .../math/prim/err/is_positive_finite_test.cpp | 31 ++++++++ test/unit/math/prim/err/is_positive_test.cpp | 29 ++++++-- .../math/prim/err/is_scal_finite_test.cpp | 37 ++++++---- test/unit/math/prim/fun/csr_u_to_z_test.cpp | 10 ++- .../prim/prob/neg_binomial_2_log_test.cpp | 2 +- .../math/prim/prob/neg_binomial_2_test.cpp | 2 +- .../rev/err/check_pos_semidefinite_test.cpp | 7 +- 28 files changed, 324 insertions(+), 292 deletions(-) create mode 100644 stan/math/prim/err/is_nonnegative.hpp create mode 100644 stan/math/prim/err/is_positive_finite.hpp create mode 100644 test/unit/math/prim/err/is_nonnegative_test.cpp create mode 100644 test/unit/math/prim/err/is_positive_finite_test.cpp diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 2822468abbe..42cf4680f6d 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -4,6 +4,10 @@ Stan Math Library Release Notes v3.2.0 (pending) ====================================================================== +## Features + +New functions is_nonnegative and is_positive_finite to parallel check_nonnegative and check_positive_finite. They signal failure by returning false instead of by throwing std::domain_error. + ## Developer-aimed features [bob-carpenter](https://github.com/bob-carpenter) extended the scalar_return metaprograms to deal with complex numbers and added a real_return program @@ -11,6 +15,12 @@ and helper metaprograms for intermediate and return types. Miscellaneous doxygen documentation cleanup. +Functions check_not_nan, check_nonnegative, check_positive, check_finite, check_positive_finite, is_not_nan, is_nonnegative, is_positive, is_scal_finite, and is_positive_finite now operate on nested containers. + +Clearer error messages when csr_u_to_z is called with out of range indices. + +check_positive now throws domain error when given an unsigned 0. + ====================================================================== v3.1.0 (24 January 2020) ====================================================================== diff --git a/stan/math/prim/err/check_finite.hpp b/stan/math/prim/err/check_finite.hpp index eb59930b3c5..3f70fbc6755 100644 --- a/stan/math/prim/err/check_finite.hpp +++ b/stan/math/prim/err/check_finite.hpp @@ -1,87 +1,27 @@ #ifndef STAN_MATH_PRIM_ERR_CHECK_FINITE_HPP #define STAN_MATH_PRIM_ERR_CHECK_FINITE_HPP -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include namespace stan { namespace math { -namespace internal { -template -struct finite { - static void check(const char* function, const char* name, const T_y& y) { - if (!is_scal_finite(y)) { - throw_domain_error(function, name, y, "is ", ", but must be finite!"); - } - } -}; - -template -struct finite { - static void check(const char* function, const char* name, const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); n++) { - if (!is_scal_finite(stan::get(y, n))) { - throw_domain_error_vec(function, name, y, n, "is ", - ", but must be finite!"); - } - } - } -}; -} // namespace internal - /** * Check if y is finite. * This function is vectorized and will check each element of * y. - * @tparam T_y Type of y - * @param function Function name (for error messages) - * @param name Variable name (for error messages) - * @param y Variable to check + * @tparam T_y type of y + * @param function function name (for error messages) + * @param name variable name (for error messages) + * @param y variable to check * @throw domain_error if y is infinity, -infinity, or NaN */ template inline void check_finite(const char* function, const char* name, const T_y& y) { - internal::finite::value>::check(function, name, y); + auto is_good = [](const auto& y) { return std::isfinite(y); }; + elementwise_check(is_good, function, name, y, ", but must be finite!"); } -/** - * Return true is the specified matrix is finite. - * - * @tparam T type of elements in the matrix - * @tparam R number of rows, can be Eigen::Dynamic - * @tparam C number of columns, can be Eigen::Dynamic - * - * @param function name of function (for error messages) - * @param name variable name (for error messages) - * @param y matrix to test - * @return true if the matrix is finite - **/ -namespace internal { -template -struct finite, true> { - static void check(const char* function, const char* name, - const Eigen::Matrix& y) { - if (!value_of(y).allFinite()) { - for (int n = 0; n < y.size(); ++n) { - if (!std::isfinite(value_of_rec(y(n)))) { - throw_domain_error_vec(function, name, y, n, "is ", - ", but must be finite!"); - } - } - } - } -}; - -} // namespace internal } // namespace math } // namespace stan diff --git a/stan/math/prim/err/check_nonnegative.hpp b/stan/math/prim/err/check_nonnegative.hpp index 891667b3624..38f5de60d9c 100644 --- a/stan/math/prim/err/check_nonnegative.hpp +++ b/stan/math/prim/err/check_nonnegative.hpp @@ -1,42 +1,11 @@ #ifndef STAN_MATH_PRIM_ERR_CHECK_NONNEGATIVE_HPP #define STAN_MATH_PRIM_ERR_CHECK_NONNEGATIVE_HPP -#include -#include -#include -#include -#include -#include +#include namespace stan { namespace math { -namespace internal { -template -struct nonnegative { - static void check(const char* function, const char* name, const T_y& y) { - // have to use not is_unsigned. is_signed will be false for - // floating point types that have no unsigned versions. - if (!std::is_unsigned::value && !(y >= 0)) { - throw_domain_error(function, name, y, "is ", ", but must be >= 0!"); - } - } -}; - -template -struct nonnegative { - static void check(const char* function, const char* name, const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); n++) { - if (!std::is_unsigned::type>::value - && !(stan::get(y, n) >= 0)) { - throw_domain_error_vec(function, name, y, n, "is ", - ", but must be >= 0!"); - } - } - } -}; -} // namespace internal - /** * Check if y is non-negative. * This function is vectorized and will check each element of y. @@ -50,9 +19,10 @@ struct nonnegative { template inline void check_nonnegative(const char* function, const char* name, const T_y& y) { - internal::nonnegative::value>::check(function, name, - y); + auto is_good = [](const auto& y) { return y >= 0; }; + elementwise_check(is_good, function, name, y, ", but must be >= 0!"); } + } // namespace math } // namespace stan #endif diff --git a/stan/math/prim/err/check_not_nan.hpp b/stan/math/prim/err/check_not_nan.hpp index f44cadf5c14..92225ce8255 100644 --- a/stan/math/prim/err/check_not_nan.hpp +++ b/stan/math/prim/err/check_not_nan.hpp @@ -1,40 +1,11 @@ #ifndef STAN_MATH_PRIM_ERR_CHECK_NOT_NAN_HPP #define STAN_MATH_PRIM_ERR_CHECK_NOT_NAN_HPP -#include -#include -#include -#include -#include -#include -#include +#include namespace stan { namespace math { -namespace internal { -template -struct not_nan { - static void check(const char* function, const char* name, const T_y& y) { - if (is_nan(value_of_rec(y))) { - throw_domain_error(function, name, y, "is ", ", but must not be nan!"); - } - } -}; - -template -struct not_nan { - static void check(const char* function, const char* name, const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); n++) { - if (is_nan(value_of_rec(stan::get(y, n)))) { - throw_domain_error_vec(function, name, y, n, "is ", - ", but must not be nan!"); - } - } - } -}; -} // namespace internal - /** * Check if y is not NaN. * This function is vectorized and will check each element of @@ -49,7 +20,8 @@ struct not_nan { template inline void check_not_nan(const char* function, const char* name, const T_y& y) { - internal::not_nan::value>::check(function, name, y); + auto is_good = [](const auto& y) { return !std::isnan(y); }; + elementwise_check(is_good, function, name, y, ", but must not be nan!"); } } // namespace math diff --git a/stan/math/prim/err/check_positive.hpp b/stan/math/prim/err/check_positive.hpp index 6af8f48908a..ec02a6d6593 100644 --- a/stan/math/prim/err/check_positive.hpp +++ b/stan/math/prim/err/check_positive.hpp @@ -1,46 +1,14 @@ #ifndef STAN_MATH_PRIM_ERR_CHECK_POSITIVE_HPP #define STAN_MATH_PRIM_ERR_CHECK_POSITIVE_HPP -#include -#include -#include +#include #include -#include -#include -#include #include +#include namespace stan { namespace math { -namespace { - -template -struct positive { - static void check(const char* function, const char* name, const T_y& y) { - // have to use not is_unsigned. is_signed will be false - // floating point types that have no unsigned versions. - if (!std::is_unsigned::value && !(y > 0)) { - throw_domain_error(function, name, y, "is ", ", but must be > 0!"); - } - } -}; - -template -struct positive { - static void check(const char* function, const char* name, const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); n++) { - if (!std::is_unsigned::type>::value - && !(stan::get(y, n) > 0)) { - throw_domain_error_vec(function, name, y, n, "is ", - ", but must be > 0!"); - } - } - } -}; - -} // namespace - /** * Check if y is positive. * This function is vectorized and will check each element of @@ -55,7 +23,8 @@ struct positive { template inline void check_positive(const char* function, const char* name, const T_y& y) { - positive::value>::check(function, name, y); + auto is_good = [](const auto& y) { return y > 0; }; + elementwise_check(is_good, function, name, y, ", but must be > 0!"); } /** diff --git a/stan/math/prim/err/check_positive_finite.hpp b/stan/math/prim/err/check_positive_finite.hpp index 5ccd75384a2..61cc2095b42 100644 --- a/stan/math/prim/err/check_positive_finite.hpp +++ b/stan/math/prim/err/check_positive_finite.hpp @@ -1,9 +1,7 @@ #ifndef STAN_MATH_PRIM_ERR_CHECK_POSITIVE_FINITE_HPP #define STAN_MATH_PRIM_ERR_CHECK_POSITIVE_FINITE_HPP -#include -#include -#include +#include namespace stan { namespace math { @@ -17,15 +15,16 @@ namespace math { * @param name Variable name (for error messages) * @param y Variable to check * @throw domain_error if any element of y is not positive or - * if any element of y is NaN. + * if any element of y is NaN or infinity. */ + template inline void check_positive_finite(const char* function, const char* name, const T_y& y) { - check_positive(function, name, y); - check_finite(function, name, y); + auto is_good = [](const auto& y) { return y > 0 && std::isfinite(y); }; + elementwise_check(is_good, function, name, y, + ", but must be positive and finite!"); } - } // namespace math } // namespace stan #endif diff --git a/stan/math/prim/err/is_nonnegative.hpp b/stan/math/prim/err/is_nonnegative.hpp new file mode 100644 index 00000000000..447cef621dd --- /dev/null +++ b/stan/math/prim/err/is_nonnegative.hpp @@ -0,0 +1,24 @@ +#ifndef STAN_MATH_PRIM_ERR_IS_NONNEGATIVE_HPP +#define STAN_MATH_PRIM_ERR_IS_NONNEGATIVE_HPP + +#include + +namespace stan { +namespace math { + +/** + * Return true if y is nonnegative. + * This function is vectorized and will check each element of + * y. + * @tparam T_y Type of y + * @param y Variable to check + * @return true if every element of y is >=0. + */ +template +inline bool is_nonnegative(const T_y& y) { + auto is_good = [](const auto& y) { return y >= 0; }; + return elementwise_is(is_good, y); +} +} // namespace math +} // namespace stan +#endif diff --git a/stan/math/prim/err/is_not_nan.hpp b/stan/math/prim/err/is_not_nan.hpp index 4e94a02cd13..f870156720a 100644 --- a/stan/math/prim/err/is_not_nan.hpp +++ b/stan/math/prim/err/is_not_nan.hpp @@ -1,11 +1,8 @@ #ifndef STAN_MATH_PRIM_ERR_IS_NOT_NAN_HPP #define STAN_MATH_PRIM_ERR_IS_NOT_NAN_HPP -#include -#include +#include #include -#include -#include namespace stan { namespace math { @@ -15,18 +12,14 @@ namespace math { * This function is vectorized and will check each element of * y. If no element is NaN, this * function will return true. - * @tparam T_y Type of y - * @param y Variable to check + * @tparam T_y type of y + * @param y variable to check * @return true if no element of y is NaN */ template inline bool is_not_nan(const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); ++n) { - if (is_nan(value_of_rec(stan::get(y, n)))) { - return false; - } - } - return true; + auto is_good = [](const auto& y) { return !std::isnan(y); }; + return elementwise_is(is_good, y); } } // namespace math diff --git a/stan/math/prim/err/is_positive.hpp b/stan/math/prim/err/is_positive.hpp index b33b3cb758e..67f99417026 100644 --- a/stan/math/prim/err/is_positive.hpp +++ b/stan/math/prim/err/is_positive.hpp @@ -1,9 +1,7 @@ #ifndef STAN_MATH_PRIM_ERR_IS_POSITIVE_HPP #define STAN_MATH_PRIM_ERR_IS_POSITIVE_HPP -#include -#include -#include +#include namespace stan { namespace math { @@ -14,16 +12,12 @@ namespace math { * y. * @tparam T_y Type of y * @param y Variable to check - * @return true if vector contains only positive elements + * @return true if y contains only positive elements */ template inline bool is_positive(const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); ++n) { - if (!(stan::get(y, n) > 0)) { - return false; - } - } - return true; + auto is_good = [](const auto& y) { return y > 0; }; + return elementwise_is(is_good, y); } /** diff --git a/stan/math/prim/err/is_positive_finite.hpp b/stan/math/prim/err/is_positive_finite.hpp new file mode 100644 index 00000000000..440b375a253 --- /dev/null +++ b/stan/math/prim/err/is_positive_finite.hpp @@ -0,0 +1,25 @@ +#ifndef STAN_MATH_PRIM_ERR_IS_POSITIVE_FINITE_HPP +#define STAN_MATH_PRIM_ERR_IS_POSITIVE_FINITE_HPP + +#include + +namespace stan { +namespace math { + +/** + * Return true if y is positive and finite. + * This function is vectorized and will check each element of + * y. + * @tparam T_y Type of y + * @param y Variable to check + * @return true if every element of y is >0 and if no element of y + * is NaN or infinity. + */ +template +inline bool is_positive_finite(const T_y& y) { + auto is_good = [](const auto& y) { return y > 0 && std::isfinite(y); }; + return elementwise_is(is_good, y); +} +} // namespace math +} // namespace stan +#endif diff --git a/stan/math/prim/err/is_scal_finite.hpp b/stan/math/prim/err/is_scal_finite.hpp index bdebf549ab1..373a01c3fb5 100644 --- a/stan/math/prim/err/is_scal_finite.hpp +++ b/stan/math/prim/err/is_scal_finite.hpp @@ -1,11 +1,7 @@ #ifndef STAN_MATH_PRIM_ERR_IS_SCAL_FINITE_HPP #define STAN_MATH_PRIM_ERR_IS_SCAL_FINITE_HPP -#include -#include -#include -#include -#include +#include namespace stan { namespace math { @@ -16,16 +12,12 @@ namespace math { * y. * @tparam T_y Type of y * @param y Variable to check - * @throw true if y is not infinity, -infinity, or NaN + * @return true if no element in y is infinity, -infinity, or NaN */ template inline bool is_scal_finite(const T_y& y) { - for (size_t n = 0; n < stan::math::size(y); ++n) { - if (!std::isfinite(value_of_rec(stan::get(y, n)))) { - return false; - } - } - return true; + auto is_good = [](const auto& y) { return std::isfinite(y); }; + return elementwise_is(is_good, y); } } // namespace math diff --git a/stan/math/prim/fun/csr_u_to_z.hpp b/stan/math/prim/fun/csr_u_to_z.hpp index 7a4411c2bef..a43fa4b4067 100644 --- a/stan/math/prim/fun/csr_u_to_z.hpp +++ b/stan/math/prim/fun/csr_u_to_z.hpp @@ -19,12 +19,12 @@ namespace math { * @param[in] u U vector. * @param[in] i Index into resulting z vector. * @return z[i] where z is conversion from u. - * @throw std::domain_error if u is zero length. + * @throw std::domain_error if u does not contain at least 2 elements. * @throw std::out_of_range if i is out of range. */ inline int csr_u_to_z(const std::vector& u, int i) { - check_positive("csr_u_to_z", "u.size()", u.size()); - check_range("csr_u_to_z", "i", u.size(), i + 1, "index out of range"); + check_greater("csr_u_to_z", "u.size()", u.size(), 1); + check_range("csr_u_to_z", "i", u.size() - 1, i + 1, "index out of range"); return u[i + 1] - u[i]; } diff --git a/test/unit/math/prim/err/check_finite_test.cpp b/test/unit/math/prim/err/check_finite_test.cpp index fe7f54926ec..d9e095d4979 100644 --- a/test/unit/math/prim/err/check_finite_test.cpp +++ b/test/unit/math/prim/err/check_finite_test.cpp @@ -124,3 +124,15 @@ TEST(ErrorHandlingScalar, CheckFinite_nan) { EXPECT_THROW(check_finite(function, "x", nan), std::domain_error); } + +TEST(ErrorHandlingScalar, CheckFiniteVectorization) { + const char* function = "check_finite"; + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 0); + EXPECT_NO_THROW( + check_finite(function, "m", std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = stan::math::INFTY; + EXPECT_THROW( + check_finite(function, "m", std::vector{m, m2, m}), + std::domain_error); +} diff --git a/test/unit/math/prim/err/check_nonnegative_test.cpp b/test/unit/math/prim/err/check_nonnegative_test.cpp index 86574a98ae2..32ae2566d42 100644 --- a/test/unit/math/prim/err/check_nonnegative_test.cpp +++ b/test/unit/math/prim/err/check_nonnegative_test.cpp @@ -5,10 +5,10 @@ #include using stan::math::check_nonnegative; +const char* function = "check_nonnegative"; TEST(ErrorHandlingArr, CheckNonnegativeVectorized) { int N = 5; - const char* function = "check_nonnegative"; std::vector x(N); x.assign(N, 0); @@ -35,7 +35,6 @@ TEST(ErrorHandlingArr, CheckNonnegativeVectorized) { TEST(ErrorHandlingArr, CheckNonnegativeVectorized_one_indexed_message) { int N = 5; - const char* function = "check_nonnegative"; std::vector x(N); std::string message; @@ -54,7 +53,6 @@ TEST(ErrorHandlingArr, CheckNonnegativeVectorized_one_indexed_message) { } TEST(ErrorHandlingArr, CheckNonnegative_nan) { - const char* function = "check_nonnegative"; double nan = std::numeric_limits::quiet_NaN(); std::vector x = {1, 2, 3}; @@ -67,7 +65,6 @@ TEST(ErrorHandlingArr, CheckNonnegative_nan) { } TEST(ErrorHandlingScalar, CheckNonnegative) { - const char* function = "check_nonnegative"; double x = 0; EXPECT_NO_THROW(check_nonnegative(function, "x", x)) @@ -91,8 +88,26 @@ TEST(ErrorHandlingScalar, CheckNonnegative) { } TEST(ErrorHandlingScalar, CheckNonnegative_nan) { - const char* function = "check_nonnegative"; double nan = std::numeric_limits::quiet_NaN(); EXPECT_THROW(check_nonnegative(function, "x", nan), std::domain_error); } + +TEST(ErrorHandlingScalar, CheckNonnegative_0) { + EXPECT_NO_THROW(check_nonnegative(function, "x", 0U)); + EXPECT_NO_THROW(check_nonnegative(function, "x", (size_t)0)); + EXPECT_NO_THROW(check_nonnegative(function, "x", 0.0)); + EXPECT_NO_THROW(check_nonnegative(function, "x", -0.0)); + EXPECT_NO_THROW(check_nonnegative(function, "x", 0)); +} + +TEST(ErrorHandlingScalar, CheckNonNegativeVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 0); + EXPECT_NO_THROW( + check_nonnegative(function, "m", std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = -1; + EXPECT_THROW( + check_nonnegative(function, "m", std::vector{m, m2, m}), + std::domain_error); +} diff --git a/test/unit/math/prim/err/check_not_nan_test.cpp b/test/unit/math/prim/err/check_not_nan_test.cpp index 09e74bae08b..f8dcdc8111c 100644 --- a/test/unit/math/prim/err/check_not_nan_test.cpp +++ b/test/unit/math/prim/err/check_not_nan_test.cpp @@ -83,3 +83,15 @@ TEST(ErrorHandlingScalar, CheckNotNan) { EXPECT_THROW(check_not_nan(function, "x", x), std::domain_error) << "check_not_nan should throw exception on NaN: " << x; } + +TEST(ErrorHandlingScalar, CheckNotNaNVectorization) { + const char* function = "check_not_nan"; + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 0); + EXPECT_NO_THROW( + check_not_nan(function, "m", std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = stan::math::NOT_A_NUMBER; + EXPECT_THROW( + check_not_nan(function, "m", std::vector{m, m2, m}), + std::domain_error); +} diff --git a/test/unit/math/prim/err/check_pos_definite_test.cpp b/test/unit/math/prim/err/check_pos_definite_test.cpp index 5ca5c66ceac..a2d652fcb97 100644 --- a/test/unit/math/prim/err/check_pos_definite_test.cpp +++ b/test/unit/math/prim/err/check_pos_definite_test.cpp @@ -143,7 +143,7 @@ TEST_F(ErrorHandlingMatrix, checkPosDefinite_nan) { y << nan; std::stringstream expected_msg; - expected_msg << "function: y[1] is nan, but must not be nan!"; + expected_msg << "function: y[row=1, col=1] is nan, but must not be nan!"; EXPECT_THROW_MSG(check_pos_definite(function, "y", y), std::domain_error, expected_msg.str()); @@ -163,20 +163,7 @@ TEST_F(ErrorHandlingMatrix, checkPosDefinite_nan) { y << 2, -1, 0, -1, 2, -1, 0, -1, 2; y(i, j) = nan; if (i >= j) { - // expected_msg.str(""); - // if (i == j) - // expected_msg << "function: y[" - // << j*y.cols() + i + 1 - // << "] is " << nan - // << ", but must not be nan!"; - // else - // expected_msg << "function: y is not symmetric. " - // << "y[" << j+1 << ", " << i+1 << "] = " << y(j, i) - // << ", but y[" << i+1 << ", " << j+1 << "] = " - // << y(i, j); - EXPECT_THROW(check_pos_definite(function, "y", y), - // , expected_msg.str()); - std::domain_error); + EXPECT_THROW(check_pos_definite(function, "y", y), std::domain_error); } } diff --git a/test/unit/math/prim/err/check_pos_semidefinite_test.cpp b/test/unit/math/prim/err/check_pos_semidefinite_test.cpp index 0554844f252..d5739b2984b 100644 --- a/test/unit/math/prim/err/check_pos_semidefinite_test.cpp +++ b/test/unit/math/prim/err/check_pos_semidefinite_test.cpp @@ -77,7 +77,7 @@ TEST_F(ErrorHandlingMatrix, checkPosSemidefinite_nan) { y << 2, -1, 0, -1, nan, -1, 0, -1, 2; EXPECT_THROW_MSG(check_pos_semidefinite(function, "y", y), std::domain_error, - "function: y[5] is nan, but must not be nan!"); + "function: y[row=2, col=2] is nan, but must not be nan!"); y << 2, -1, 0, -1, 2, nan, 0, nan, 2; EXPECT_THROW_MSG( diff --git a/test/unit/math/prim/err/check_positive_finite_test.cpp b/test/unit/math/prim/err/check_positive_finite_test.cpp index 4c02c5aade9..36c922bb75c 100644 --- a/test/unit/math/prim/err/check_positive_finite_test.cpp +++ b/test/unit/math/prim/err/check_positive_finite_test.cpp @@ -181,3 +181,19 @@ TEST(ErrorHandlingScalar, CheckPositiveFinite_nan) { EXPECT_THROW(check_positive_finite(function, "x", nan), std::domain_error); } + +TEST(ErrorHandlingScalar, CheckPositiveFiniteVectorization) { + const char* function = "check_positive_finite"; + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); + EXPECT_NO_THROW(check_positive_finite(function, "m", + std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = -1; + EXPECT_THROW(check_positive_finite(function, "m", + std::vector{m, m2, m}), + std::domain_error); + m2(1, 1) = stan::math::NOT_A_NUMBER; + EXPECT_THROW(check_positive_finite(function, "m", + std::vector{m, m2, m}), + std::domain_error); +} diff --git a/test/unit/math/prim/err/check_positive_test.cpp b/test/unit/math/prim/err/check_positive_test.cpp index 987f5b62a77..2ae0e369b8f 100644 --- a/test/unit/math/prim/err/check_positive_test.cpp +++ b/test/unit/math/prim/err/check_positive_test.cpp @@ -3,10 +3,10 @@ #include #include -TEST(ErrorHandlingArr, CheckPositive) { - using stan::math::check_positive; - const char* function = "check_positive"; +using stan::math::check_positive; +const char* function = "check_positive"; +TEST(ErrorHandlingArr, CheckPositive) { std::vector x = {1, 2, 3}; for (size_t i = 0; i < x.size(); i++) { @@ -15,9 +15,6 @@ TEST(ErrorHandlingArr, CheckPositive) { } TEST(ErrorHandlingArr, CheckPositive_nan) { - using stan::math::check_positive; - const char* function = "check_positive"; - double nan = std::numeric_limits::quiet_NaN(); std::vector x = {1, 2, 3}; @@ -30,9 +27,6 @@ TEST(ErrorHandlingArr, CheckPositive_nan) { } TEST(ErrorHandlingMat, CheckPositive) { - using stan::math::check_positive; - const char* function = "check_positive"; - Eigen::Matrix x_mat(3); x_mat << 1, 2, 3; for (int i = 0; i < x_mat.size(); i++) { @@ -44,9 +38,6 @@ TEST(ErrorHandlingMat, CheckPositive) { } TEST(ErrorHandlingMat, CheckPositive_nan) { - using stan::math::check_positive; - const char* function = "check_positive"; - double nan = std::numeric_limits::quiet_NaN(); Eigen::Matrix x_mat(3); @@ -59,17 +50,30 @@ TEST(ErrorHandlingMat, CheckPositive_nan) { } TEST(ErrorHandlingScalar, CheckPositive) { - using stan::math::check_positive; - const char* function = "check_positive"; - EXPECT_NO_THROW(check_positive(function, "x", 3.0)); } TEST(ErrorHandlingScalar, CheckPositive_nan) { - using stan::math::check_positive; - const char* function = "check_positive"; - double nan = std::numeric_limits::quiet_NaN(); EXPECT_THROW(check_positive(function, "x", nan), std::domain_error); } + +TEST(ErrorHandlingScalar, CheckPositive_0) { + EXPECT_THROW(check_positive(function, "x", 0u), std::domain_error); + EXPECT_THROW(check_positive(function, "x", (size_t)0), std::domain_error); + EXPECT_THROW(check_positive(function, "x", 0.0), std::domain_error); + EXPECT_THROW(check_positive(function, "x", -0.0), std::domain_error); + EXPECT_THROW(check_positive(function, "x", 0), std::domain_error); +} + +TEST(ErrorHandlingScalar, CheckPositiveVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); + EXPECT_NO_THROW( + check_positive(function, "m", std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = -1; + EXPECT_THROW( + check_positive(function, "m", std::vector{m, m2, m}), + std::domain_error); +} diff --git a/test/unit/math/prim/err/is_nonnegative_test.cpp b/test/unit/math/prim/err/is_nonnegative_test.cpp new file mode 100644 index 00000000000..c22664533b5 --- /dev/null +++ b/test/unit/math/prim/err/is_nonnegative_test.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include + +using stan::math::is_nonnegative; + +TEST(ErrorHandlingScalar, isNonnegative) { + EXPECT_FALSE(is_nonnegative(stan::math::NEGATIVE_INFTY)); + EXPECT_FALSE(is_nonnegative(-3.0)); + EXPECT_FALSE(is_nonnegative(-3)); + EXPECT_TRUE(is_nonnegative(-0.0)); + EXPECT_TRUE(is_nonnegative(0.0)); + EXPECT_TRUE(is_nonnegative(0u)); + EXPECT_TRUE(is_nonnegative((size_t)0)); + EXPECT_TRUE(is_nonnegative(0)); + EXPECT_TRUE(is_nonnegative(3.0)); + EXPECT_TRUE(is_nonnegative(3)); + EXPECT_TRUE(is_nonnegative(stan::math::INFTY)); + EXPECT_FALSE(is_nonnegative(stan::math::NOT_A_NUMBER)); +} + +TEST(ErrorHandlingScalar, isNonnegativeVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 0); + EXPECT_TRUE(is_nonnegative(std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = -0.5; + EXPECT_FALSE(is_nonnegative(std::vector{m, m2, m})); +} diff --git a/test/unit/math/prim/err/is_not_nan_test.cpp b/test/unit/math/prim/err/is_not_nan_test.cpp index f627300e022..2835f74c970 100644 --- a/test/unit/math/prim/err/is_not_nan_test.cpp +++ b/test/unit/math/prim/err/is_not_nan_test.cpp @@ -1,20 +1,29 @@ -#include #include -#include +#include +#include +#include using stan::math::is_not_nan; TEST(ErrorHandlingScalar, isNotNan) { - double x = 0; - - EXPECT_TRUE(is_not_nan(x)); - - x = std::numeric_limits::infinity(); - EXPECT_TRUE(is_not_nan(x)); - - x = -std::numeric_limits::infinity(); - EXPECT_TRUE(is_not_nan(x)); + EXPECT_TRUE(is_not_nan(stan::math::NEGATIVE_INFTY)); + EXPECT_TRUE(is_not_nan(-3.0)); + EXPECT_TRUE(is_not_nan(-3)); + EXPECT_TRUE(is_not_nan(-0.0)); + EXPECT_TRUE(is_not_nan(0.0)); + EXPECT_TRUE(is_not_nan(0u)); + EXPECT_TRUE(is_not_nan((size_t)0)); + EXPECT_TRUE(is_not_nan(0)); + EXPECT_TRUE(is_not_nan(3.0)); + EXPECT_TRUE(is_not_nan(3)); + EXPECT_TRUE(is_not_nan(stan::math::INFTY)); + EXPECT_FALSE(is_not_nan(stan::math::NOT_A_NUMBER)); +} - x = std::numeric_limits::quiet_NaN(); - EXPECT_FALSE(is_not_nan(x)); +TEST(ErrorHandlingScalar, isNotNanVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); + EXPECT_TRUE(is_not_nan(std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = stan::math::NOT_A_NUMBER; + EXPECT_FALSE(is_not_nan(std::vector{m, m2, m})); } diff --git a/test/unit/math/prim/err/is_positive_finite_test.cpp b/test/unit/math/prim/err/is_positive_finite_test.cpp new file mode 100644 index 00000000000..f947bf81740 --- /dev/null +++ b/test/unit/math/prim/err/is_positive_finite_test.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +using stan::math::is_positive_finite; + +TEST(ErrorHandlingScalar, isPositiveFinite) { + EXPECT_FALSE(is_positive_finite(stan::math::NEGATIVE_INFTY)); + EXPECT_FALSE(is_positive_finite(-3.0)); + EXPECT_FALSE(is_positive_finite(-3)); + EXPECT_FALSE(is_positive_finite(-0.0)); + EXPECT_FALSE(is_positive_finite(0.0)); + EXPECT_FALSE(is_positive_finite(0u)); + EXPECT_FALSE(is_positive_finite((size_t)0)); + EXPECT_FALSE(is_positive_finite(0)); + EXPECT_TRUE(is_positive_finite(3.0)); + EXPECT_TRUE(is_positive_finite(3)); + EXPECT_FALSE(is_positive_finite(stan::math::INFTY)); + EXPECT_FALSE(is_positive_finite(stan::math::NOT_A_NUMBER)); +} + +TEST(ErrorHandlingScalar, isPositiveFiniteVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); + EXPECT_TRUE(is_positive_finite(std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = -0.5; + EXPECT_FALSE(is_positive_finite(std::vector{m, m2, m})); + m2(1, 1) = stan::math::NOT_A_NUMBER; + EXPECT_FALSE(is_positive_finite(std::vector{m, m2, m})); +} diff --git a/test/unit/math/prim/err/is_positive_test.cpp b/test/unit/math/prim/err/is_positive_test.cpp index f5a023253d8..954638a7e94 100644 --- a/test/unit/math/prim/err/is_positive_test.cpp +++ b/test/unit/math/prim/err/is_positive_test.cpp @@ -1,14 +1,29 @@ -#include #include -#include +#include +#include +#include + +using stan::math::is_positive; TEST(ErrorHandlingScalar, isPositive) { - using stan::math::is_positive; + EXPECT_FALSE(is_positive(stan::math::NEGATIVE_INFTY)); + EXPECT_FALSE(is_positive(-3.0)); + EXPECT_FALSE(is_positive(-3)); + EXPECT_FALSE(is_positive(-0.0)); + EXPECT_FALSE(is_positive(0.0)); + EXPECT_FALSE(is_positive(0u)); + EXPECT_FALSE(is_positive((size_t)0)); + EXPECT_FALSE(is_positive(0)); EXPECT_TRUE(is_positive(3.0)); + EXPECT_TRUE(is_positive(3)); + EXPECT_TRUE(is_positive(stan::math::INFTY)); + EXPECT_FALSE(is_positive(stan::math::NOT_A_NUMBER)); } -TEST(ErrorHandlingScalar, isPositive_nan) { - using stan::math::is_positive; - double nan = std::numeric_limits::quiet_NaN(); - EXPECT_FALSE(is_positive(nan)); +TEST(ErrorHandlingScalar, isPositiveVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); + EXPECT_TRUE(is_positive(std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = -0.5; + EXPECT_FALSE(is_positive(std::vector{m, m2, m})); } diff --git a/test/unit/math/prim/err/is_scal_finite_test.cpp b/test/unit/math/prim/err/is_scal_finite_test.cpp index fd8596b5ef0..5dea24b9dc8 100644 --- a/test/unit/math/prim/err/is_scal_finite_test.cpp +++ b/test/unit/math/prim/err/is_scal_finite_test.cpp @@ -1,24 +1,29 @@ -#include #include -#include +#include +#include +#include using stan::math::is_scal_finite; TEST(ErrorHandlingScalar, isScalFinite) { - double x = 0; - EXPECT_TRUE(is_scal_finite(x)); - - x = std::numeric_limits::infinity(); - EXPECT_FALSE(is_scal_finite(x)); - - x = -std::numeric_limits::infinity(); - EXPECT_FALSE(is_scal_finite(x)); - - x = std::numeric_limits::quiet_NaN(); - EXPECT_FALSE(is_scal_finite(x)); + EXPECT_FALSE(is_scal_finite(stan::math::NEGATIVE_INFTY)); + EXPECT_TRUE(is_scal_finite(-3.0)); + EXPECT_TRUE(is_scal_finite(-3)); + EXPECT_TRUE(is_scal_finite(-0.0)); + EXPECT_TRUE(is_scal_finite(0.0)); + EXPECT_TRUE(is_scal_finite(0u)); + EXPECT_TRUE(is_scal_finite((size_t)0)); + EXPECT_TRUE(is_scal_finite(0)); + EXPECT_TRUE(is_scal_finite(3.0)); + EXPECT_TRUE(is_scal_finite(3)); + EXPECT_FALSE(is_scal_finite(stan::math::INFTY)); + EXPECT_FALSE(is_scal_finite(stan::math::NOT_A_NUMBER)); } -TEST(ErrorHandlingScalar, isScalFinite_nan) { - double nan = std::numeric_limits::quiet_NaN(); - EXPECT_FALSE(is_scal_finite(nan)); +TEST(ErrorHandlingScalar, isScalFiniteVectorization) { + Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); + EXPECT_TRUE(is_scal_finite(std::vector{m, m, m})); + Eigen::MatrixXd m2 = m; + m2(1, 1) = stan::math::NOT_A_NUMBER; + EXPECT_FALSE(is_scal_finite(std::vector{m, m2, m})); } diff --git a/test/unit/math/prim/fun/csr_u_to_z_test.cpp b/test/unit/math/prim/fun/csr_u_to_z_test.cpp index 5879f8918ad..2acfa81cdb3 100644 --- a/test/unit/math/prim/fun/csr_u_to_z_test.cpp +++ b/test/unit/math/prim/fun/csr_u_to_z_test.cpp @@ -7,7 +7,15 @@ TEST(MathUtoZ, sizeZeroInput) { using stan::math::csr_u_to_z; std::vector u(0); for (int n = -1; n < 2; ++n) - EXPECT_THROW(csr_u_to_z(u, n), std::out_of_range); + EXPECT_THROW(csr_u_to_z(u, n), std::domain_error); + u.push_back(1); + for (int n = -1; n < 2; ++n) + EXPECT_THROW(csr_u_to_z(u, n), std::domain_error); + u.push_back(1); + EXPECT_THROW(csr_u_to_z(u, -1), std::out_of_range); + EXPECT_NO_THROW(csr_u_to_z(u, 0)); + EXPECT_THROW(csr_u_to_z(u, 1), std::out_of_range); + EXPECT_THROW(csr_u_to_z(u, 2), std::out_of_range); } TEST(MathUtoZ, nonemptyInput) { using stan::math::csr_u_to_z; diff --git a/test/unit/math/prim/prob/neg_binomial_2_log_test.cpp b/test/unit/math/prim/prob/neg_binomial_2_log_test.cpp index 00645c9ceee..a60cc051413 100644 --- a/test/unit/math/prim/prob/neg_binomial_2_log_test.cpp +++ b/test/unit/math/prim/prob/neg_binomial_2_log_test.cpp @@ -42,7 +42,7 @@ TEST(ProbDistributionsNegBinomial2Log, error_check) { error_msg = "neg_binomial_2_log_rng: Exponential " "of the log-location parameter divided by the precision " - "parameter is inf, but must be finite!"; + "parameter is inf, but must be positive and finite!"; try { stan::math::neg_binomial_2_log_rng(log(1e300), 1e-300, rng); FAIL() << "neg_binomial_2_log_rng should have thrown" << std::endl; diff --git a/test/unit/math/prim/prob/neg_binomial_2_test.cpp b/test/unit/math/prim/prob/neg_binomial_2_test.cpp index e73eb227b0f..52ee74cb4d1 100644 --- a/test/unit/math/prim/prob/neg_binomial_2_test.cpp +++ b/test/unit/math/prim/prob/neg_binomial_2_test.cpp @@ -62,7 +62,7 @@ TEST(ProbDistributionsNegBinomial2, error_check) { error_msg = "neg_binomial_2_rng: Location parameter " "divided by the precision parameter is " - "inf, but must be finite!"; + "inf, but must be positive and finite!"; try { stan::math::neg_binomial_2_rng(1e300, 1e-300, rng); FAIL() << "neg_binomial_2_rng should have thrown" << std::endl; diff --git a/test/unit/math/rev/err/check_pos_semidefinite_test.cpp b/test/unit/math/rev/err/check_pos_semidefinite_test.cpp index b384b023483..1fa789ee6a4 100644 --- a/test/unit/math/rev/err/check_pos_semidefinite_test.cpp +++ b/test/unit/math/rev/err/check_pos_semidefinite_test.cpp @@ -14,9 +14,10 @@ TEST(AgradRevErrorHandlingMatrix, checkPosSemiDefiniteMatrix_nan) { y.resize(1, 1); y << nan; - EXPECT_THROW_MSG(check_pos_semidefinite("checkPosDefiniteMatrix", "y", y), - std::domain_error, - "checkPosDefiniteMatrix: y[1] is nan, but must not be nan!"); + EXPECT_THROW_MSG( + check_pos_semidefinite("checkPosDefiniteMatrix", "y", y), + std::domain_error, + "checkPosDefiniteMatrix: y[row=1, col=1] is nan, but must not be nan!"); y.resize(3, 3); y << 2, -1, 0, -1, 2, -1, 0, -1, 2; From e6eeaf97ce31f59763a7146f85a743f8a57b5c04 Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Tue, 24 Mar 2020 10:38:45 -0400 Subject: [PATCH 2/5] [Jenkins] auto-formatting by clang-format version 5.0.2-svn328729-1~exp1~20180509124008.99 (branches/release_50) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index 63836cc7a07..af538d6653b 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -48,7 +48,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const& { return load_(a_); } + inline load_ deep_copy() const & { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** From e5a7fa8928c8b87046845d5cfda87090ee76e743 Mon Sep 17 00:00:00 2001 From: Ben Date: Wed, 8 Jul 2020 22:33:01 -0400 Subject: [PATCH 3/5] Removed release notes (issue #1798) --- RELEASE-NOTES.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt index 42cf4680f6d..2822468abbe 100644 --- a/RELEASE-NOTES.txt +++ b/RELEASE-NOTES.txt @@ -4,10 +4,6 @@ Stan Math Library Release Notes v3.2.0 (pending) ====================================================================== -## Features - -New functions is_nonnegative and is_positive_finite to parallel check_nonnegative and check_positive_finite. They signal failure by returning false instead of by throwing std::domain_error. - ## Developer-aimed features [bob-carpenter](https://github.com/bob-carpenter) extended the scalar_return metaprograms to deal with complex numbers and added a real_return program @@ -15,12 +11,6 @@ and helper metaprograms for intermediate and return types. Miscellaneous doxygen documentation cleanup. -Functions check_not_nan, check_nonnegative, check_positive, check_finite, check_positive_finite, is_not_nan, is_nonnegative, is_positive, is_scal_finite, and is_positive_finite now operate on nested containers. - -Clearer error messages when csr_u_to_z is called with out of range indices. - -check_positive now throws domain error when given an unsigned 0. - ====================================================================== v3.1.0 (24 January 2020) ====================================================================== From fe372409b8631b3fc47a0ef968cd40da5d5a7e0a Mon Sep 17 00:00:00 2001 From: Stan Jenkins Date: Wed, 8 Jul 2020 22:45:25 -0400 Subject: [PATCH 4/5] [Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2 (tags/RELEASE_600/final) --- stan/math/opencl/kernel_generator/load.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stan/math/opencl/kernel_generator/load.hpp b/stan/math/opencl/kernel_generator/load.hpp index 47dc210e3a8..bd9ede85391 100644 --- a/stan/math/opencl/kernel_generator/load.hpp +++ b/stan/math/opencl/kernel_generator/load.hpp @@ -52,7 +52,7 @@ class load_ * Creates a deep copy of this expression. * @return copy of \c *this */ - inline load_ deep_copy() const & { return load_(a_); } + inline load_ deep_copy() const& { return load_(a_); } inline load_ deep_copy() && { return load_(std::forward(a_)); } /** From cae335ec68f91633b71f0a487a58d296d9207b80 Mon Sep 17 00:00:00 2001 From: Ben Date: Thu, 9 Jul 2020 11:13:27 -0400 Subject: [PATCH 5/5] Added missing namespace stuff in tests (issue #1635) --- test/unit/math/prim/err/check_finite_test.cpp | 1 + test/unit/math/prim/err/check_not_nan_test.cpp | 1 + test/unit/math/prim/err/check_positive_finite_test.cpp | 1 + test/unit/math/prim/err/is_scal_finite_test.cpp | 2 ++ 4 files changed, 5 insertions(+) diff --git a/test/unit/math/prim/err/check_finite_test.cpp b/test/unit/math/prim/err/check_finite_test.cpp index 6c967fdc0e1..3312d2202ba 100644 --- a/test/unit/math/prim/err/check_finite_test.cpp +++ b/test/unit/math/prim/err/check_finite_test.cpp @@ -129,6 +129,7 @@ TEST(ErrorHandlingScalar, CheckFinite_nan) { } TEST(ErrorHandlingScalar, CheckFiniteVectorization) { + using stan::math::check_finite; const char* function = "check_finite"; Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 0); EXPECT_NO_THROW( diff --git a/test/unit/math/prim/err/check_not_nan_test.cpp b/test/unit/math/prim/err/check_not_nan_test.cpp index 80f64a0a2d7..f620f54e965 100644 --- a/test/unit/math/prim/err/check_not_nan_test.cpp +++ b/test/unit/math/prim/err/check_not_nan_test.cpp @@ -87,6 +87,7 @@ TEST(ErrorHandlingScalar, CheckNotNan) { } TEST(ErrorHandlingScalar, CheckNotNaNVectorization) { + using stan::math::check_not_nan; const char* function = "check_not_nan"; Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 0); EXPECT_NO_THROW( diff --git a/test/unit/math/prim/err/check_positive_finite_test.cpp b/test/unit/math/prim/err/check_positive_finite_test.cpp index 37e317afcb0..48a4cb97f8b 100644 --- a/test/unit/math/prim/err/check_positive_finite_test.cpp +++ b/test/unit/math/prim/err/check_positive_finite_test.cpp @@ -190,6 +190,7 @@ TEST(ErrorHandlingScalar, CheckPositiveFinite_nan) { } TEST(ErrorHandlingScalar, CheckPositiveFiniteVectorization) { + using stan::math::check_positive_finite; const char* function = "check_positive_finite"; Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); EXPECT_NO_THROW(check_positive_finite(function, "m", diff --git a/test/unit/math/prim/err/is_scal_finite_test.cpp b/test/unit/math/prim/err/is_scal_finite_test.cpp index 52f52563d09..655dbccb293 100644 --- a/test/unit/math/prim/err/is_scal_finite_test.cpp +++ b/test/unit/math/prim/err/is_scal_finite_test.cpp @@ -4,6 +4,7 @@ #include TEST(ErrorHandlingScalar, isScalFinite) { + using stan::math::is_scal_finite; EXPECT_FALSE(is_scal_finite(stan::math::NEGATIVE_INFTY)); EXPECT_TRUE(is_scal_finite(-3.0)); EXPECT_TRUE(is_scal_finite(-3)); @@ -20,6 +21,7 @@ TEST(ErrorHandlingScalar, isScalFinite) { } TEST(ErrorHandlingScalar, isScalFiniteVectorization) { + using stan::math::is_scal_finite; Eigen::MatrixXd m = Eigen::MatrixXd::Constant(3, 2, 1); EXPECT_TRUE(is_scal_finite(std::vector{m, m, m})); Eigen::MatrixXd m2 = m;