CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
lang_c_default_reverse2_var_name_gen.hpp
1#ifndef CPPAD_CG_LANG_C_DEFAULT_REVERSE2_VAR_NAME_GEN_INCLUDED
2#define CPPAD_CG_LANG_C_DEFAULT_REVERSE2_VAR_NAME_GEN_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
19namespace CppAD {
20namespace cg {
21
30template<class Base>
32protected:
34 // the lowest variable ID used for the first independent variable level
35 const size_t _minLevel1ID;
36 // array name of the independent variables (1st level)
37 const std::string _level1Name;
38 // the lowest variable ID used for the second independent variable level
39 const size_t _minLevel2ID;
40 // array name of the independent variables (2nd level)
41 const std::string _level2Name;
42 // auxiliary string stream
43 std::stringstream _ss;
44public:
45
47 size_t n,
48 size_t n1) :
49 _nameGen(nameGen),
50 _minLevel1ID(n + 1),
51 _level1Name("tx1"),
52 _minLevel2ID(_minLevel1ID + n1),
53 _level2Name("py2") {
54
55 CPPADCG_ASSERT_KNOWN(_nameGen != nullptr, "The name generator must not be null")
56
57 initialize();
58 }
59
61 size_t n,
62 std::string level1Name,
63 size_t n1,
64 std::string level2Name) :
65 _nameGen(nameGen),
66 _minLevel1ID(n + 1),
67 _level1Name(std::move(level1Name)),
68 _minLevel2ID(_minLevel1ID + n1),
69 _level2Name(std::move(level2Name)) {
70
71 CPPADCG_ASSERT_KNOWN(_nameGen != nullptr, "The name generator must not be null")
72 CPPADCG_ASSERT_KNOWN(_level1Name.size() > 0, "The name for the first level must not be empty")
73 CPPADCG_ASSERT_KNOWN(_level2Name.size() > 0, "The name for the second level must not be empty")
74
75 initialize();
76 }
77
78 inline virtual ~LangCDefaultReverse2VarNameGenerator() = default;
79
80 const std::vector<FuncArgument>& getDependent() const override {
81 return _nameGen->getDependent();
82 }
83
84 const std::vector<FuncArgument>& getTemporary() const override {
85 return _nameGen->getTemporary();
86 }
87
88 size_t getMinTemporaryVariableID() const override {
89 return _nameGen->getMinTemporaryVariableID();
90 }
91
92 size_t getMaxTemporaryVariableID() const override {
93 return _nameGen->getMaxTemporaryVariableID();
94 }
95
96 size_t getMaxTemporaryArrayVariableID() const override {
97 return _nameGen->getMaxTemporaryArrayVariableID();
98 }
99
100 size_t getMaxTemporarySparseArrayVariableID() const override {
101 return _nameGen->getMaxTemporarySparseArrayVariableID();
102 }
103
104 std::string generateDependent(size_t index) override {
105 return _nameGen->generateDependent(index);
106 }
107
108 std::string generateIndependent(const OperationNode<Base>& independent,
109 size_t id) override {
110 if (id < _minLevel1ID) {
111 return _nameGen->generateIndependent(independent, id);
112 } else {
113 _ss.clear();
114 _ss.str("");
115 if (id < _minLevel2ID) {
116 _ss << _level1Name << "[" << (id - _minLevel1ID) << "]";
117 } else {
118 _ss << _level2Name << "[" << (id - _minLevel2ID) << "]";
119 }
120 return _ss.str();
121 }
122 }
123
124 std::string generateTemporary(const OperationNode<Base>& variable,
125 size_t id) override {
126 return _nameGen->generateTemporary(variable, id);
127 }
128
129 std::string generateTemporaryArray(const OperationNode<Base>& variable,
130 size_t id) override {
131 return _nameGen->generateTemporaryArray(variable, id);
132 }
133
135 size_t id) override {
136 return _nameGen->generateTemporarySparseArray(variable, id);
137 }
138
140 size_t id,
141 const IndexPattern& ip) override {
142 return _nameGen->generateIndexedDependent(var, id, ip);
143 }
144
145 std::string generateIndexedIndependent(const OperationNode<Base>& independent,
146 size_t id,
147 const IndexPattern& ip) override {
148 size_t varType = independent.getInfo()[0];
149 if (varType == 0) {
150 return _nameGen->generateIndexedIndependent(independent, id, ip);
151 } else {
152 size_t nIndex = independent.getArguments().size();
153
154 CPPADCG_ASSERT_KNOWN(independent.getOperationType() == CGOpCode::LoopIndexedIndep, "Invalid node type")
155 CPPADCG_ASSERT_KNOWN(nIndex > 0, "Invalid number of arguments")
156
157 _ss.clear();
158 _ss.str("");
159
160 std::vector<const OperationNode<Base>*> indices(nIndex);
161 for (size_t i = 0; i < nIndex; ++i) {// typically there is only one index but there may be more
162 CPPADCG_ASSERT_KNOWN(independent.getArguments()[i].getOperation() != nullptr, "Invalid argument")
163 CPPADCG_ASSERT_KNOWN(independent.getArguments()[i].getOperation()->getOperationType() == CGOpCode::Index, "Invalid argument")
164 indices[i] = &static_cast<const IndexOperationNode<Base>&> (*independent.getArguments()[i].getOperation()).getIndex();
165 }
166
167 if (varType == 1) {
168 _ss << _level1Name << "[" << LanguageC<Base>::indexPattern2String(ip, indices) << "]";
169 } else {
170 _ss << _level2Name << "[" << LanguageC<Base>::indexPattern2String(ip, indices) << "]";
171 }
172 return _ss.str();
173 }
174
175 }
176
177 const std::string& getIndependentArrayName(const OperationNode<Base>& indep,
178 size_t id) override {
179 if (id < _minLevel1ID)
180 return _nameGen->getIndependentArrayName(indep, id);
181 else if (id < _minLevel2ID)
182 return _level1Name;
183 else
184 return _level2Name;
185 }
186
188 size_t id) override {
189 if (id < _minLevel1ID)
190 return _nameGen->getIndependentArrayIndex(indep, id);
191 else if (id < _minLevel2ID)
192 return id - _minLevel1ID;
193 else
194 return id - _minLevel2ID;
195 }
196
198 size_t id1,
199 const OperationNode<Base>& indepSecond,
200 size_t id2) override {
201 if ((id1 < _minLevel1ID) != (id2 < _minLevel1ID))
202 return false;
203
204 if (id1 < _minLevel1ID && id2 < _minLevel1ID)
205 return _nameGen->isConsecutiveInIndepArray(indepFirst, id1, indepSecond, id2);
206
207 if ((id1 < _minLevel2ID) != (id2 < _minLevel2ID))
208 return false;
209
210 return id1 + 1 == id2;
211 }
212
214 size_t id1,
215 const OperationNode<Base>& indep2,
216 size_t id2) override {
217 size_t l1;
218 if (indep1.getOperationType() == CGOpCode::Inv) {
219 l1 = id1 < _minLevel1ID ? 0 : (id1 < _minLevel2ID ? 1 : 2);
220 } else {
221 l1 = indep1.getInfo()[0]; //CGLoopIndexedIndepOp
222 }
223
224 size_t l2;
225 if (indep2.getOperationType() == CGOpCode::Inv) {
226 l2 = id2 < _minLevel1ID ? 0 : (id2 < _minLevel2ID ? 1 : 2);
227 } else {
228 l2 = indep2.getInfo()[0]; //CGLoopIndexedIndepOp
229 }
230
231 return l1 == l2;
232 }
233
234 const std::string& getTemporaryVarArrayName(const OperationNode<Base>& var,
235 size_t id) override {
236 return _nameGen->getTemporaryVarArrayName(var, id);
237 }
238
240 size_t id) override {
241 return _nameGen->getTemporaryVarArrayIndex(var, id);
242 }
243
245 size_t idFirst,
246 const OperationNode<Base>& varSecond,
247 size_t idSecond) override {
248 return _nameGen->isConsecutiveInTemporaryVarArray(varFirst, idFirst, varSecond, idSecond);
249 }
250
252 size_t id1,
253 const OperationNode<Base>& var2,
254 size_t id2) override {
255 return _nameGen->isInSameTemporaryVarArray(var1, id1, var2, id2);
256 }
257
258 void setTemporaryVariableID(size_t minTempID,
259 size_t maxTempID,
260 size_t maxTempArrayID,
261 size_t maxTempSparseArrayID) override {
262 _nameGen->setTemporaryVariableID(minTempID, maxTempID, maxTempArrayID, maxTempSparseArrayID);
263 }
264
265private:
266
267 inline void initialize() {
268 this->_independent = _nameGen->getIndependent(); // copy
269 this->_independent.push_back(FuncArgument(_level1Name));
270 this->_independent.push_back(FuncArgument(_level2Name));
271 }
272
273};
274
275} // END cg namespace
276} // END CppAD namespace
277
278#endif
void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID) override
bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond) override
const std::vector< FuncArgument > & getDependent() const override
std::string generateIndexedIndependent(const OperationNode< Base > &independent, size_t id, const IndexPattern &ip) override
size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id) override
const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id) override
std::string generateIndependent(const OperationNode< Base > &independent, size_t id) override
std::string generateTemporary(const OperationNode< Base > &variable, size_t id) override
std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id) override
bool isInSameIndependentArray(const OperationNode< Base > &indep1, size_t id1, const OperationNode< Base > &indep2, size_t id2) override
std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id) override
const std::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id) override
bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2) override
std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip) override
size_t getTemporaryVarArrayIndex(const OperationNode< Base > &var, size_t id) override
bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t id1, const OperationNode< Base > &indepSecond, size_t id2) override
const std::vector< FuncArgument > & getTemporary() const override
const std::vector< size_t > & getInfo() const
const std::vector< Argument< Base > > & getArguments() const
CGOpCode getOperationType() const
virtual std::string generateTemporary(const OperationNode< Base > &variable, size_t id)=0
virtual const std::vector< FuncArgument > & getDependent() const
virtual size_t getMaxTemporarySparseArrayVariableID() const =0
virtual std::string generateIndexedIndependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip)=0
virtual std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id)=0
virtual const std::vector< FuncArgument > & getIndependent() const
virtual bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t idFirst, const OperationNode< Base > &indepSecond, size_t idSecond)=0
virtual size_t getTemporaryVarArrayIndex(const OperationNode< Base > &var, size_t id)=0
virtual const std::vector< FuncArgument > & getTemporary() const
virtual std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id)=0
virtual size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id)=0
virtual void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID)=0
virtual std::string generateIndependent(const OperationNode< Base > &variable, size_t id)=0
virtual bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2)=0
virtual size_t getMinTemporaryVariableID() const =0
virtual bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond)=0
virtual std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip)=0
virtual size_t getMaxTemporaryArrayVariableID() const =0
virtual std::string generateDependent(size_t index)=0
virtual size_t getMaxTemporaryVariableID() const =0
virtual const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id)=0
virtual const std::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id)=0