CppADCodeGen  HEAD
A C++ Algorithmic Differentiation Package with Source Code Generation
lang_c_default_hessian_var_name_gen.hpp
1 #ifndef CPPAD_CG_LANG_C_DEFAULT_HESSIAN_VAR_NAME_GEN_INCLUDED
2 #define CPPAD_CG_LANG_C_DEFAULT_HESSIAN_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 equation multipliers
35  const size_t _minMultiplierID;
36  // array name of the independent variables
37  const std::string _multName;
38  // auxiliary string stream
39  std::stringstream _ss;
40 public:
41 
43  size_t n) :
44  _nameGen(nameGen),
45  _minMultiplierID(n + 1),
46  _multName("mult") {
47 
48  CPPADCG_ASSERT_KNOWN(_nameGen != nullptr, "The name generator must not be NULL")
49 
50  initialize();
51  }
52 
54  std::string multName,
55  size_t n) :
56  _nameGen(nameGen),
57  _minMultiplierID(n + 1),
58  _multName(std::move(multName)) {
59 
60  CPPADCG_ASSERT_KNOWN(_nameGen != nullptr, "The name generator must not be null")
61  CPPADCG_ASSERT_KNOWN(_multName.size() > 0, "The name for the multipliers must not be empty")
62 
63  initialize();
64  }
65 
66  inline virtual ~LangCDefaultHessianVarNameGenerator() = default;
67 
68  const std::vector<FuncArgument>& getDependent() const override {
69  return _nameGen->getDependent();
70  }
71 
72  const std::vector<FuncArgument>& getTemporary() const override {
73  return _nameGen->getTemporary();
74  }
75 
76  size_t getMinTemporaryVariableID() const override {
77  return _nameGen->getMinTemporaryVariableID();
78  }
79 
80  size_t getMaxTemporaryVariableID() const override {
81  return _nameGen->getMaxTemporaryVariableID();
82  }
83 
84  size_t getMaxTemporaryArrayVariableID() const override {
85  return _nameGen->getMaxTemporaryArrayVariableID();
86  }
87 
88  size_t getMaxTemporarySparseArrayVariableID() const override {
89  return _nameGen->getMaxTemporarySparseArrayVariableID();
90  }
91 
92  std::string generateDependent(size_t index) override {
93  return _nameGen->generateDependent(index);
94  }
95 
96  std::string generateIndependent(const OperationNode<Base>& independent,
97  size_t id) override {
98  if (id < _minMultiplierID) {
99  return _nameGen->generateIndependent(independent, id);
100  }
101 
102  _ss.clear();
103  _ss.str("");
104  _ss << _multName << "[" << (id - _minMultiplierID) << "]";
105  return _ss.str();
106  }
107 
108  std::string generateTemporary(const OperationNode<Base>& variable,
109  size_t id) override {
110  return _nameGen->generateTemporary(variable, id);
111  }
112 
113  std::string generateTemporaryArray(const OperationNode<Base>& variable,
114  size_t id) override {
115  return _nameGen->generateTemporaryArray(variable, id);
116  }
117 
119  size_t id) override {
120  return _nameGen->generateTemporarySparseArray(variable, id);
121  }
122 
124  size_t id,
125  const IndexPattern& ip) override {
126  return _nameGen->generateIndexedDependent(var, id, ip);
127  }
128 
129  std::string generateIndexedIndependent(const OperationNode<Base>& indexedIndep,
130  size_t id,
131  const IndexPattern& ip) override {
132  bool isX = indexedIndep.getInfo()[0] == 0;
133  if (isX) {
134  return _nameGen->generateIndexedIndependent(indexedIndep, id, ip);
135  }
136 
137  size_t nIndex = indexedIndep.getArguments().size();
138 
139  CPPADCG_ASSERT_KNOWN(indexedIndep.getOperationType() == CGOpCode::LoopIndexedIndep, "Invalid node type")
140  CPPADCG_ASSERT_KNOWN(nIndex > 0, "Invalid number of arguments")
141 
142  std::vector<const OperationNode<Base>*> indices(nIndex);
143  for (size_t i = 0; i < nIndex; ++i) {// typically there is only one index but there may be more
144  CPPADCG_ASSERT_KNOWN(indexedIndep.getArguments()[i].getOperation() != nullptr, "Invalid argument")
145  CPPADCG_ASSERT_KNOWN(indexedIndep.getArguments()[i].getOperation()->getOperationType() == CGOpCode::Index, "Invalid argument")
146  indices[i] = &static_cast<const IndexOperationNode<Base>&> (*indexedIndep.getArguments()[i].getOperation()).getIndex();
147  }
148 
149  _ss.clear();
150  _ss.str("");
151 
152  _ss << _multName << "[" << LanguageC<Base>::indexPattern2String(ip, indices) << "]";
153  return _ss.str();
154  }
155 
156  const std::string& getIndependentArrayName(const OperationNode<Base>& indep,
157  size_t id) override {
158  if (id < _minMultiplierID)
159  return _nameGen->getIndependentArrayName(indep, id);
160  else
161  return _multName;
162  }
163 
165  size_t id) override {
166  if (id < _minMultiplierID)
167  return _nameGen->getIndependentArrayIndex(indep, id);
168  else
169  return id - _minMultiplierID;
170  }
171 
173  size_t id1,
174  const OperationNode<Base>& indepSecond,
175  size_t id2) override {
176  if ((id1 < _minMultiplierID) != (id2 < _minMultiplierID))
177  return false;
178 
179  if (id1 < _minMultiplierID && id2 < _minMultiplierID)
180  return _nameGen->isConsecutiveInIndepArray(indepFirst, id1, indepSecond, id2);
181  else
182  return id1 + 1 == id2;
183  }
184 
186  size_t id1,
187  const OperationNode<Base>& indep2,
188  size_t id2) override {
189  size_t l1;
190  if (indep1.getOperationType() == CGOpCode::Inv) {
191  l1 = id1 < _minMultiplierID ? 0 : 1;
192  } else {
193  l1 = indep1.getInfo()[0]; //CGLoopIndexedIndepOp
194  }
195 
196  size_t l2;
197  if (indep2.getOperationType() == CGOpCode::Inv) {
198  l2 = id2 < _minMultiplierID ? 0 : 1;
199  } else {
200  l2 = indep2.getInfo()[0]; //CGLoopIndexedIndepOp
201  }
202 
203  return l1 == l2;
204  }
205 
206  void setTemporaryVariableID(size_t minTempID,
207  size_t maxTempID,
208  size_t maxTempArrayID,
209  size_t maxTempSparseArrayID) override {
210  _nameGen->setTemporaryVariableID(minTempID, maxTempID, maxTempArrayID, maxTempSparseArrayID);
211  }
212 
213  const std::string& getTemporaryVarArrayName(const OperationNode<Base>& var,
214  size_t id) override {
215  return _nameGen->getTemporaryVarArrayName(var, id);
216  }
217 
219  size_t id) override {
220  return _nameGen->getTemporaryVarArrayIndex(var, id);
221  }
222 
224  size_t idFirst,
225  const OperationNode<Base>& varSecond,
226  size_t idSecond) override {
227  return _nameGen->isConsecutiveInTemporaryVarArray(varFirst, idFirst, varSecond, idSecond);
228  }
229 
231  size_t id1,
232  const OperationNode<Base>& var2,
233  size_t id2) override {
234  return _nameGen->isInSameTemporaryVarArray(var1, id1, var2, id2);
235  }
236 
237 private:
238 
239  inline void initialize() {
240  this->_independent = _nameGen->getIndependent(); // copy
241 
242  this->_independent.push_back(FuncArgument(_multName));
243  }
244 
245 };
246 
247 } // END cg namespace
248 } // END CppAD namespace
249 
250 #endif
virtual std::string generateTemporary(const OperationNode< Base > &variable, size_t id)=0
virtual std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip)=0
std::string generateIndependent(const OperationNode< Base > &independent, size_t id) override
virtual size_t getMaxTemporaryArrayVariableID() const =0
virtual const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id)=0
virtual std::string generateIndexedIndependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip)=0
const std::string & getTemporaryVarArrayName(const OperationNode< Base > &var, size_t id) override
virtual bool isConsecutiveInTemporaryVarArray(const OperationNode< Base > &varFirst, size_t idFirst, const OperationNode< Base > &varSecond, size_t idSecond)=0
const std::vector< Argument< Base > > & getArguments() const
virtual const std::vector< FuncArgument > & getTemporary() const
std::string generateTemporarySparseArray(const OperationNode< Base > &variable, size_t id) override
virtual size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id)=0
virtual size_t getMinTemporaryVariableID() const =0
const std::vector< FuncArgument > & getDependent() const override
bool isInSameIndependentArray(const OperationNode< Base > &indep1, size_t id1, const OperationNode< Base > &indep2, size_t id2) 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
size_t getTemporaryVarArrayIndex(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
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
std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id) override
void setTemporaryVariableID(size_t minTempID, size_t maxTempID, size_t maxTempArrayID, size_t maxTempSparseArrayID) override
const std::vector< FuncArgument > & getTemporary() const override
bool isConsecutiveInIndepArray(const OperationNode< Base > &indepFirst, size_t id1, const OperationNode< Base > &indepSecond, size_t id2) override
virtual std::string generateTemporaryArray(const OperationNode< Base > &variable, size_t id)=0
size_t getIndependentArrayIndex(const OperationNode< Base > &indep, size_t id) override
virtual size_t getMaxTemporarySparseArrayVariableID() const =0
std::string generateIndexedDependent(const OperationNode< Base > &var, size_t id, const IndexPattern &ip) override
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
bool isInSameTemporaryVarArray(const OperationNode< Base > &var1, size_t id1, const OperationNode< Base > &var2, size_t id2) override
virtual size_t getMaxTemporaryVariableID() const =0
std::string generateIndexedIndependent(const OperationNode< Base > &indexedIndep, size_t id, const IndexPattern &ip) override
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
std::string generateTemporary(const OperationNode< Base > &variable, size_t id) override
const std::vector< size_t > & getInfo() const
virtual const std::string & getIndependentArrayName(const OperationNode< Base > &indep, size_t id)=0