CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
atomic_fun.hpp
1#ifndef CPPAD_CG_ATOMIC_FUN_INCLUDED
2#define CPPAD_CG_ATOMIC_FUN_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2013 Ciengis
6 * Copyright (C) 2018 Joao Leal
7 *
8 * CppADCodeGen is distributed under multiple licenses:
9 *
10 * - Eclipse Public License Version 1.0 (EPL1), and
11 * - GNU General Public License Version 3 (GPL3).
12 *
13 * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
14 * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
15 * ----------------------------------------------------------------------------
16 * Author: Joao Leal
17 */
18
19namespace CppAD {
20namespace cg {
21
27template <class Base>
28class CGAtomicFun : public CGAbstractAtomicFun<Base> {
29protected:
30 using CGB = CG<Base>;
31protected:
32 atomic_base<Base>& atomicFun_;
33 const CppAD::vector<Base> xSparsity_; // independent vector used to determine sparsity patterns
34public:
35
50 CGAtomicFun(atomic_base<Base>& atomicFun,
51 const CppAD::vector<Base>& xSparsity,
52 bool standAlone = false) :
53 CGAbstractAtomicFun<Base>(atomicFun.atomic_name(), standAlone),
54 atomicFun_(atomicFun),
55 xSparsity_(xSparsity) {
56 }
57
58 CGAtomicFun(atomic_base<Base>& atomicFun,
59 ArrayView<const Base> xSparsity,
60 bool standAlone = false) :
61 CGAtomicFun(atomicFun, values(xSparsity), standAlone) {
62 }
63
64 CGAtomicFun(atomic_base<Base>& atomicFun,
65 ArrayView<const CppAD::AD<Base>> xSparsity,
66 bool standAlone = false) :
67 CGAtomicFun(atomicFun, values(xSparsity), standAlone) {
68 }
69
70 virtual ~CGAtomicFun() = default;
71
72 template <class ADVector>
73 void operator()(const ADVector& ax,
74 ADVector& ay,
75 size_t id = 0) {
76 this->CGAbstractAtomicFun<Base>::operator()(ax, ay, id);
77 }
78
79 bool for_sparse_jac(size_t q,
80 const CppAD::vector<std::set<size_t> >& r,
81 CppAD::vector<std::set<size_t> >& s,
82 const CppAD::vector<CGB>& x) override {
83 return atomicFun_.for_sparse_jac(q, r, s, sparsityIndeps(x));
84 }
85
86 bool for_sparse_jac(size_t q,
87 const CppAD::vector<std::set<size_t> >& r,
88 CppAD::vector<std::set<size_t> >& s) override {
89 return atomicFun_.for_sparse_jac(q, r, s);
90 }
91
92 bool for_sparse_jac(size_t q,
93 const CppAD::vector<bool>& r,
95 const CppAD::vector<CGB>& x) override {
96 return atomicFun_.for_sparse_jac(q, r, s, sparsityIndeps(x));
97 }
98
99 bool for_sparse_jac(size_t q,
100 const CppAD::vector<bool>& r,
101 CppAD::vector<bool>& s) override {
102 return atomicFun_.for_sparse_jac(q, r, s);
103 }
104
105 bool rev_sparse_jac(size_t q,
106 const CppAD::vector<std::set<size_t> >& rt,
107 CppAD::vector<std::set<size_t> >& st,
108 const CppAD::vector<CGB>& x) override {
109 return atomicFun_.rev_sparse_jac(q, rt, st, sparsityIndeps(x));
110 }
111
112 bool rev_sparse_jac(size_t q,
113 const CppAD::vector<std::set<size_t> >& rt,
114 CppAD::vector<std::set<size_t> >& st) override {
115 return atomicFun_.rev_sparse_jac(q, rt, st);
116 }
117
118 bool rev_sparse_jac(size_t q,
119 const CppAD::vector<bool>& rt,
121 const CppAD::vector<CGB>& x) override {
122 return atomicFun_.rev_sparse_jac(q, rt, st, sparsityIndeps(x));
123 }
124
125 bool rev_sparse_jac(size_t q,
126 const CppAD::vector<bool>& rt,
127 CppAD::vector<bool>& st) override {
128 return atomicFun_.rev_sparse_jac(q, rt, st);
129 }
130
131 bool rev_sparse_hes(const CppAD::vector<bool>& vx,
132 const CppAD::vector<bool>& s,
134 size_t q,
135 const CppAD::vector<std::set<size_t> >& r,
136 const CppAD::vector<std::set<size_t> >& u,
137 CppAD::vector<std::set<size_t> >& v,
138 const CppAD::vector<CGB>& x) override {
139 return atomicFun_.rev_sparse_hes(vx, s, t, q, r, u, v, sparsityIndeps(x));
140 }
141
142 bool rev_sparse_hes(const CppAD::vector<bool>& vx,
143 const CppAD::vector<bool>& s,
145 size_t q,
146 const CppAD::vector<std::set<size_t> >& r,
147 const CppAD::vector<std::set<size_t> >& u,
148 CppAD::vector<std::set<size_t> >& v) override {
149 return atomicFun_.rev_sparse_hes(vx, s, t, q, r, u, v);
150 }
151
152 bool rev_sparse_hes(const CppAD::vector<bool>& vx,
153 const CppAD::vector<bool>& s,
155 size_t q,
156 const CppAD::vector<bool>& r,
157 const CppAD::vector<bool>& u,
159 const CppAD::vector<CGB>& x) override {
160 return atomicFun_.rev_sparse_hes(vx, s, t, q, r, u, v, sparsityIndeps(x));
161 }
162
163 bool rev_sparse_hes(const CppAD::vector<bool>& vx,
164 const CppAD::vector<bool>& s,
166 size_t q,
167 const CppAD::vector<bool>& r,
168 const CppAD::vector<bool>& u,
169 CppAD::vector<bool>& v) override {
170 return atomicFun_.rev_sparse_hes(vx, s, t, q, r, u, v);
171 }
172
173protected:
174
175 void zeroOrderDependency(const CppAD::vector<bool>& vx,
177 const CppAD::vector<CGB>& x) override {
178 using CppAD::vector;
179
180 size_t m = vy.size();
181 size_t n = vx.size();
182
183 vector<std::set<size_t> > rt(m);
184 for (size_t j = 0; j < m; j++) {
185 rt[j].insert(j);
186 }
187 vector<std::set<size_t> > st(n);
188
189 bool ok = rev_sparse_jac(m, rt, st, x);
190 if (!ok)
191 throw CGException("False returned from rev_sparse_jac() in the atomic function \"", this->atomic_name(), "\".");
192
193 for (size_t j = 0; j < n; j++) {
194 for (size_t i : st[j]) {
195 if (vx[j]) {
196 vy[i] = true;
197 }
198 }
199 }
200 }
201
202 bool atomicForward(size_t q,
203 size_t p,
204 const CppAD::vector<Base>& tx,
205 CppAD::vector<Base>& ty) override {
206 CppAD::vector<bool> vx, vy;
207 return atomicFun_.forward(q, p, vx, vy, tx, ty);
208 }
209
210 bool atomicReverse(size_t p,
211 const CppAD::vector<Base>& tx,
212 const CppAD::vector<Base>& ty,
214 const CppAD::vector<Base>& py) override {
215 return atomicFun_.reverse(p, tx, ty, px, py);
216 }
217
218private:
219 inline CppAD::vector<Base> sparsityIndeps(const CppAD::vector<CGB>& x) const {
220 CPPADCG_ASSERT_UNKNOWN(x.size() == xSparsity_.size());
221
222 size_t n = x.size();
223 CppAD::vector<Base> out(n);
224 for (size_t i = 0; i < n; ++i) {
225 if (x[i].isValueDefined()) {
226 out[i] = x[i].getValue();
227 } else {
228 out = xSparsity_;
229 break;
230 }
231 }
232
233 return out;
234 }
235
236 inline static CppAD::vector<Base> values(ArrayView<const CppAD::AD<Base>> x) {
237 CppAD::vector<Base> out(x.size());
238 for (size_t i = 0; i < out.size(); ++i) {
239 out[i] = CppAD::Value(CppAD::Var2Par(x[i]));
240 }
241 return out;
242 }
243
244 inline static CppAD::vector<Base> values(ArrayView<const Base> x) {
245 CppAD::vector<Base> out(x.size());
246 for (size_t i = 0; i < out.size(); ++i) {
247 out[i] = x[i];
248 }
249 return out;
250 }
251};
252
253} // END cg namespace
254} // END CppAD namespace
255
256#endif
CGAtomicFun(atomic_base< Base > &atomicFun, const CppAD::vector< Base > &xSparsity, bool standAlone=false)
bool atomicReverse(size_t p, const CppAD::vector< Base > &tx, const CppAD::vector< Base > &ty, CppAD::vector< Base > &px, const CppAD::vector< Base > &py) override
bool atomicForward(size_t q, size_t p, const CppAD::vector< Base > &tx, CppAD::vector< Base > &ty) override