Skip to content

Remove linear indexing requirements from functions #2205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 32 commits into from
Dec 1, 2020
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
61160ed
simplify and use elementwise_check helper
t4c1 Nov 23, 2020
eadb6fa
test that no function requires linear indexing
t4c1 Nov 23, 2020
88af7c5
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot Nov 23, 2020
6a28b3d
handle autodiff types
t4c1 Nov 23, 2020
14b2601
fixed doxygen
t4c1 Nov 23, 2020
8e0d5cf
added missing header
t4c1 Nov 23, 2020
81434c1
fix a typo and more includes
t4c1 Nov 23, 2020
b97a903
typo
t4c1 Nov 23, 2020
1501d93
back to value_of_rec
t4c1 Nov 23, 2020
b14b350
fix typo
t4c1 Nov 23, 2020
20cc034
added Eigen traits for arena_matrix
t4c1 Nov 24, 2020
9cf5ceb
typos
t4c1 Nov 24, 2020
4406ad7
Merge commit '92fce0218c9fb15fd405ef031f488cad05c5546b' into HEAD
yashikno Nov 24, 2020
d703bcd
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot Nov 24, 2020
7d48486
another typo
t4c1 Nov 24, 2020
40e849c
Merge branch 'no_linear_indexing_requirement' of https://github.com/b…
t4c1 Nov 24, 2020
bf508ba
fix performance regression
t4c1 Nov 24, 2020
d713cd7
fix some brittle tests
t4c1 Nov 24, 2020
ede1749
bugfix
t4c1 Nov 24, 2020
86c7bea
bugfix
t4c1 Nov 24, 2020
ec1f046
replace +1 with +error_index::value
t4c1 Nov 24, 2020
e035d83
added space and improved some brittle tests
t4c1 Nov 25, 2020
1826702
another brittle test
t4c1 Nov 25, 2020
55ffbbe
another testimproved
t4c1 Nov 26, 2020
60e204e
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot Nov 26, 2020
2e169a2
bugfix expression tests
t4c1 Nov 26, 2020
2ba50b6
remove linear indexing requirement from multiply_lower_tri_self_trans…
t4c1 Nov 27, 2020
0d5cef3
remove linear indexing requirement from to_matrix
t4c1 Nov 27, 2020
27b17be
addressed review comments
t4c1 Nov 30, 2020
ddfaa12
applied Ben's suggestion
t4c1 Nov 30, 2020
3e27038
Merge commit '0c1ef70578684386fae2b15af26d2d3854790959' into HEAD
yashikno Nov 30, 2020
e3fbd53
[Jenkins] auto-formatting by clang-format version 6.0.0-1ubuntu2~16.0…
stan-buildbot Nov 30, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 9 additions & 119 deletions stan/math/prim/err/check_finite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
#define STAN_MATH_PRIM_ERR_CHECK_FINITE_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err/is_scal_finite.hpp>
#include <stan/math/prim/err/throw_domain_error.hpp>
#include <stan/math/prim/err/throw_domain_error_vec.hpp>
#include <stan/math/prim/err/elementwise_check.hpp>
#include <stan/math/prim/fun/Eigen.hpp>
#include <stan/math/prim/fun/get.hpp>
#include <stan/math/prim/fun/size.hpp>
Expand All @@ -14,130 +12,22 @@

