CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
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 
19 namespace CppAD {
20 namespace cg {
21 
30 template<class Base>
32 protected:
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;
44 public:
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 
265 private:
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
virtual std::string generateTemporary(const OperationNode< Base > &variable, size_t id)=0
bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t id1, const OperationNode< Base > &indepSecond, size_t id2) override
size_t getTemporaryVarArrayIndex(const OperationNode< Base > &var, size_t id) override
virtual std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip)=0
virtual size_t getMaxTemporaryArrayVariableID() const =0
virtual const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id)=0
bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2) override
virtual std::string generateIndexedIndependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip)=0
virtual bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond)=0
std::string generateIndependent(const OperationNode< Base > &independent, size_t id) override
const std::vector< Argument< Base > > & getArguments() const
virtual const std::vector< FuncArgument > & getTemporary() const
size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id) override
std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id) override
virtual size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id)=0
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
virtual size_t getMinTemporaryVariableID() const =0
std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip) override
const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id) override
virtual std::string generateDependent(size_t index)=0
virtual bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t idFirst, const OperationNode< Base > &indepSecond, size_t idSecond)=0
void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID) override
std::string generateTemporary(const OperationNode< Base > &variable, size_t id) override
const std::vector< FuncArgument > & getDependent() const override
CGOpCode getOperationType() const
virtual void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID)=0
virtual size_t getTemporaryVarArrayIndex(const OperationNode< Base > &var, size_t id)=0
bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond) override
std::string generateIndexedIndependent(const OperationNode< Base > &independent, size_t id, const IndexPattern &ip) override
const std::vector< FuncArgument > & getTemporary() const override
virtual std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id)=0
virtual size_t getMaxTemporarySparseArrayVariableID() const =0
virtual const std::vector< FuncArgument > & getDependent() const
virtual std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id)=0
virtual const std::vector< FuncArgument > & getIndependent() const
virtual std::string generateIndependent(const OperationNode< Base > &variable, size_t id)=0
virtual size_t getMaxTemporaryVariableID() const =0
const std::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id) override
virtual bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2)=0
const std::vector< size_t > & getInfo() const
virtual const std::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id)=0