1#ifndef CPPAD_CG_LANGUAGE_C_INDEX_PATTERNS_INCLUDED
2#define CPPAD_CG_LANGUAGE_C_INDEX_PATTERNS_INCLUDED
23inline void LanguageC<Base>::generateNames4RandomIndexPatterns(
const std::set<RandomIndexPattern*>&
randomPatterns) {
24 std::ostringstream os;
31 if (!
ip->getName().empty()) {
39 if (
ip->getName().empty()) {
43 os << _C_STATIC_INDEX_ARRAY <<
c;
60 if (
ip->getType() == IndexPatternType::Random1D) {
65 const std::map<size_t, size_t>&
x2y =
ip1->getValues();
67 std::vector<size_t>
y(
x2y.rbegin()->first + 1);
68 for (
const auto&
p :
x2y)
69 y[
p.first] =
p.second;
72 printStaticIndexArray(os,
ip->getName(),
y);
74 CPPADCG_ASSERT_UNKNOWN(
ip->getType() == IndexPatternType::Random2D)
80 printStaticIndexMatrix(os,
ip->getName(),
ip2->getValues());
90 if (_info->indexes.empty())
93 std::set<const OperationNode<Base>*>
funcArgs(_funcArgIndexes.begin(), _funcArgIndexes.end());
97 printRandomIndexPatternDeclaration(_ss, _spaces, _info->indexRandomPatterns);
99 _ss << _spaces << U_INDEX_TYPE;
106 _ss <<
" " << (*
iti->getName());
114void LanguageC<Base>::printStaticIndexArray(std::ostringstream& os,
115 const std::string& name,
116 const std::vector<size_t>& values) {
117 os <<
"static " << U_INDEX_TYPE <<
" const " << name <<
"[" << values.size() <<
"] = {";
118 if (!values.empty()) {
120 for (
size_t i = 1;
i < values.size();
i++) {
121 os <<
"," << values[
i];
128void LanguageC<Base>::printStaticIndexMatrix(std::ostringstream& os,
129 const std::string& name,
130 const std::map<
size_t, std::map<size_t, size_t> >& values) {
134 std::map<size_t, std::map<size_t, size_t> >::const_iterator
it;
135 std::map<size_t, size_t>::const_iterator
ity2z;
137 if (!values.empty()) {
138 m = values.rbegin()->first + 1;
140 for (
it = values.begin();
it != values.end(); ++
it) {
141 if (!
it->second.empty())
142 n = std::max<size_t>(
n,
it->second.rbegin()->first + 1);
146 os <<
"static " << U_INDEX_TYPE <<
" const " << name <<
"[" << m <<
"][" <<
n <<
"] = {";
148 for (
it = values.begin();
it != values.end(); ++
it) {
149 if (
it->first != x) {
150 while (
it->first != x) {
161 while (
ity2z->first !=
y) {
168 if (
ity2z->first !=
it->second.rbegin()->first) os <<
",";
174 if (
it->first != values.rbegin()->first) os <<
",";
182inline std::string LanguageC<Base>::indexPattern2String(
const IndexPattern&
ip,
184 return indexPattern2String(
ip,{index.getName()});
188inline std::string LanguageC<Base>::indexPattern2String(
const IndexPattern&
ip,
189 const std::string& index) {
190 return indexPattern2String(
ip,{&index});
194inline std::string LanguageC<Base>::indexPattern2String(
const IndexPattern&
ip,
196 std::vector<const std::string*>
indexStr(indexes.size());
197 for (
size_t i = 0;
i < indexes.size(); ++
i)
203inline std::string LanguageC<Base>::indexPattern2String(
const IndexPattern&
ip,
204 const std::vector<const std::string*>& indexes) {
205 std::stringstream
ss;
206 switch (
ip.getType()) {
207 case IndexPatternType::Linear:
209 CPPADCG_ASSERT_KNOWN(indexes.size() == 1,
"Invalid number of indexes")
211 return linearIndexPattern2String(
lip, *indexes[0]);
213 case IndexPatternType::Sectioned:
215 CPPADCG_ASSERT_KNOWN(indexes.size() == 1,
"Invalid number of indexes")
219 CPPADCG_ASSERT_UNKNOWN(
sSize > 1)
222 for (
size_t s = 0; s <
sSize - 1; s++) {
223 const IndexPattern*
lp =
its->second;
227 ss <<
"(" << (*indexes[0]) <<
"<" <<
xStart <<
")? "
228 << indexPattern2String(*
lp, *indexes[0]) <<
": ";
230 ss << indexPattern2String(*
its->second, *indexes[0]);
235 case IndexPatternType::Plane2D:
237 CPPADCG_ASSERT_KNOWN(!indexes.empty(),
"Invalid number of indexes")
240 bool useParens =
pip.getPattern1() !=
nullptr &&
pip.getPattern2() !=
nullptr;
244 if (
pip.getPattern1() !=
nullptr)
245 indexExpr += indexPattern2String(*
pip.getPattern1(), *indexes[0]);
249 if (
pip.getPattern2() !=
nullptr)
250 indexExpr += indexPattern2String(*
pip.getPattern2(), *indexes.back());
256 case IndexPatternType::Random1D:
258 CPPADCG_ASSERT_KNOWN(indexes.size() == 1,
"Invalid number of indexes")
260 CPPADCG_ASSERT_KNOWN(!
rip.getName().empty(), "
Invalid name
for array")
261 return rip.getName() + "[" + (*indexes[0]) + "]";
263 case IndexPatternType::Random2D:
265 CPPADCG_ASSERT_KNOWN(indexes.size() == 2,
"Invalid number of indexes")
267 CPPADCG_ASSERT_KNOWN(!
rip.getName().empty(), "
Invalid name
for array")
268 return rip.getName() + "[" + (*indexes[0]) + "][" + (*indexes[1]) + "]";
271 CPPADCG_ASSERT_UNKNOWN(
false);
277inline std::
string LanguageC<Base>::linearIndexPattern2String(
const LinearIndexPattern&
lip,
278 const OperationNode<Base>& index) {
279 return linearIndexPattern2String(
lip, *index.getName());
283inline std::string LanguageC<Base>::linearIndexPattern2String(
const LinearIndexPattern&
lip,
284 const std::string& index) {
285 long dy =
lip.getLinearSlopeDy();
286 long dx =
lip.getLinearSlopeDx();
287 long b =
lip.getLinearConstantTerm();
290 std::stringstream
ss;
319bool LanguageC<Base>::isOffsetBy(
const IndexPattern*
ip,
320 const IndexPattern*
refIp,
323 if (
ip->getType() == IndexPatternType::Linear) {
324 const auto*
lIp =
dynamic_cast<const LinearIndexPattern*
> (
ip);
327 if (
refIp->getType() != IndexPatternType::Linear)
329 const auto*
refLIp =
dynamic_cast<const LinearIndexPattern*
> (
refIp);
334 }
else if (
ip->getType() == IndexPatternType::Sectioned) {
335 const auto*
sIp =
dynamic_cast<const SectionedIndexPattern*
> (
ip);
338 if (
refIp->getType() != IndexPatternType::Sectioned)
340 const auto*
refSecp =
dynamic_cast<const SectionedIndexPattern*
> (
refIp);
352bool LanguageC<Base>::isOffsetBy(
const LinearIndexPattern*
lIp,
353 const LinearIndexPattern*
refLIp,
363bool LanguageC<Base>::isOffsetBy(
const LinearIndexPattern&
lIp,
364 const LinearIndexPattern&
refLIp,
366 return refLIp.getLinearSlopeDx() ==
lIp.getLinearSlopeDx() &&
367 refLIp.getLinearSlopeDy() ==
lIp.getLinearSlopeDy() &&
368 refLIp.getXOffset() ==
lIp.getXOffset() &&
369 refLIp.getLinearConstantTerm() +
offset ==
lIp.getLinearConstantTerm();
373bool LanguageC<Base>::isOffsetBy(
const SectionedIndexPattern*
sIp,
374 const SectionedIndexPattern*
refSecp,
383bool LanguageC<Base>::isOffsetBy(
const SectionedIndexPattern&
sIp,
384 const SectionedIndexPattern&
refSecp,
387 if (
refSecp.getLinearSections().size() !=
sIp.getLinearSections().size())
391 for (
const auto&
section :
sIp.getLinearSections()) {
395 }
else if (
itRef->second->getType() != IndexPatternType::Linear ||
section.second->getType() != IndexPatternType::Linear) {
399 auto*
refSecLIp =
static_cast<LinearIndexPattern*
> (
itRef->second);
400 auto*
secLIp =
static_cast<LinearIndexPattern*
> (
section.second);
413Plane2DIndexPattern* LanguageC<Base>::encapsulateIndexPattern(
const LinearIndexPattern&
refLIp,
415 std::unique_ptr<IndexPattern>
ip2;
419 lip2->setLinearConstantTerm(
lip2->getLinearConstantTerm() -
starti);
421 return new Plane2DIndexPattern(
ip2.release(),
new LinearIndexPattern(0, 1, 1, 0));
425Plane2DIndexPattern* LanguageC<Base>::encapsulateIndexPattern(
const SectionedIndexPattern&
refSecp,
427 std::unique_ptr<IndexPattern>
ip2;
429 std::map<size_t, IndexPattern*>
sections;
431 auto*
lip2 =
new LinearIndexPattern(*
static_cast<LinearIndexPattern*
> (
section.second));
432 lip2->setLinearConstantTerm(
lip2->getLinearConstantTerm() -
starti);
437 return new Plane2DIndexPattern(
ip2.release(),
new LinearIndexPattern(0, 1, 1, 0));
static void printRandomIndexPatternDeclaration(std::ostringstream &os, const std::string &identation, const std::set< RandomIndexPattern * > &randomPatterns)
bool GreaterThanZero(const cg::CG< Base > &x)