CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
lang_latex_default_var_name_gen.hpp
1 #ifndef CPPAD_CG_LANG_LATEX_DEFAULT_VAR_NAME_GEN_INCLUDED
2 #define CPPAD_CG_LANG_LATEX_DEFAULT_VAR_NAME_GEN_INCLUDED
3 /* --------------------------------------------------------------------------
4  * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5  * Copyright (C) 2014 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 LangLatexDefaultVariableNameGenerator(std::string depName = "y",
53  std::string indepName = "x",
54  std::string tmpName = "v",
55  std::string tmpArrayName = "\\mathbf{a}",
56  std::string tmpSparseArrayName = "\\mathbf{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 ~LangLatexDefaultVariableNameGenerator() = 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 << _depName;
97  latexIndex(_ss, index);
98 
99  return _ss.str();
100  }
101 
102  inline std::string generateIndependent(const OperationNode<Base>& independent,
103  size_t id) override {
104  _ss.clear();
105  _ss.str("");
106 
107  _ss << _indepName;
108  latexIndex(_ss, id - 1);
109 
110  return _ss.str();
111  }
112 
113  inline std::string generateTemporary(const OperationNode<Base>& variable,
114  size_t id) override {
115  _ss.clear();
116  _ss.str("");
117 
118  if (this->_temporary[0].array) {
119  _ss << _tmpName;
120  latexIndex(_ss, id - this->_minTemporaryID);
121  } else {
122  _ss << _tmpName << id;
123  latexIndex(_ss, id);
124  }
125 
126  return _ss.str();
127  }
128 
129  std::string generateTemporaryArray(const OperationNode<Base>& variable,
130  size_t id) override {
131  _ss.clear();
132  _ss.str("");
133 
134  CPPADCG_ASSERT_UNKNOWN(variable.getOperationType() == CGOpCode::ArrayCreation)
135 
136  _ss << "\\&" << _tmpArrayName;
137  latexIndex(_ss, id - 1);
138 
139  return _ss.str();
140  }
141 
143  size_t id) override {
144  _ss.clear();
145  _ss.str("");
146 
147  CPPADCG_ASSERT_UNKNOWN(variable.getOperationType() == CGOpCode::SparseArrayCreation)
148 
149  _ss << "\\&" << _tmpSparseArrayName;
150  latexIndex(_ss, id - 1);
151 
152  return _ss.str();
153  }
154 
156  size_t id,
157  const IndexPattern& ip) override {
158  CPPADCG_ASSERT_KNOWN(var.getOperationType() == CGOpCode::LoopIndexedDep, "Invalid node type")
159  CPPADCG_ASSERT_KNOWN(!var.getArguments().empty(), "Invalid number of arguments")
160 
161  _ss.clear();
162  _ss.str("");
163 
164  std::string index = LanguageLatex<Base>::indexPattern2String(ip, getIndexes(var, 1));
165  _ss << _depName << "_";
166  if (index.size() > 1)
167  _ss << "{" << index << "}";
168  else
169  _ss << index;
170 
171  return _ss.str();
172  }
173 
174  std::string generateIndexedIndependent(const OperationNode<Base>& independent,
175  size_t id,
176  const IndexPattern& ip) override {
177  CPPADCG_ASSERT_KNOWN(independent.getOperationType() == CGOpCode::LoopIndexedIndep, "Invalid node type")
178  CPPADCG_ASSERT_KNOWN(independent.getArguments().size() > 0, "Invalid number of arguments")
179 
180  _ss.clear();
181  _ss.str("");
182 
183  std::string index = LanguageLatex<Base>::indexPattern2String(ip, getIndexes(independent));
184  _ss << _indepName << "_";
185  if (index.size() > 1)
186  _ss << "{" << index << "}";
187  else
188  _ss << index;
189 
190  return _ss.str();
191  }
192 
193  inline void setTemporaryVariableID(size_t minTempID,
194  size_t maxTempID,
195  size_t maxTempArrayID,
196  size_t maxTempSparseArrayID) override {
197  _minTemporaryID = minTempID;
198  _maxTemporaryID = maxTempID;
199  _maxTemporaryArrayID = maxTempArrayID;
200  _maxTemporarySparseArrayID = maxTempSparseArrayID;
201 
202  // if
203  // _minTemporaryID == _maxTemporaryID + 1
204  // then no temporary variables are being used
205  CPPADCG_ASSERT_UNKNOWN(_minTemporaryID <= _maxTemporaryID + 1)
206  }
207 
208  const std::string& getIndependentArrayName(const OperationNode<Base>& indep,
209  size_t id) override {
210  return _indepName;
211  }
212 
214  size_t id) override {
215  return id - 1;
216  }
217 
219  size_t idFirst,
220  const OperationNode<Base>& indepSecond,
221  size_t idSecond) override {
222  return idFirst + 1 == idSecond;
223  }
224 
226  size_t id1,
227  const OperationNode<Base>& indep2,
228  size_t id2) override {
229  return true;
230  }
231 
232  const std::string& getTemporaryVarArrayName(const OperationNode<Base>& var,
233  size_t id) override {
234  return _tmpName;
235  }
236 
238  size_t id) override {
239  return id - this->_minTemporaryID;
240  }
241 
243  size_t idFirst,
244  const OperationNode<Base>& varSecond,
245  size_t idSecond) override {
246  return idFirst + 1 == idSecond;
247  }
248 
250  size_t id1,
251  const OperationNode<Base>& var2,
252  size_t id2) override {
253  return true;
254  }
255 
256 protected:
257 
258  static inline std::stringstream& latexIndex(std::stringstream& ss,
259  size_t index) {
260  ss << "_";
261  if (index < 10)
262  ss << index;
263  else
264  ss << "{" << index << "}";
265 
266  return ss;
267  }
268 
269  static inline std::vector<const OperationNode<Base>*> getIndexes(const OperationNode<Base>& var,
270  size_t offset = 0) {
271  const std::vector<Argument<Base> >& args = var.getArguments();
272  std::vector<const OperationNode<Base>*> indexes(args.size() - offset);
273 
274  for (size_t a = offset; a < args.size(); a++) {
275  CPPADCG_ASSERT_KNOWN(args[a].getOperation() != nullptr, "Invalid argument")
276  CPPADCG_ASSERT_KNOWN(args[a].getOperation()->getOperationType() == CGOpCode::Index, "Invalid argument")
277 
278  indexes[a - offset] = &static_cast<const IndexOperationNode<Base>*> (args[a].getOperation())->getIndex();
279  }
280 
281  return indexes;
282  }
283 };
284 
285 } // END cg namespace
286 } // END CppAD namespace
287 
288 #endif
std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id) override
size_t getTemporaryVarArrayIndex(const OperationNode< Base > &var, size_t id) override
size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id) override
const std::vector< Argument< Base > > & getArguments() const
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
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::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id) override
CGOpCode getOperationType() const
std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id) override
bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t idFirst, const OperationNode< Base > &indepSecond, size_t idSecond) override
std::string generateIndependent(const OperationNode< Base > &independent, size_t id) override
std::string generateTemporary(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
bool isInSameIndependentArray(const OperationNode< Base > &indep1, size_t id1, const OperationNode< Base > &indep2, size_t id2) override