1#ifndef STAN_MATH_REV_FUNCTOR_INTEGRATE_1D_ADJOINT_HPP
2#define STAN_MATH_REV_FUNCTOR_INTEGRATE_1D_ADJOINT_HPP
55template <
typename F,
typename T_a,
typename T_b,
typename Integrator,
58 const char* function,
const F& f,
const T_a& a,
const T_b& b,
59 Integrator&& integrator, std::ostream* msgs,
const Args&... args) {
69 auto args_val_tuple = std::make_tuple(
value_of(args)...);
70 auto eval_f = [&](
const auto& x,
const auto& xc) {
72 [&](
auto&&... val_args) {
return f(x, xc, msgs, val_args...); },
76 const double integral = integrator(eval_f);
78 if constexpr (is_var_v<T_a>) {
79 double partial_a = 0.0;
81 partial_a = -eval_f(a_val, 0.0);
84 [ret, a, partial_a]() { a.adj() += partial_a * ret.adj(); });
86 if constexpr (is_var_v<T_b>) {
87 double partial_b = 0.0;
89 partial_b = eval_f(b_val, 0.0);
92 [ret, b, partial_b]() { b.adj() += partial_b * ret.adj(); });
100 auto args_copy = deep_copy_vargs<var>(std::forward_as_tuple(args...));
102 auto integrate_grad = [&](
auto&& target) ->
double {
103 return integrator([&](
const auto& x,
const auto& xc) {
107 [&](
auto&&... local_args) {
108 return f(x, xc, msgs, local_args...);
119 std::size_t param_index = 0;
120 auto assign_grad = [&](
auto&& adj,
auto&& target) {
121 adj = integrate_grad(target);
124 "is nan for parameter ",
"");
129 [&](
auto&& adj_leaf,
auto&& var_leaf) {
130 using leaf_t = std::decay_t<
decltype(var_leaf)>;
131 if constexpr (is_std_vector_v<leaf_t>) {
132 for (
size_t j = 0; j < var_leaf.size(); ++j) {
133 assign_grad(adj_leaf[j], var_leaf[j]);
135 }
else if constexpr (is_eigen_v<leaf_t>) {
136 for (Eigen::Index j = 0; j < var_leaf.size(); ++j) {
137 assign_grad(adj_leaf.coeffRef(j), var_leaf.coeff(j));
140 assign_grad(adj_leaf, var_leaf);
143 args_adj, args_copy_filter);
void set_zero_all_adjoints()
Reset all adjoint values in this nested stack to zero.
A class following the RAII idiom to start and recover nested autodiff scopes.
typename return_type< Ts... >::type return_type_t
Convenience type for the return type of the specified template parameters.
return_type_t< T_a, T_b, Args... > integrate_1d_adjoint(const char *function, const F &f, const T_a &a, const T_b &b, Integrator &&integrator, std::ostream *msgs, const Args &... args)
Build the reverse-mode result of a one-dimensional adaptive quadrature.
constexpr decltype(auto) filter_var_scalar_types(T &&t)
Filter a tuple and return a tuple with references to the types with a var scalar type.
void reverse_pass_collect_adjoints(var ret, Output &&output, Input &&input)
Collects adjoints from a tuple or std::vector of tuples.
constexpr auto make_zeroed_arena(Input &&input)
Creates an arena type that is the same type as the input and initialized with zeros.
void iter_tuple_nested(F &&f, Types &&... args)
Iterate and nest into a tuple or std::vector to apply f to each matrix or scalar type.
bool is_nan(T &&x)
Returns 1 if the input's value is NaN and 0 otherwise.
void gradient(const F &f, const Eigen::Matrix< T, Eigen::Dynamic, 1 > &x, T &fx, Eigen::Matrix< T, Eigen::Dynamic, 1 > &grad_fx)
Calculate the value and the gradient of the specified function at the specified argument.
void reverse_pass_callback(F &&functor)
Puts a callback on the autodiff stack to be called in reverse pass.
T value_of(const fvar< T > &v)
Return the value of the specified variable.
void throw_domain_error(const char *function, const char *name, const T &y, const char *msg1, const char *msg2)
Throw a domain error with a consistently formatted message.
int is_inf(const fvar< T > &x)
Returns 1 if the input's value is infinite and 0 otherwise.
constexpr decltype(auto) apply(F &&f, Tuple &&t, PreArgs &&... pre_args)
constexpr bool is_any_var_scalar_v
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...