Skip to content

Commit

Permalink
Merge pull request #1641 from stan-dev/feature/parameter-pack-odes
Browse files Browse the repository at this point in the history
Clicked my button for the day
  • Loading branch information
bbbales2 committed Jul 15, 2020
2 parents 6d63a44 + bec1c2a commit 5598ed1
Show file tree
Hide file tree
Showing 71 changed files with 8,902 additions and 2,534 deletions.
50 changes: 25 additions & 25 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -248,31 +248,31 @@ pipeline {
}
post { always { retry(3) { deleteDir() } } }
}
stage('OpenCL tests async') {
agent { label "gpu-async" }
when {
expression {
runGpuAsync
}
}
steps {
deleteDir()
unstash 'MathSetup'
sh "echo CXX=${env.CXX} -Werror > make/local"
sh "echo STAN_OPENCL=true>> make/local"
sh "echo OPENCL_PLATFORM_ID=0>> make/local"
sh "echo OPENCL_DEVICE_ID=${OPENCL_DEVICE_ID}>> make/local"
sh "make -j${env.PARALLEL} test-headers"
runTests("test/unit/math/opencl")
runTests("test/unit/math/prim/fun/gp_exp_quad_cov_test")
runTests("test/unit/math/prim/fun/mdivide_left_tri_test")
runTests("test/unit/math/prim/fun/mdivide_right_tri_test")
runTests("test/unit/math/prim/fun/multiply_test")
runTests("test/unit/math/rev/fun/mdivide_left_tri_test")
runTests("test/unit/math/rev/fun/multiply_test")
}
post { always { retry(3) { deleteDir() } } }
}
// stage('OpenCL tests async') {
// agent { label "gpu-async" }
// when {
// expression {
// runGpuAsync
// }
// }
// steps {
// deleteDir()
// unstash 'MathSetup'
// sh "echo CXX=${env.CXX} -Werror > make/local"
// sh "echo STAN_OPENCL=true>> make/local"
// sh "echo OPENCL_PLATFORM_ID=0>> make/local"
// sh "echo OPENCL_DEVICE_ID=${OPENCL_DEVICE_ID}>> make/local"
// sh "make -j${env.PARALLEL} test-headers"
// runTests("test/unit/math/opencl")
// runTests("test/unit/math/prim/fun/gp_exp_quad_cov_test")
// runTests("test/unit/math/prim/fun/mdivide_left_tri_test")
// runTests("test/unit/math/prim/fun/mdivide_right_tri_test")
// runTests("test/unit/math/prim/fun/multiply_test")
// runTests("test/unit/math/rev/fun/mdivide_left_tri_test")
// runTests("test/unit/math/rev/fun/multiply_test")
// }
// post { always { retry(3) { deleteDir() } } }
// }
stage('Distribution tests') {
agent { label "distribution-tests" }
steps {
Expand Down
1 change: 1 addition & 0 deletions stan/math/prim/err.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <stan/math/prim/err/check_nonzero_size.hpp>
#include <stan/math/prim/err/check_not_nan.hpp>
#include <stan/math/prim/err/check_ordered.hpp>
#include <stan/math/prim/err/check_sorted.hpp>
#include <stan/math/prim/err/check_pos_definite.hpp>
#include <stan/math/prim/err/check_pos_semidefinite.hpp>
#include <stan/math/prim/err/check_positive.hpp>
Expand Down
76 changes: 76 additions & 0 deletions stan/math/prim/err/check_sorted.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#ifndef STAN_MATH_PRIM_ERR_CHECK_SORTED_HPP
#define STAN_MATH_PRIM_ERR_CHECK_SORTED_HPP

#include <stan/math/prim/err/throw_domain_error.hpp>
#include <stan/math/prim/fun/Eigen.hpp>
#include <sstream>
#include <string>
#include <vector>

namespace stan {
namespace math {

/**
* Check if the specified vector is sorted into increasing order (repeated
* values are okay).
* @tparam T_y Type of scalar
* @param function Function name (for error messages)
* @param name Variable name (for error messages)
* @param y Vector to test
* @throw <code>std::domain_error</code> if the vector elements are
* not sorted, or if any element is <code>NaN</code>.
*/
template <typename T_y>
void check_sorted(const char* function, const char* name,
const Eigen::Matrix<T_y, Eigen::Dynamic, 1>& y) {
using size_type = index_type_t<Eigen::Matrix<T_y, Eigen::Dynamic, 1>>;

for (size_type n = 1; n < y.size(); n++) {
if (!(y[n] >= y[n - 1])) {
std::ostringstream msg1;
msg1 << "is not a valid sorted vector."
<< " The element at " << stan::error_index::value + n << " is ";
std::string msg1_str(msg1.str());
std::ostringstream msg2;
msg2 << ", but should be greater than or equal to the previous element, "
<< y[n - 1];
std::string msg2_str(msg2.str());
throw_domain_error(function, name, y[n], msg1_str.c_str(),
msg2_str.c_str());
}
}
}

/**
* Check if the specified vector is sorted into increasing order (repeated
* values are okay).
* @tparam T_y Type of scalar
* @param function Function name (for error messages)
* @param name Variable name (for error messages)
* @param y <code>std::vector</code> to test
* @throw <code>std::domain_error</code> if the vector elements are
* not sorted, or if any element
* is <code>NaN</code>.
*/
template <typename T_y>
void check_sorted(const char* function, const char* name,
const std::vector<T_y>& y) {
for (size_t n = 1; n < y.size(); n++) {
if (!(y[n] >= y[n - 1])) {
std::ostringstream msg1;
msg1 << "is not a valid sorted vector."
<< " The element at " << stan::error_index::value + n << " is ";
std::string msg1_str(msg1.str());
std::ostringstream msg2;
msg2 << ", but should be greater than or equal to the previous element, "
<< y[n - 1];
std::string msg2_str(msg2.str());
throw_domain_error(function, name, y[n], msg1_str.c_str(),
msg2_str.c_str());
}
}
}

} // namespace math
} // namespace stan
#endif
1 change: 1 addition & 0 deletions stan/math/prim/fun.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
#include <stan/math/prim/fun/elt_multiply.hpp>
#include <stan/math/prim/fun/erf.hpp>
#include <stan/math/prim/fun/erfc.hpp>
#include <stan/math/prim/fun/eval.hpp>
#include <stan/math/prim/fun/exp.hpp>
#include <stan/math/prim/fun/exp2.hpp>
#include <stan/math/prim/fun/expm1.hpp>
Expand Down
41 changes: 41 additions & 0 deletions stan/math/prim/fun/eval.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef STAN_MATH_PRIM_FUN_EVAL_HPP
#define STAN_MATH_PRIM_FUN_EVAL_HPP

#include <stan/math/prim/meta.hpp>
#include <stan/math/prim/fun/Eigen.hpp>

namespace stan {
namespace math {

/**
* Inputs which have a plain_type equal to the own time are forwarded
* unmodified (for Eigen expressions these types are different)
*
* @tparam T Input type
* @param[in] arg Input argument
* @return Forwarded input argument
**/
template <typename T,
require_same_t<std::decay_t<T>, plain_type_t<T>>* = nullptr>
inline decltype(auto) eval(T&& arg) {
return std::forward<T>(arg);
}

/**
* Inputs which have a plain_type different from their own type are
* Eval'd (this catches Eigen expressions)
*
* @tparam T Input type
* @param[in] arg Input argument
* @return Eval'd argument
**/
template <typename T,
require_not_same_t<std::decay_t<T>, plain_type_t<T>>* = nullptr>
inline decltype(auto) eval(const T& arg) {
return arg.eval();
}

} // namespace math
} // namespace stan

#endif
121 changes: 24 additions & 97 deletions stan/math/prim/fun/value_of.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,102 +10,48 @@ namespace stan {
namespace math {

/**
* Return the value of the specified scalar argument
* converted to a double value.
* Inputs that are arithmetic types or containers of airthmetric types
* are returned from value_of unchanged
*
* <p>See the <code>primitive_value</code> function to
* extract values without casting to <code>double</code>.
*
* <p>This function is meant to cover the primitive types. For
* types requiring pass-by-reference, this template function
* should be specialized.
*
* @tparam T type of scalar.
* @param x scalar to convert to double
* @return value of scalar cast to double
*/
template <typename T, require_arithmetic_t<T>* = nullptr>
inline double value_of(const T x) {
return static_cast<double>(x);
}

/**
* Return the specified argument.
*
* <p>See <code>value_of(T)</code> for a polymorphic
* implementation using static casts.
*
* <p>This inline pass-through no-op should be compiled away.
*
* @param x value
* @return input value
*/
template <>
inline double value_of<double>(double x) {
return x;
* @tparam T Input type
* @param[in] x Input argument
* @return Forwarded input argument
**/
template <typename T, require_st_arithmetic<T>* = nullptr>
inline decltype(auto) value_of(T&& x) {
return std::forward<T>(x);
}

/**
* Return the specified argument.
*
* <p>See <code>value_of(T)</code> for a polymorphic
* implementation using static casts.
* For std::vectors of non-arithmetic types, return a std::vector composed
* of value_of applied to each element.
*
* <p>This inline pass-through no-op should be compiled away.
*
* @param x value
* @return input value
*/
inline int value_of(int x) { return x; }

/**
* Convert a std::vector of type T to a std::vector of
* child_type<T>::type.
*
* @tparam T Scalar type in std::vector
* @param[in] x std::vector to be converted
* @tparam T Input element type
* @param[in] x Input std::vector
* @return std::vector of values
**/
template <typename T, require_not_double_or_int_t<T>* = nullptr>
inline std::vector<typename child_type<T>::type> value_of(
const std::vector<T>& x) {
size_t x_size = x.size();
std::vector<typename child_type<T>::type> result(x_size);
for (size_t i = 0; i < x_size; i++) {
result[i] = value_of(x[i]);
template <typename T, require_not_st_arithmetic<T>* = nullptr>
inline auto value_of(const std::vector<T>& x) {
std::vector<plain_type_t<decltype(value_of(std::declval<T>()))>> out;
out.reserve(x.size());
for (auto&& x_elem : x) {
out.emplace_back(value_of(x_elem));
}
return result;
return out;
}

/**
* Return the specified argument.
*
* <p>See <code>value_of(T)</code> for a polymorphic
* implementation using static casts.
*
* <p>This inline pass-through no-op should be compiled away.
*
* @param x Specified std::vector.
* @return Specified std::vector.
*/
template <typename Vec, require_std_vector_vt<is_double_or_int, Vec>* = nullptr>
inline Vec value_of(Vec&& x) {
return std::forward<Vec>(x);
}

/**
* Convert a matrix of type T to a matrix of doubles.
*
* T must implement value_of. See
* test/math/fwd/fun/value_of.cpp for fvar and var usage.
* For Eigen matrices and expressions of non-arithmetic types, return an
*expression that represents the Eigen::Matrix resulting from applying value_of
*elementwise
*
* @tparam EigMat type of the matrix
*
* @param[in] M Matrix to be converted
* @return Matrix of values
**/
template <typename EigMat, require_eigen_t<EigMat>* = nullptr,
require_not_vt_double_or_int<EigMat>* = nullptr>
require_not_st_arithmetic<EigMat>* = nullptr>
inline auto value_of(EigMat&& M) {
return make_holder(
[](auto& a) {
Expand All @@ -114,25 +60,6 @@ inline auto value_of(EigMat&& M) {
std::forward<EigMat>(M));
}

/**
* Return the specified argument.
*
* <p>See <code>value_of(T)</code> for a polymorphic
* implementation using static casts.
*
* <p>This inline pass-through no-op should be compiled away.
*
* @tparam EigMat type of the matrix
*
* @param x Specified matrix.
* @return Specified matrix.
*/
template <typename EigMat,
require_eigen_vt<is_double_or_int, EigMat>* = nullptr>
inline EigMat value_of(EigMat&& x) {
return std::forward<EigMat>(x);
}

} // namespace math
} // namespace stan

Expand Down
5 changes: 4 additions & 1 deletion stan/math/prim/functor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#include <stan/math/prim/functor/apply_scalar_unary.hpp>
#include <stan/math/prim/functor/apply_scalar_binary.hpp>
#include <stan/math/prim/functor/apply_vector_unary.hpp>
#include <stan/math/prim/functor/coupled_ode_observer.hpp>
#include <stan/math/prim/functor/coupled_ode_system.hpp>
#include <stan/math/prim/functor/finite_diff_gradient.hpp>
#include <stan/math/prim/functor/finite_diff_gradient_auto.hpp>
Expand All @@ -14,6 +13,9 @@
#include <stan/math/prim/functor/finite_diff_hessian_helper.hpp>
#include <stan/math/prim/functor/integrate_1d.hpp>
#include <stan/math/prim/functor/integrate_ode_rk45.hpp>
#include <stan/math/prim/functor/integrate_ode_std_vector_interface_adapter.hpp>
#include <stan/math/prim/functor/ode_rk45.hpp>
#include <stan/math/prim/functor/ode_store_sensitivities.hpp>
#include <stan/math/prim/functor/map_rect.hpp>
#include <stan/math/prim/functor/map_rect_combine.hpp>
#include <stan/math/prim/functor/map_rect_concurrent.hpp>
Expand All @@ -24,4 +26,5 @@
#include <stan/math/prim/functor/operands_and_partials.hpp>
#include <stan/math/prim/functor/reduce_sum.hpp>
#include <stan/math/prim/functor/reduce_sum_static.hpp>

#endif
1 change: 1 addition & 0 deletions stan/math/prim/functor/apply.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ constexpr decltype(auto) apply_impl(F&& f, Tuple&& t,
return f(std::forward<decltype(std::get<I>(t))>(std::get<I>(t))...);
}
} // namespace internal

/*
* Call the functor f with the tuple of arguments t, like:
*
Expand Down
Loading

0 comments on commit 5598ed1

Please sign in to comment.