namespace stan {
namespace math {
namespace internal {
/**
* Return true if y is finite
*
* @tparam T_y type of y
* @param y parameter to check
* @return boolean
*/
template <typename T_y>
bool is_finite(const T_y& y) {
return is_scal_finite(y);
}

/**
* Return true if every element of the matrix y is finite
*
* @tparam T_y type of elements y
* @param y matrix to check
* @return boolean
*/
template <typename T_y, int R, int C>
bool is_finite(const Eigen::Matrix<T_y, R, C>& y) {
bool all = true;
for (size_t n = 0; n < y.size(); ++n) {
all &= is_finite(y(n));
}
return all;
}

/**
* Return true if every element of the vector y is finite
*
* @tparam T_y type of elements y
* @param y vector to check
* @return boolean
*/
template <typename T_y>
bool is_finite(const std::vector<T_y>& y) {
bool all = true;
for (size_t n = 0; n < stan::math::size(y); ++n) {
all &= is_finite(y[n]);
}
return all;
}
} // namespace internal

/**
* Check if <code>y</code> is finite.
* This function is vectorized and will check each element of
* <code>y</code>.
* @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 <code>domain_error</code> if y is infinity, -infinity, or NaN
*/
template <typename T_y, require_stan_scalar_t<T_y>* = nullptr>
inline void check_finite(const char* function, const char* name, const T_y& y) {
if (!internal::is_finite(y)) {
throw_domain_error(function, name, y, "is ", ", but must be finite!");
}
}

/**
* Return <code>true</code> if all values in the std::vector are finite.
*
* @tparam T_y type of elements in the std::vector
*
* @param function name of function (for error messages)
* @param name variable name (for error messages)
* @param y std::vector to test
* @return <code>true</code> if all values are finite
**/
template <typename T_y, require_stan_scalar_t<T_y>* = nullptr>
inline void check_finite(const char* function, const char* name,
const std::vector<T_y>& y) {
for (size_t n = 0; n < stan::math::size(y); n++) {
if (!internal::is_finite(stan::get(y, n))) {
throw_domain_error_vec(function, name, y, n, "is ",
", but must be finite!");
}
}
}

/**
* Return <code>true</code> is the specified matrix is finite.
*
* @tparam Derived Eigen derived type
*
* @param function name of function (for error messages)
* @param name variable name (for error messages)
* @param y matrix to test
* @return <code>true</code> if the matrix is finite
**/
template <typename Mat, require_matrix_t<Mat>* = nullptr>
inline void check_finite(const char* function, const char* name, const Mat& 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, value_of(y), n, "is ",
", but must be finite!");
}
}
}
}

/**
* Return <code>true</code> if all values in the std::vector are finite.
* Return <code>true</code> if all values in `y` are finite. `y` can be a
*scalar, `std::vector` or Eigen type.
*
* @tparam T_y type of elements in the std::vector
* @tparam T_y type of `y`
*
* @param function name of function (for error messages)
* @param name variable name (for error messages)
* @param y std::vector to test
* @param y scalar or container to test
* @return <code>true</code> if all values are finite
**/
template <typename T_y, require_not_stan_scalar_t<T_y>* = nullptr>
inline void check_finite(const char* function, const char* name,
const std::vector<T_y>& y) {
for (size_t n = 0; n < stan::math::size(y); n++) {
if (!internal::is_finite(stan::get(y, n))) {
throw_domain_error(function, name, "", "", "is not finite!");
}
}
template <typename T_y>
inline void check_finite(const char* function, const char* name, const T_y& y) {
elementwise_check([](double x) { return std::isfinite(x); }, function, name,
y, "finite");
}

} // namespace math
Expand Down
33 changes: 3 additions & 30 deletions stan/math/prim/err/check_nonnegative.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,14 @@
#define STAN_MATH_PRIM_ERR_CHECK_NONNEGATIVE_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err/throw_domain_error.hpp>
#include <stan/math/prim/err/throw_domain_error_vec.hpp>
#include <stan/math/prim/err/elementwise_check.hpp>
#include <stan/math/prim/fun/get.hpp>
#include <stan/math/prim/fun/size.hpp>
#include <type_traits>

namespace stan {
namespace math {

namespace internal {
template <typename T_y, bool is_vec>
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<T_y>::value && !(y >= 0)) {
throw_domain_error(function, name, y, "is ", ", but must be >= 0!");
}
}
};

template <typename T_y>
struct nonnegative<T_y, true> {
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<typename value_type<T_y>::type>::value
&& !(stan::get(y, n) >= 0)) {
throw_domain_error_vec(function, name, y, n, "is ",
", but must be >= 0!");
}
}
}
};
} // namespace internal

