1 #ifndef CPPAD_CG_LANGUAGE_C_INDEX_PATTERNS_INCLUDED 2 #define CPPAD_CG_LANGUAGE_C_INDEX_PATTERNS_INCLUDED 22 inline void LanguageC<Base>::generateNames4RandomIndexPatterns(
const std::set<RandomIndexPattern*>& randomPatterns) {
23 std::ostringstream os;
25 std::set<std::string> usedNames;
29 for (RandomIndexPattern* ip : randomPatterns) {
30 if (!ip->getName().empty()) {
31 usedNames.insert(ip->getName());
37 for (RandomIndexPattern* ip : randomPatterns) {
38 if (ip->getName().empty()) {
42 os << _C_STATIC_INDEX_ARRAY << c;
46 }
while (usedNames.find(name) != usedNames.end());
56 const std::string& indentation,
57 const std::set<RandomIndexPattern*>& randomPatterns) {
59 if (ip->getType() == IndexPatternType::Random1D) {
64 const std::map<size_t, size_t>& x2y = ip1->getValues();
66 std::vector<size_t> y(x2y.rbegin()->first + 1);
67 for (
const std::pair<size_t, size_t>& p : x2y)
68 y[p.first] = p.second;
71 printStaticIndexArray(os, ip->getName(), y);
73 CPPADCG_ASSERT_UNKNOWN(ip->getType() == IndexPatternType::Random2D);
79 printStaticIndexMatrix(os, ip->getName(), ip2->getValues());
89 if (_info->indexes.empty())
92 std::set<const OperationNode<Base>*> funcArgs(_funcArgIndexes.begin(), _funcArgIndexes.end());
96 printRandomIndexPatternDeclaration(_ss, _spaces, _info->indexRandomPatterns);
98 _ss << _spaces << U_INDEX_TYPE;
101 if (funcArgs.find(iti) == funcArgs.end()) {
102 if (first) first =
false;
105 _ss <<
" " << (*iti->
getName());
114 const std::string& name,
115 const std::vector<size_t>& values) {
116 os <<
"static " << U_INDEX_TYPE <<
" const " << name <<
"[" << values.size() <<
"] = {";
117 if (!values.empty()) {
119 for (
size_t i = 1; i < values.size(); i++) {
120 os <<
"," << values[i];
128 const std::string& name,
129 const std::map<
size_t, std::map<size_t, size_t> >& values) {
133 std::map<size_t, std::map<size_t, size_t> >::const_iterator it;
134 std::map<size_t, size_t>::const_iterator ity2z;
136 if (!values.empty()) {
137 m = values.rbegin()->first + 1;
139 for (it = values.begin(); it != values.end(); ++it) {
140 if (!it->second.empty())
141 n = std::max(n, it->second.rbegin()->first + 1);
145 os <<
"static " << U_INDEX_TYPE <<
" const " << name <<
"[" << m <<
"][" << n <<
"] = {";
147 for (it = values.begin(); it != values.end(); ++it) {
148 if (it->first != x) {
149 while (it->first != x) {
158 for (ity2z = it->second.begin(); ity2z != it->second.end(); ++ity2z) {
159 if (ity2z->first != y) {
160 while (ity2z->first != y) {
167 if (ity2z->first != it->second.rbegin()->first) os <<
",";
173 if (it->first != values.rbegin()->first) os <<
",";
183 return indexPattern2String(ip,{index.
getName()});
188 const std::string& index) {
189 return indexPattern2String(ip,{&index});
195 std::vector<const std::string*> indexStr(indexes.size());
196 for (
size_t i = 0; i < indexes.size(); ++i)
197 indexStr[i] = indexes[i]->getName();
198 return indexPattern2String(ip, indexStr);
203 const std::vector<const std::string*>& indexes) {
204 std::stringstream ss;
205 switch (ip.getType()) {
206 case IndexPatternType::Linear:
208 CPPADCG_ASSERT_KNOWN(indexes.size() == 1,
"Invalid number of indexes");
210 return linearIndexPattern2String(lip, *indexes[0]);
212 case IndexPatternType::Sectioned:
214 CPPADCG_ASSERT_KNOWN(indexes.size() == 1,
"Invalid number of indexes");
216 const std::map<size_t, IndexPattern*>& sections = lip->getLinearSections();
217 size_t sSize = sections.size();
218 CPPADCG_ASSERT_UNKNOWN(sSize > 1);
220 std::map<size_t, IndexPattern*>::const_iterator its = sections.begin();
221 for (
size_t s = 0; s < sSize - 1; s++) {
224 size_t xStart = its->first;
226 ss <<
"(" << (*indexes[0]) <<
"<" << xStart <<
")? " 227 << indexPattern2String(*lp, *indexes[0]) <<
": ";
229 ss << indexPattern2String(*its->second, *indexes[0]);
234 case IndexPatternType::Plane2D:
236 CPPADCG_ASSERT_KNOWN(indexes.size() >= 1,
"Invalid number of indexes");
237 std::string indexExpr;
239 bool useParens = pip.getPattern1() !=
nullptr && pip.getPattern2() !=
nullptr;
241 if (useParens) indexExpr +=
"(";
243 if (pip.getPattern1() !=
nullptr)
244 indexExpr += indexPattern2String(*pip.getPattern1(), *indexes[0]);
246 if (useParens) indexExpr +=
") + (";
248 if (pip.getPattern2() !=
nullptr)
249 indexExpr += indexPattern2String(*pip.getPattern2(), *indexes.back());
251 if (useParens) indexExpr +=
")";
255 case IndexPatternType::Random1D:
257 CPPADCG_ASSERT_KNOWN(indexes.size() == 1,
"Invalid number of indexes");
259 CPPADCG_ASSERT_KNOWN(!rip.getName().empty(),
"Invalid name for array");
260 return rip.getName() +
"[" + (*indexes[0]) +
"]";
262 case IndexPatternType::Random2D:
264 CPPADCG_ASSERT_KNOWN(indexes.size() == 2,
"Invalid number of indexes");
266 CPPADCG_ASSERT_KNOWN(!rip.getName().empty(),
"Invalid name for array");
267 return rip.getName() +
"[" + (*indexes[0]) +
"][" + (*indexes[1]) +
"]";
270 CPPADCG_ASSERT_UNKNOWN(
false);
278 return linearIndexPattern2String(lip, *index.
getName());
283 const std::string& index) {
284 long dy = lip.getLinearSlopeDy();
285 long dx = lip.getLinearSlopeDx();
286 long b = lip.getLinearConstantTerm();
287 long xOffset = lip.getXOffset();
289 std::stringstream ss;
296 ss <<
" - " << xOffset <<
")";
322 if (ip->getType() == IndexPatternType::Linear) {
324 assert(lIp !=
nullptr);
326 if (refIp->getType() != IndexPatternType::Linear)
329 assert(refLIp !=
nullptr);
331 return isOffsetBy(*lIp, *refLIp, offset);
333 }
else if (ip->getType() == IndexPatternType::Sectioned) {
335 assert(sIp !=
nullptr);
337 if (refIp->getType() != IndexPatternType::Sectioned)
340 assert(refSecp !=
nullptr);
342 return isOffsetBy(*sIp, *refSecp, offset);
355 if (lIp ==
nullptr || refLIp ==
nullptr)
358 return isOffsetBy(*lIp, *refLIp, offset);
365 return refLIp.getLinearSlopeDx() == lIp.getLinearSlopeDx() &&
366 refLIp.getLinearSlopeDy() == lIp.getLinearSlopeDy() &&
367 refLIp.getXOffset() == lIp.getXOffset() &&
368 refLIp.getLinearConstantTerm() + offset == lIp.getLinearConstantTerm();
375 if (refSecp ==
nullptr || sIp ==
nullptr)
378 return isOffsetBy(*sIp, *refSecp, offset);
386 if (refSecp.getLinearSections().size() != sIp.getLinearSections().size())
389 auto itRef = refSecp.getLinearSections().begin();
390 for (
const auto& section : sIp.getLinearSections()) {
392 if (itRef->first != section.first) {
394 }
else if (itRef->second->getType() != IndexPatternType::Linear || section.second->getType() != IndexPatternType::Linear) {
401 if (!isOffsetBy(secLIp, refSecLIp, offset)) {
414 std::unique_ptr<IndexPattern> ip2;
418 lip2->setLinearConstantTerm(lip2->getLinearConstantTerm() - starti);
426 std::unique_ptr<IndexPattern> ip2;
428 std::map<size_t, IndexPattern*> sections;
429 for (
const auto& section : refSecp.getLinearSections()) {
431 lip2->setLinearConstantTerm(lip2->getLinearConstantTerm() - starti);
432 sections[section.first] = lip2;
const std::string * getName() const
static void printRandomIndexPatternDeclaration(std::ostringstream &os, const std::string &identation, const std::set< RandomIndexPattern *> &randomPatterns)