1#ifndef STAN_MATH_REV_CORE_PRECOMPUTED_GRADIENTS_HPP
2#define STAN_MATH_REV_CORE_PRECOMPUTED_GRADIENTS_HPP
27template <
typename ContainerOperands = std::tuple<>,
28 typename ContainerGradients = std::tuple<>>
34 static_assert(std::tuple_size<ContainerOperands>::value
35 == std::tuple_size<ContainerGradients>::value,
36 "precomputed_gradients_vari: ContainerOperands and "
37 "ContainerGradients should have same size!");
39 = std::tuple_size<ContainerOperands>::value;
49 template <
size_t... Is>
51 static_cast<void>(std::initializer_list<int>{
74 template <
typename... ContainerOps,
typename... ContainerGrads>
76 double val,
size_t size,
vari** varis,
double* gradients,
77 const std::tuple<ContainerOps...>& container_operands = std::tuple<>(),
78 const std::tuple<ContainerGrads...>& container_gradients = std::tuple<>())
84 return std::make_tuple(
to_arena(std::get<Is>(container_operands))...);
87 return std::make_tuple(
88 to_arena(std::get<Is>(container_gradients))...);
90 check_sizes(std::make_index_sequence<N_containers>());
113 template <
typename Arith,
typename VecVar,
typename VecArith,
114 typename... ContainerOps,
typename... ContainerGrads,
115 require_all_vector_t<VecVar, VecArith>* =
nullptr>
117 Arith val,
const VecVar& vars,
const VecArith& gradients,
118 const std::tuple<ContainerOps...>& container_operands = std::tuple<>(),
119 const std::tuple<ContainerGrads...>& container_gradients = std::tuple<>())
127 return std::make_tuple(
to_arena(std::get<Is>(container_operands))...);
130 return std::make_tuple(
131 to_arena(std::get<Is>(container_gradients))...);
134 "gradients", gradients);
135 check_sizes(std::make_index_sequence<N_containers>());
136 for (
size_t i = 0; i < vars.size(); ++i) {
139 std::copy(gradients.begin(), gradients.end(),
gradients_);
147 for (
size_t i = 0; i <
size_; ++i) {
150 index_apply<N_containers>([
this](
auto... Is) {
151 static_cast<void>(std::initializer_list<int>{
152 (this->
chain_one(std::get<Is>(this->container_operands_),
153 std::get<Is>(this->container_gradients_)),
166 template <
typename Op,
typename Grad,
169 op.vi_->adj_ = op.vi_->adj_ + this->adj_ *
grad;
179 template <
typename Op,
typename OpAlloc,
typename Grad,
typename GradAlloc>
181 const std::vector<Grad, GradAlloc>&
grad) {
182 for (
int i = 0; i < op.size(); i++) {
211template <
typename Arith,
typename VecVar,
typename VecArith,
212 typename... ContainerOperands,
typename... ContainerGradients>
214 Arith value,
const VecVar& operands,
const VecArith& gradients,
215 const std::tuple<ContainerOperands...>& container_operands = std::tuple<>(),
216 const std::tuple<ContainerGradients...>& container_gradients
219 std::tuple<arena_t<ContainerOperands>...>,
220 std::tuple<arena_t<ContainerGradients>...>>(
221 value, operands, gradients, container_operands, container_gradients)};
void check_sizes(std::index_sequence< Is... >)
Checks that sizes of containers in container operands and container_gradients match.
void chain()
Implements the chain rule for this variable, using the prestored operands and gradient.
ContainerGradients container_gradients_
static constexpr size_t N_containers
void chain_one(Op &op, const Grad &grad)
Implements the chain rule for one non-std::vector operand.
void chain_one(const std::vector< Op, OpAlloc > &op, const std::vector< Grad, GradAlloc > &grad)
Implements the chain rule for one std::vector operand.
precomputed_gradients_vari_template(Arith val, const VecVar &vars, const VecArith &gradients, const std::tuple< ContainerOps... > &container_operands=std::tuple<>(), const std::tuple< ContainerGrads... > &container_gradients=std::tuple<>())
Construct a precomputed vari with the specified value, operands, gradients and optionally container o...
precomputed_gradients_vari_template(double val, size_t size, vari **varis, double *gradients, const std::tuple< ContainerOps... > &container_operands=std::tuple<>(), const std::tuple< ContainerGrads... > &container_gradients=std::tuple<>())
Construct a precomputed vari with the specified value, operands, gradients and optionally container o...
ContainerOperands container_operands_
A variable implementation taking a sequence of operands and partial derivatives with respect to the o...
require_all_not_t< is_std_vector< std::decay_t< Types > >... > require_all_not_std_vector_t
Require none of the types satisfy is_std_vector.
int64_t size(const T &m)
Returns the size (number of the elements) of a matrix_cl or var_value<matrix_cl<T>>.
void check_matching_dims(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Check if the two containers have the same dimensions.
arena_t< T > to_arena(const T &a)
Converts given argument into a type that either has any dynamic allocation on AD stack or schedules i...
void check_consistent_sizes(const char *)
Trivial no input case, this function is a no-op.
constexpr auto index_apply(F &&f)
Calls given callable with an index sequence.
static void grad()
Compute the gradient for all variables starting from the end of the AD tape.
var precomputed_gradients(Arith value, const VecVar &operands, const VecArith &gradients, const std::tuple< ContainerOperands... > &container_operands=std::tuple<>(), const std::tuple< ContainerGradients... > &container_gradients=std::tuple<>())
This function returns a var for an expression that has the specified value, vector of operands,...
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
This struct always provides access to the autodiff stack using the singleton pattern.