CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
pantelides.hpp
1#ifndef CPPAD_CG_PANTELIDES_INCLUDED
2#define CPPAD_CG_PANTELIDES_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2012 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
19#include <cppad/cg/dae_index_reduction/dae_structural_index_reduction.hpp>
20#include <cppad/cg/dae_index_reduction/augment_path_depth_lookahead.hpp>
21
22namespace CppAD {
23namespace cg {
24
28template<class Base>
30protected:
32 using ADCG = CppAD::AD<CGBase>;
33protected:
34 // avoids having to type this->graph_
35 using DaeStructuralIndexReduction<Base>::graph_;
36 // typical values used to avoid NaNs in the tape validation by CppAD
37 std::vector<Base> x_;
38 // whether or not reduceIndex() has been called
39 bool reduced_;
40 AugmentPathDepthLookahead<Base> defaultAugmentPath_;
41 AugmentPath<Base>* augmentPath_;
42public:
43
55 const std::vector<DaeVarInfo>& varInfo,
56 const std::vector<std::string>& eqName,
57 const std::vector<Base>& x) :
58 DaeStructuralIndexReduction<Base>(fun, varInfo, eqName),
59 x_(x),
60 reduced_(false),
61 augmentPath_(&defaultAugmentPath_) {
62
63 }
64
65 Pantelides(const Pantelides& p) = delete;
66
67 Pantelides& operator=(const Pantelides& p) = delete;
68
69 virtual ~Pantelides() = default;
70
71 AugmentPath<Base>& getAugmentPath() const {
72 return *augmentPath_;
73 }
74
75 void setAugmentPath(AugmentPath<Base>& a) const {
76 augmentPath_ = &a;
77 }
78
79 inline std::unique_ptr<ADFun<CG<Base>>> reduceIndex(std::vector<DaeVarInfo>& newVarInfo,
80 std::vector<DaeEquationInfo>& equationInfo) override {
81 if (reduced_)
82 throw CGException("reduceIndex() can only be called once!");
83
84 if (this->verbosity_ >= Verbosity::Low)
85 log() << "######## Pantelides method ########\n";
86
87 augmentPath_->setLogger(*this);
88
89 reduced_ = true;
90
92
93 if (this->verbosity_ >= Verbosity::Low) {
94 graph_.printResultInfo("Pantelides");
95
96 log() << "Structural index: " << graph_.getStructuralIndex() << std::endl;
97 }
98
99 std::unique_ptr<ADFun<CGBase>> reducedFun(graph_.generateNewModel(newVarInfo, equationInfo, x_));
100
101 return reducedFun;
102 }
103
104protected:
105 using DaeStructuralIndexReduction<Base>::log;
106
110 inline void detectSubset2Dif() {
111 auto& vnodes = graph_.variables();
112 auto& enodes = graph_.equations();
113
114 Enode<Base>* ll;
115
116 if (this->verbosity_ >= Verbosity::High)
117 graph_.printDot(this->log());
118
119 size_t Ndash = enodes.size();
120 for (size_t k = 0; k < Ndash; k++) {
121 Enode<Base>* i = enodes[k];
122
123 if (this->verbosity_ >= Verbosity::High)
124 log() << "Outer loop: equation k = " << *i << "\n";
125
126 bool pathfound = false;
127 while (!pathfound) {
128
133 for (Vnode<Base>* jj : vnodes) {
134 if (!jj->isDeleted() && jj->derivative() != nullptr) {
135 jj->deleteNode(log(), this->verbosity_);
136 }
137 }
138
139 graph_.uncolorAll();
140
141 pathfound = augmentPath_->augmentPath(*i);
142
143 if (!pathfound) {
144 const size_t vsize = vnodes.size(); // the size might change
145 for (size_t l = 0; l < vsize; ++l) {
146 Vnode<Base>* jj = vnodes[l];
147 if (jj->isColored() && !jj->isDeleted()) {
148 // add new variable derivatives of colored variables
149 graph_.createDerivate(*jj);
150 }
151 }
152
153 const size_t esize = enodes.size(); // the size might change
154 for (size_t l = 0; l < esize; l++) {
155 ll = enodes[l];
156 if (ll->isColored()) {
157 // add new derivative equations for colored equations and create edges
158 graph_.createDerivate(*ll);
159 }
160 }
161
162 // structural check to avoid infinite recursion
163 for (size_t l = esize; l < enodes.size(); l++) {
164 ll = enodes[l];
165 const std::vector<Vnode<Base>*>& nvars = ll->originalVariables();
166 bool ok = false;
167 for (Vnode<Base>* js : nvars) {
168 if (js->equations().size() > 1) {
169 ok = true;
170 break;
171 }
172 }
173 if (!ok)
174 throw CGException("Invalid equation structure. The model appears to be over-defined.");
175 }
176
177 for (Vnode<Base>* jj : vnodes) {
178 if (jj->isColored() && !jj->isDeleted()) {
179 Vnode<Base>* jDiff = jj->derivative();
180 jDiff->setAssignmentEquation(*jj->assignmentEquation()->derivative(), log(), this->verbosity_);
181 }
182 }
183
184 i = i->derivative();
185
186 if (this->verbosity_ >= Verbosity::High) {
187 log() << "Set current equation to (i=" << i->index() << ") " << *i << "\n";
188
189 graph_.printDot(this->log());
190 }
191 }
192 }
193
194 }
195
196 }
197
198};
199
200} // END cg namespace
201} // END CppAD namespace
202
203#endif
virtual bool augmentPath(Enode< Base > &i)=0
Enode< Base > * derivative() const
std::unique_ptr< ADFun< CG< Base > > > reduceIndex(std::vector< DaeVarInfo > &newVarInfo, std::vector< DaeEquationInfo > &equationInfo) override
Pantelides(ADFun< CG< Base > > &fun, const std::vector< DaeVarInfo > &varInfo, const std::vector< std::string > &eqName, const std::vector< Base > &x)
Vnode< Base > * derivative() const