/**
* Check if <code>y</code> is non-negative.
* This function is vectorized and will check each element of <code>y</code>.
Expand All @@ -50,8 +23,8 @@ struct nonnegative<T_y, true> {
template <typename T_y>
inline void check_nonnegative(const char* function, const char* name,
const T_y& y) {
internal::nonnegative<T_y, is_vector_like<T_y>::value>::check(function, name,
y);
elementwise_check([](double x) { return x >= 0; }, function, name, y,
"nonnegative");
}
} // namespace math
} // namespace stan
Expand Down
29 changes: 3 additions & 26 deletions stan/math/prim/err/check_not_nan.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#define STAN_MATH_PRIM_ERR_CHECK_NOT_NAN_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err/throw_domain_error.hpp>
#include <stan/math/prim/err/throw_domain_error_vec.hpp>
#include <stan/math/prim/err/elementwise_check.hpp>
#include <stan/math/prim/fun/get.hpp>
#include <stan/math/prim/fun/is_nan.hpp>
#include <stan/math/prim/fun/size.hpp>
Expand All @@ -12,29 +11,6 @@
namespace stan {
namespace math {

namespace internal {
template <typename T_y, bool is_vec>
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 <typename T_y>
struct not_nan<T_y, true> {
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 <code>y</code> is not <code>NaN</code>.
* This function is vectorized and will check each element of
Expand All @@ -49,7 +25,8 @@ struct not_nan<T_y, true> {
template <typename T_y>
inline void check_not_nan(const char* function, const char* name,
const T_y& y) {
internal::not_nan<T_y, is_vector_like<T_y>::value>::check(function, name, y);
elementwise_check([](double x) { return !std::isnan(x); }, function, name, y,
"not nan");
}

} // namespace math
Expand Down
34 changes: 3 additions & 31 deletions stan/math/prim/err/check_positive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#define STAN_MATH_PRIM_ERR_CHECK_POSITIVE_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err/throw_domain_error.hpp>
#include <stan/math/prim/err/throw_domain_error_vec.hpp>
#include <stan/math/prim/err/elementwise_check.hpp>
#include <stan/math/prim/err/invalid_argument.hpp>
#include <stan/math/prim/fun/get.hpp>
#include <stan/math/prim/fun/size.hpp>
Expand All @@ -13,34 +12,6 @@
namespace stan {
namespace math {

namespace {

template <typename T_y, bool is_vec>
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<T_y>::value && !(y > 0)) {
throw_domain_error(function, name, y, "is ", ", but must be > 0!");
}
}
};

template <typename T_y>
struct positive<T_y, true> {
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<typename value_type<T_y>::type>::value
&& !(stan::get(y, n) > 0)) {
throw_domain_error_vec(function, name, y, n, "is ",
", but must be > 0!");
}
}
}
};

} // namespace

/**
* Check if <code>y</code> is positive.
* This function is vectorized and will check each element of
Expand All @@ -55,7 +26,8 @@ struct positive<T_y, true> {
template <typename T_y>
inline void check_positive(const char* function, const char* name,
const T_y& y) {
positive<T_y, is_vector_like<T_y>::value>::check(function, name, y);
elementwise_check([](double x) { return x > 0; }, function, name, y,
"positive");
}

/**
Expand Down
7 changes: 3 additions & 4 deletions stan/math/prim/err/check_positive_finite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
#define STAN_MATH_PRIM_ERR_CHECK_POSITIVE_FINITE_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/err/check_positive.hpp>
#include <stan/math/prim/err/check_finite.hpp>
#include <stan/math/prim/err/elementwise_check.hpp>

namespace stan {
namespace math {
Expand All @@ -22,8 +21,8 @@ namespace math {
template <typename T_y>
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);
elementwise_check([](double x) { return x > 0 && std::isfinite(x); },
function, name, y, "positive finite");
}

} // namespace math
Expand Down
Loading