Automatic Differentiation
 
Loading...
Searching...
No Matches
accumulate_adjoints.hpp
Go to the documentation of this file.
1#ifndef STAN_MATH_REV_CORE_ACCUMULATE_ADJOINTS_HPP
2#define STAN_MATH_REV_CORE_ACCUMULATE_ADJOINTS_HPP
3
8
9#include <utility>
10#include <vector>
11
12namespace stan {
13namespace math {
14
15template <typename... Pargs>
16inline double* accumulate_adjoints(double* dest, const var& x, Pargs&&... args);
17
18template <typename VarVec, require_std_vector_vt<is_var, VarVec>* = nullptr,
19 typename... Pargs>
20inline double* accumulate_adjoints(double* dest, VarVec&& x, Pargs&&... args);
21
22template <typename VecContainer,
23 require_std_vector_st<is_var, VecContainer>* = nullptr,
24 require_std_vector_vt<is_container, VecContainer>* = nullptr,
25 typename... Pargs>
26inline double* accumulate_adjoints(double* dest, VecContainer&& x,
27 Pargs&&... args);
28
29template <typename EigT, require_eigen_vt<is_var, EigT>* = nullptr,
30 typename... Pargs>
31inline double* accumulate_adjoints(double* dest, EigT&& x, Pargs&&... args);
32
33template <typename Arith, require_st_arithmetic<Arith>* = nullptr,
34 typename... Pargs>
35inline double* accumulate_adjoints(double* dest, Arith&& x, Pargs&&... args);
36
37template <typename Tuple, require_tuple_t<Tuple>* = nullptr, typename... Pargs>
38inline double* accumulate_adjoints(double* dest, Tuple&& x, Pargs&&... args);
39
40inline double* accumulate_adjoints(double* dest);
41
54template <typename... Pargs>
55inline double* accumulate_adjoints(double* dest, const var& x,
56 Pargs&&... args) {
57 *dest += x.adj();
58 return accumulate_adjoints(dest + 1, std::forward<Pargs>(args)...);
59}
60
73template <typename VarVec, require_std_vector_vt<is_var, VarVec>*,
74 typename... Pargs>
75inline double* accumulate_adjoints(double* dest, VarVec&& x, Pargs&&... args) {
76 for (auto&& x_iter : x) {
77 *dest += x_iter.adj();
78 ++dest;
79 }
80 return accumulate_adjoints(dest, std::forward<Pargs>(args)...);
81}
82
98template <typename VecContainer, require_std_vector_st<is_var, VecContainer>*,
99 require_std_vector_vt<is_container, VecContainer>*, typename... Pargs>
100inline double* accumulate_adjoints(double* dest, VecContainer&& x,
101 Pargs&&... args) {
102 for (auto&& x_iter : x) {
103 dest = accumulate_adjoints(dest, x_iter);
104 }
105 return accumulate_adjoints(dest, std::forward<Pargs>(args)...);
106}
107
122template <typename EigT, require_eigen_vt<is_var, EigT>*, typename... Pargs>
123inline double* accumulate_adjoints(double* dest, EigT&& x, Pargs&&... args) {
124 Eigen::Map<Eigen::MatrixXd>(dest, x.rows(), x.cols()) += x.adj();
125 return accumulate_adjoints(dest + x.size(), std::forward<Pargs>(args)...);
126}
127
142template <typename Arith, require_st_arithmetic<Arith>*, typename... Pargs>
143inline double* accumulate_adjoints(double* dest, Arith&& x, Pargs&&... args) {
144 return accumulate_adjoints(dest, std::forward<Pargs>(args)...);
145}
146
158template <typename Tuple, require_tuple_t<Tuple>*, typename... Pargs>
159inline double* accumulate_adjoints(double* dest, Tuple&& x, Pargs&&... args) {
160 dest = stan::math::apply(
161 [dest](auto&&... tuple_args) {
162 return accumulate_adjoints(dest, tuple_args...);
163 },
164 std::forward<Tuple>(x));
165 return accumulate_adjoints(dest, std::forward<Pargs>(args)...);
166}
167
173inline double* accumulate_adjoints(double* dest) { return dest; }
174
175} // namespace math
176} // namespace stan
177
178#endif
var_value< double > var
Definition var.hpp:1187
double * accumulate_adjoints(double *dest, const var &x, Pargs &&... args)
Accumulate adjoints from x into storage pointed to by dest, increment the adjoint storage pointer,...
constexpr decltype(auto) apply(F &&f, Tuple &&t, PreArgs &&... pre_args)
Definition apply.hpp:51
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...