CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
bipartite_nodes.hpp
1#ifndef CPPAD_CG_BIPARTITE_NODES_INCLUDED
2#define CPPAD_CG_BIPARTITE_NODES_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2012 Ciengis
6 *
7 * CppADCodeGen is distributed under multiple licenses:
8 *
9 * - Eclipse Public License Version 1.0 (EPL1), and
10 * - GNU General Public License Version 3 (GPL3).
11 *
12 * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13 * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14 * ----------------------------------------------------------------------------
15 * Author: Joao Leal
16 */
17
18#include <assert.h>
19#include <algorithm>
20#include <iostream>
21#include <sstream>
22#include <vector>
23
24namespace CppAD {
25namespace cg {
26
30template<class Base>
32protected:
33 size_t index_; // location of node
34 bool colored_; // node visited
35public:
36
37 inline BiPGraphNode(size_t index) :
38 index_(index),
39 colored_(false) {
40 }
41
42 inline void color(std::ostream& out = std::cout,
43 Verbosity verbosity = Verbosity::None) {
44 colored_ = true;
45
46 if (verbosity >= Verbosity::High)
47 out << " Colored " << nodeType() << " " << name() << "\n";
48 }
49
50 inline void uncolor() {
51 colored_ = false;
52 }
53
54 inline bool isColored() const {
55 return colored_;
56 }
57
58 inline size_t index() const {
59 return index_;
60 }
61
62 inline void setIndex(size_t index) {
63 index_ = index;
64 }
65
66 virtual const std::string& name() const = 0;
67
68 virtual std::string nodeType() = 0;
69
70 inline virtual ~BiPGraphNode() {
71 }
72};
73
74template<class Base>
75class Vnode; // forward declaration
76
80template<class Base>
81class Enode : public BiPGraphNode<Base> {
82protected:
83 static const std::string TYPE;
88 std::vector<Vnode<Base>*> vnodes_orig_;
93 std::vector<Vnode<Base>*> vnodes_;
106 Vnode<Base>* assign_;
110 std::string name_;
111public:
112
113 inline Enode(size_t index,
114 const std::string& name = "") :
115 BiPGraphNode<Base>(index),
116 differentiation_(nullptr),
117 differentiationOf_(nullptr),
118 assign_(nullptr),
119 name_(name.empty()? ("Eq" + std::to_string(index)) : name) {
120 }
121
122 inline Enode(size_t index,
123 Enode<Base>* differentiationOf) :
124 BiPGraphNode<Base>(index),
125 differentiation_(nullptr),
126 differentiationOf_(differentiationOf),
127 assign_(nullptr),
128 name_("Diff(" + differentiationOf->name() + ")") {
129 differentiationOf_->setDerivative(this);
130 }
131
132 inline virtual ~Enode() {
133 }
134
135 inline const std::vector<Vnode<Base>*>& variables() const {
136 return vnodes_;
137 }
138
139 inline const std::vector<Vnode<Base>*>& originalVariables() const {
140 return vnodes_orig_;
141 }
142
143 inline void addVariable(Vnode<Base>* j) {
144 if (std::find(vnodes_orig_.begin(), vnodes_orig_.end(), j) == vnodes_orig_.end()) {
145 vnodes_orig_.push_back(j);
146 if (!j->isDeleted()) {
147 vnodes_.push_back(j);
148 j->addEquation(this);
149 }
150 }
151 }
152
153 inline Vnode<Base>* assignmentVariable() const {
154 return assign_;
155 }
156
157 inline void setAssigmentVariable(Vnode<Base>& j) {
158 assign_ = &j;
159 }
160
165 inline Enode<Base>* derivative() const {
166 return differentiation_;
167 }
168
169 inline Enode<Base>* derivativeOf() const {
170 return differentiationOf_;
171 }
172
173 inline Enode<Base>* originalEquation() {
174 if (differentiationOf_ == nullptr) {
175 return this;
176 } else {
177 return differentiationOf_->originalEquation();
178 }
179 }
180
181 inline void deleteNode(Vnode<Base>* j) {
182 auto it = std::find(vnodes_.begin(), vnodes_.end(), j);
183 if (it != vnodes_.end())
184 vnodes_.erase(it);
185 }
186
187 inline void setDerivative(Enode<Base>* difEq) {
188 differentiation_ = difEq;
189 }
190
191 virtual const std::string& name() const {
192 return name_;
193 }
194
195 virtual std::string nodeType() {
196 return TYPE;
197 }
198};
199
200template<class Base>
201inline std::ostream& operator <<(std::ostream& os, const Enode<Base>& i) {
202 if (i.derivativeOf() != nullptr) {
203 os << "Diff(" << *i.derivativeOf() << ")";
204 } else {
205 os << "Equation " << i.name() << " (" << i.index() << ")";
206 }
207
208 return os;
209}
210
211template<class Base>
212const std::string Enode<Base>::TYPE = "Equation";
213
217template<class Base>
218class Vnode : public BiPGraphNode<Base> {
219protected:
220 static const std::string TYPE;
224 bool deleted_;
233 std::vector<Enode<Base>*> enodes_;
237 Enode<Base>* assign_;
254 std::string name_;
255
256public:
257
258 inline Vnode(size_t index,
259 int tapeIndex,
260 const std::string& name) :
261 BiPGraphNode<Base>(index),
262 deleted_(false),
263 parameter_(false),
264 assign_(nullptr),
265 derivative_(nullptr),
266 antiDerivative_(nullptr),
267 tapeIndex_(tapeIndex),
268 name_(name) {
269
270 }
271
272 inline Vnode(size_t index,
273 size_t tapeIndex,
274 Vnode<Base>* derivativeOf,
275 const std::string& name = "") :
276 BiPGraphNode<Base>(index),
277 deleted_(false),
278 parameter_(false),
279 assign_(nullptr),
280 derivative_(nullptr),
281 antiDerivative_(derivativeOf),
282 tapeIndex_(tapeIndex),
283 name_(name.empty() ? "d" + derivativeOf->name() + "dt" : name) {
284 CPPADCG_ASSERT_UNKNOWN(antiDerivative_ != nullptr);
285
286 antiDerivative_->setDerivative(this);
287 }
288
289 inline virtual ~Vnode() {
290 }
291
292 inline virtual const std::string& name() const {
293 return name_;
294 }
295
296 inline size_t tapeIndex() const {
297 return tapeIndex_;
298 }
299
300 inline void setTapeIndex(size_t tapeIndex) {
301 tapeIndex_ = tapeIndex;
302 }
303
304 inline std::vector<Enode<Base>*>& equations() {
305 return enodes_;
306 }
307
308 inline const std::vector<Enode<Base>*>& equations() const {
309 return enodes_;
310 }
311
315 inline Vnode<Base>* derivative() const {
316 return derivative_;
317 }
318
322 inline Vnode<Base>* antiDerivative() const {
323 return antiDerivative_;
324 }
325
326 inline Vnode<Base>* originalVariable() {
327 if (antiDerivative_ == nullptr) {
328 return this;
329 } else {
330 return antiDerivative_->originalVariable();
331 }
332 }
333
334 inline Vnode<Base>* originalVariable(size_t origVarSize) {
335 if (antiDerivative_ == nullptr || this->index_ < origVarSize) {
336 return this;
337 } else {
338 return antiDerivative_->originalVariable();
339 }
340 }
341
342 inline bool isDeleted() const {
343 return deleted_;
344 }
345
346 inline void makeParameter(std::ostream& out = std::cout,
347 Verbosity verbosity = Verbosity::None) {
348 parameter_ = true;
349 deleteNode(out, verbosity);
350 }
351
352 inline bool isParameter() const {
353 return parameter_;
354 }
355
356 inline void deleteNode(std::ostream& out = std::cout,
357 Verbosity verbosity = Verbosity::None) {
358 if (verbosity >= Verbosity::High)
359 out << "Deleting " << *this << "\n";
360
361 deleted_ = true;
362 for (Enode<Base>* i : enodes_) {
363 i->deleteNode(this);
364 }
365 enodes_.clear();
366 }
367
368 inline Enode<Base>* assignmentEquation() const {
369 return assign_;
370 }
371
372 inline void setAssignmentEquation(Enode<Base>& i,
373 std::ostream& out = std::cout,
374 Verbosity verbosity = Verbosity::None) {
375 if (verbosity >= Verbosity::High)
376 out << " Assigning " << *this << " to " << i << "\n";
377
378 assign_ = &i;
379 i.setAssigmentVariable(*this);
380 }
381
382 virtual std::string nodeType() {
383 return TYPE;
384 }
385
386 inline void setDerivative(Vnode<Base>* div) {
387 derivative_ = div;
388 }
389
390 unsigned int order() const {
391 if (antiDerivative_ == nullptr) {
392 return 0u;
393 } else {
394 return antiDerivative_->order() + 1u;
395 }
396 }
397
398protected:
399
400 inline void addEquation(Enode<Base>* i) {
401 if (!deleted_) {
402 CPPADCG_ASSERT_UNKNOWN(std::find(enodes_.begin(), enodes_.end(), i) == enodes_.end());
403 enodes_.push_back(i);
404 }
405 }
406
407 friend class Enode<Base>;
408};
409
410template<class Base>
411inline std::ostream& operator <<(std::ostream& os, const Vnode<Base>& j) {
412 if (j.antiDerivative() != nullptr) {
413 os << "Diff(" << *j.antiDerivative() << ")";
414 } else {
415 os << "Variable " << j.name();
416 }
417 return os;
418}
419
420template<class Base>
421const std::string Vnode<Base>::TYPE = "Variable";
422
423} // END cg namespace
424} // END CppAD namespace
425
426#endif
std::vector< Vnode< Base > * > vnodes_
Enode< Base > * differentiation_
Enode< Base > * derivative() const
std::vector< Vnode< Base > * > vnodes_orig_
Enode< Base > * differentiationOf_
Vnode< Base > *const antiDerivative_
Vnode< Base > * derivative() const
Vnode< Base > * antiDerivative() const
std::vector< Enode< Base > * > enodes_
Vnode< Base > * derivative_