CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
lang_mathml_default_var_name_gen.hpp
1 #ifndef CPPAD_CG_LANG_MATHML_DEFAULT_VAR_NAME_GEN_INCLUDED
2 #define CPPAD_CG_LANG_MATHML_DEFAULT_VAR_NAME_GEN_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2015 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 
27 template<class Base>
29 protected:
30  // auxiliary string stream
31  std::stringstream _ss;
32  // array name of the dependent variables
33  std::string _depName;
34  // array name of the independent variables
35  std::string _indepName;
36  // array name of the temporary variables
37  std::string _tmpName;
38  // array name of the temporary array variables
39  std::string _tmpArrayName;
40  // sparse array name of the temporary array variables
41  std::string _tmpSparseArrayName;
42  // the lowest variable ID used for the temporary variables
43  size_t _minTemporaryID;
44  // the highest variable ID used for the temporary variables
45  size_t _maxTemporaryID;
46  // the highest ID used for the temporary array variables
47  size_t _maxTemporaryArrayID;
48  // the highest ID used for the temporary sparse array variables
49  size_t _maxTemporarySparseArrayID;
50 public:
51 
52  inline LangMathMLDefaultVariableNameGenerator(std::string depName = "y",
53  std::string indepName = "x",
54  std::string tmpName = "v",
55  std::string tmpArrayName = "a",
56  std::string tmpSparseArrayName = "s") :
57  _depName(std::move(depName)),
58  _indepName(std::move(indepName)),
59  _tmpName(std::move(tmpName)),
60  _tmpArrayName(std::move(tmpArrayName)),
61  _tmpSparseArrayName(std::move(tmpSparseArrayName)),
62  _minTemporaryID(0), // not really required (but it avoids warnings)
63  _maxTemporaryID(0), // not really required (but it avoids warnings)
64  _maxTemporaryArrayID(0), // not really required (but it avoids warnings)
65  _maxTemporarySparseArrayID(0) { // not really required (but it avoids warnings)
66 
67  this->_independent.push_back(FuncArgument(_indepName));
68  this->_dependent.push_back(FuncArgument(_depName));
69  this->_temporary.push_back(FuncArgument(_tmpName));
70  this->_temporary.push_back(FuncArgument(_tmpArrayName));
71  this->_temporary.push_back(FuncArgument(_tmpSparseArrayName));
72  }
73 
74  inline virtual ~LangMathMLDefaultVariableNameGenerator() = default;
75 
76  inline size_t getMinTemporaryVariableID() const override {
77  return _minTemporaryID;
78  }
79 
80  inline size_t getMaxTemporaryVariableID() const override {
81  return _maxTemporaryID;
82  }
83 
84  inline size_t getMaxTemporaryArrayVariableID() const override {
85  return _maxTemporaryArrayID;
86  }
87 
88  size_t getMaxTemporarySparseArrayVariableID() const override {
89  return _maxTemporarySparseArrayID;
90  }
91 
92  inline std::string generateDependent(size_t index) override {
93  _ss.clear();
94  _ss.str("");
95 
96  _ss << "<msub>"
97  "<mi>" << _depName << "</mi>"
98  "<mn>" << index << "</mn>"
99  "</msub>";
100 
101  return _ss.str();
102  }
103 
104  inline std::string generateIndependent(const OperationNode<Base>& independent,
105  size_t id) override {
106  _ss.clear();
107  _ss.str("");
108 
109  _ss << "<msub>"
110  "<mi>" << _indepName << "</mi>"
111  "<mn>" << (id - 1) << "</mn>"
112  "</msub>";
113 
114  return _ss.str();
115  }
116 
117  inline std::string generateTemporary(const OperationNode<Base>& variable,
118  size_t id) override {
119  _ss.clear();
120  _ss.str("");
121 
122  if (this->_temporary[0].array) {
123  _ss << "<msub>"
124  "<mi>" << _tmpName << "</mi>"
125  "<mn>" << (id - this->_minTemporaryID) << "</mn>"
126  "</msub>";
127  } else {
128  _ss << "<msub>"
129  "<mi>" << _tmpName << "</mi>"
130  "<mn>" << id << "</mn>"
131  "</msub>";
132  }
133 
134  return _ss.str();
135  }
136 
137  std::string generateTemporaryArray(const OperationNode<Base>& variable,
138  size_t id) override {
139  _ss.clear();
140  _ss.str("");
141 
142  CPPADCG_ASSERT_UNKNOWN(variable.getOperationType() == CGOpCode::ArrayCreation)
143 
144  _ss << "<mi>" << _tmpArrayName << "</mi>"
145  "<mfenced open='[' close=']'>"
146  "<mrow>"
147  "<mn>" << id - 1 << "</mn>"
148  "<mo>:</mo>"
149  "</mrow>"
150  "</mfenced>";
151 
152  return _ss.str();
153  }
154 
156  size_t id) override {
157  _ss.clear();
158  _ss.str("");
159 
160  CPPADCG_ASSERT_UNKNOWN(variable.getOperationType() == CGOpCode::SparseArrayCreation)
161 
162  _ss << "<mi>" << _tmpSparseArrayName << "</mi>"
163  "<mfenced open='[' close=']'>"
164  "<mrow>"
165  "<mn>" << id - 1 << "</mn>"
166  "<mo>:</mo>"
167  "</mrow>"
168  "</mfenced>";
169 
170  return _ss.str();
171  }
172 
174  size_t id,
175  const IndexPattern& ip) override {
176  CPPADCG_ASSERT_KNOWN(var.getOperationType() == CGOpCode::LoopIndexedDep, "Invalid node type")
177  CPPADCG_ASSERT_KNOWN(!var.getArguments().empty(), "Invalid number of arguments")
178 
179  _ss.clear();
180  _ss.str("");
181 
182  _ss << "<msub>"
183  "<mi>" << _depName << "</mi>"
184  << "<mrow>";
185  LanguageMathML<Base>::indexPattern2String(_ss, ip, getIndexes(var, 1));
186  _ss << "</mrow>";
187  _ss << "</msub>";
188 
189  return _ss.str();
190  }
191 
192  std::string generateIndexedIndependent(const OperationNode<Base>& independent,
193  size_t id,
194  const IndexPattern& ip) override {
195  CPPADCG_ASSERT_KNOWN(independent.getOperationType() == CGOpCode::LoopIndexedIndep, "Invalid node type")
196  CPPADCG_ASSERT_KNOWN(independent.getArguments().size() > 0, "Invalid number of arguments")
197 
198  _ss.clear();
199  _ss.str("");
200 
201 
202  _ss << "<msub>"
203  "<mi>" << _indepName << "</mi>"
204  << "<mrow>";
205  LanguageMathML<Base>::indexPattern2String(_ss, ip, getIndexes(independent));
206  _ss << "</mrow>";
207  _ss << "</msub>";
208 
209  return _ss.str();
210  }
211 
212  inline void setTemporaryVariableID(size_t minTempID,
213  size_t maxTempID,
214  size_t maxTempArrayID,
215  size_t maxTempSparseArrayID) override {
216  _minTemporaryID = minTempID;
217  _maxTemporaryID = maxTempID;
218  _maxTemporaryArrayID = maxTempArrayID;
219  _maxTemporarySparseArrayID = maxTempSparseArrayID;
220 
221  // if
222  // _minTemporaryID == _maxTemporaryID + 1
223  // then no temporary variables are being used
224  CPPADCG_ASSERT_UNKNOWN(_minTemporaryID <= _maxTemporaryID + 1)
225  }
226 
227  const std::string& getIndependentArrayName(const OperationNode<Base>& indep,
228  size_t id) override {
229  return _indepName;
230  }
231 
233  size_t id) override {
234  return id - 1;
235  }
236 
238  size_t idFirst,
239  const OperationNode<Base>& indepSecond,
240  size_t idSecond) override {
241  return idFirst + 1 == idSecond;
242  }
243 
245  size_t id1,
246  const OperationNode<Base>& indep2,
247  size_t id2) override {
248  return true;
249  }
250 
251  const std::string& getTemporaryVarArrayName(const OperationNode<Base>& var,
252  size_t id) override {
253  return _tmpName;
254  }
255 
257  size_t id) override {
258  return id - this->_minTemporaryID;
259  }
260 
262  size_t idFirst,
263  const OperationNode<Base>& varSecond,
264  size_t idSecond) override {
265  return idFirst + 1 == idSecond;
266  }
267 
269  size_t id1,
270  const OperationNode<Base>& var2,
271  size_t id2) override {
272  return true;
273  }
274 
275 protected:
276 
277  static inline std::vector<const OperationNode<Base>*> getIndexes(const OperationNode<Base>& var,
278  size_t offset = 0) {
279  const std::vector<Argument<Base> >& args = var.getArguments();
280  std::vector<const OperationNode<Base>*> indexes(args.size() - offset);
281 
282  for (size_t a = offset; a < args.size(); a++) {
283  CPPADCG_ASSERT_KNOWN(args[a].getOperation() != nullptr, "Invalid argument")
284  CPPADCG_ASSERT_KNOWN(args[a].getOperation()->getOperationType() == CGOpCode::Index, "Invalid argument")
285 
286  indexes[a - offset] = &static_cast<const IndexOperationNode<Base>*> (args[a].getOperation())->getIndex();
287  }
288 
289  return indexes;
290  }
291 };
292 
293 } // END cg namespace
294 } // END CppAD namespace
295 
296 #endif
size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id) 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 isInSameIndependentArray(const OperationNode< Base > &indep1, size_t id1, const OperationNode< Base > &indep2, size_t id2) override
const std::vector< Argument< Base > > & getArguments() const
bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond) override
std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id) override
void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID) override
bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2) override
const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id) override
std::string generateIndexedIndependent(const OperationNode< Base > &independent, size_t id, const IndexPattern &ip) override
CGOpCode getOperationType() const
std::string generateIndependent(const OperationNode< Base > &independent, size_t id) override
std::string generateTemporary(const OperationNode< Base > &variable, size_t id) 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 idFirst, const OperationNode< Base > &indepSecond, size_t idSecond) override