Stan Math Library  2.20.0
reverse mode automatic differentiation
operands_and_partials.hpp
Go to the documentation of this file.
1 #ifndef STAN_MATH_REV_MAT_META_OPERANDS_AND_PARTIALS_HPP
2 #define STAN_MATH_REV_MAT_META_OPERANDS_AND_PARTIALS_HPP
3 
9 #include <vector>
10 
11 namespace stan {
12 namespace math {
13 namespace internal {
14 // Vectorized Univariate
15 template <>
16 class ops_partials_edge<double, std::vector<var> > {
17  public:
18  typedef std::vector<var> Op;
19  typedef Eigen::VectorXd partials_t;
20  partials_t partials_; // For univariate use-cases
22  explicit ops_partials_edge(const Op& op)
23  : partials_(partials_t::Zero(op.size())),
24  partials_vec_(partials_),
25  operands_(op) {}
26 
27  private:
28  template <typename, typename, typename, typename, typename, typename>
30  const Op& operands_;
31 
32  void dump_partials(double* partials) {
33  for (int i = 0; i < this->partials_.size(); ++i) {
34  partials[i] = this->partials_[i];
35  }
36  }
37  void dump_operands(vari** varis) {
38  for (size_t i = 0; i < this->operands_.size(); ++i) {
39  varis[i] = this->operands_[i].vi_;
40  }
41  }
42  int size() { return this->operands_.size(); }
43 };
44 
45 template <int R, int C>
46 class ops_partials_edge<double, Eigen::Matrix<var, R, C> > {
47  public:
48  typedef Eigen::Matrix<var, R, C> Op;
49  typedef Eigen::Matrix<double, R, C> partials_t;
50  partials_t partials_; // For univariate use-cases
52  explicit ops_partials_edge(const Op& ops)
53  : partials_(partials_t::Zero(ops.rows(), ops.cols())),
54  partials_vec_(partials_),
55  operands_(ops) {}
56 
57  private:
58  template <typename, typename, typename, typename, typename, typename>
60  const Op& operands_;
61 
62  void dump_operands(vari** varis) {
63  for (int i = 0; i < this->operands_.size(); ++i) {
64  varis[i] = this->operands_(i).vi_;
65  }
66  }
67  void dump_partials(double* partials) {
68  for (int i = 0; i < this->partials_.size(); ++i) {
69  partials[i] = this->partials_(i);
70  }
71  }
72  int size() { return this->operands_.size(); }
73 };
74 
75 // SPECIALIZATIONS FOR MULTIVARIATE VECTORIZATIONS
76 // (i.e. nested containers)
77 template <int R, int C>
78 class ops_partials_edge<double, std::vector<Eigen::Matrix<var, R, C> > > {
79  public:
80  typedef std::vector<Eigen::Matrix<var, R, C> > Op;
81  typedef Eigen::Matrix<double, -1, -1> partial_t;
82  std::vector<partial_t> partials_vec_;
83  explicit ops_partials_edge(const Op& ops)
84  : partials_vec_(ops.size()), operands_(ops) {
85  for (size_t i = 0; i < ops.size(); ++i) {
86  partials_vec_[i] = partial_t::Zero(ops[i].rows(), ops[i].cols());
87  }
88  }
89 
90  private:
91  template <typename, typename, typename, typename, typename, typename>
93  const Op& operands_;
94 
95  void dump_partials(double* partials) {
96  int p_i = 0;
97  for (size_t i = 0; i < this->partials_vec_.size(); ++i) {
98  for (int j = 0; j < this->partials_vec_[i].size(); ++j, ++p_i) {
99  partials[p_i] = this->partials_vec_[i](j);
100  }
101  }
102  }
103  void dump_operands(vari** varis) {
104  int p_i = 0;
105  for (size_t i = 0; i < this->operands_.size(); ++i) {
106  for (int j = 0; j < this->operands_[i].size(); ++j, ++p_i) {
107  varis[p_i] = this->operands_[i](j).vi_;
108  }
109  }
110  }
111  int size() {
112  if (unlikely(this->operands_.size() == 0))
113  return 0;
114  return this->operands_.size() * this->operands_[0].size();
115  }
116 };
117 
118 template <>
119 class ops_partials_edge<double, std::vector<std::vector<var> > > {
120  public:
121  typedef std::vector<std::vector<var> > Op;
122  typedef std::vector<double> partial_t;
123  std::vector<partial_t> partials_vec_;
124  explicit ops_partials_edge(const Op& ops)
125  : partials_vec_(length(ops)), operands_(ops) {
126  for (size_t i = 0; i < length(ops); ++i) {
127  partials_vec_[i] = partial_t(length(ops[i]), 0.0);
128  }
129  }
130 
131  private:
132  template <typename, typename, typename, typename, typename, typename>
134  const Op& operands_;
135 
136  void dump_partials(double* partials) {
137  int p_i = 0;
138  for (size_t i = 0; i < this->partials_vec_.size(); ++i) {
139  for (size_t j = 0; j < this->partials_vec_[i].size(); ++j, ++p_i) {
140  partials[p_i] = this->partials_vec_[i][j];
141  }
142  }
143  }
144  void dump_operands(vari** varis) {
145  int p_i = 0;
146  for (size_t i = 0; i < this->operands_.size(); ++i) {
147  for (size_t j = 0; j < this->operands_[i].size(); ++j, ++p_i) {
148  varis[p_i] = this->operands_[i][j].vi_;
149  }
150  }
151  }
152  int size() {
153  if (unlikely(this->operands_.size() == 0))
154  return 0;
155  return this->operands_.size() * this->operands_[0].size();
156  }
157 };
158 } // namespace internal
159 } // namespace math
160 } // namespace stan
161 #endif
int rows(const Eigen::Matrix< T, R, C > &m)
Return the number of rows in the specified matrix, vector, or row vector.
Definition: rows.hpp:20
An edge holds both the operands and its associated partial derivatives.
This template builds partial derivatives with respect to a set of operands.
The variable implementation base class.
Definition: vari.hpp:30
size_t length(const std::vector< T > &x)
Returns the length of the provided std::vector.
Definition: length.hpp:16
(Expert) Numerical traits for algorithmic differentiation variables.
#define unlikely(x)
Definition: likely.hpp:9
empty_broadcast_array< ViewElt, Op > partials_
int cols(const Eigen::Matrix< T, R, C > &m)
Return the number of columns in the specified matrix, vector, or row vector.
Definition: cols.hpp:20
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
Definition: size.hpp:17

     [ Stan Home Page ] © 2011–2018, Stan Development Team.