CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
language_latex_index_patterns.hpp
1#ifndef CPPAD_CG_LANGUAGE_LATEX_INDEX_PATTERNS_INCLUDED
2#define CPPAD_CG_LANGUAGE_LATEX_INDEX_PATTERNS_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2014 Ciengis
6 * Copyright (C) 2019 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
19namespace CppAD {
20namespace cg {
21
22template<class Base>
23inline void LanguageLatex<Base>::generateNames4RandomIndexPatterns(const std::set<RandomIndexPattern*>& randomPatterns) {
24 std::ostringstream os;
25
26 std::set<std::string> usedNames;
27
28 // save existing names so that they are not to overridden
29 // (independent variable names might have already used them)
30 for (RandomIndexPattern* ip : randomPatterns) {
31 if (!ip->getName().empty()) {
32 usedNames.insert(ip->getName());
33 }
34 }
35
36 // create new names for the index pattern arrays without a name
37 size_t c = 0;
38 for (RandomIndexPattern* ip : randomPatterns) {
39 if (ip->getName().empty()) {
40 // new name required
41 std::string name;
42 do {
43 os << _C_STATIC_INDEX_ARRAY << c;
44 name = os.str();
45 os.str("");
46 c++;
47 } while (usedNames.find(name) != usedNames.end());
48
49 ip->setName(name);
50 }
51 }
52
53}
54
55template<class Base>
57 const std::string& indentation,
58 const std::set<RandomIndexPattern*>& randomPatterns) {
59 for (RandomIndexPattern* ip : randomPatterns) {
60 if (ip->getType() == IndexPatternType::Random1D) {
64 auto* ip1 = static_cast<Random1DIndexPattern*> (ip);
65 const std::map<size_t, size_t>& x2y = ip1->getValues();
66
67 std::vector<size_t> y(x2y.rbegin()->first + 1);
68 for (const auto& p : x2y)
69 y[p.first] = p.second;
70
71 os << indentation;
72 printStaticIndexArray(os, ip->getName(), y);
73 } else {
74 CPPADCG_ASSERT_UNKNOWN(ip->getType() == IndexPatternType::Random2D)
78 auto* ip2 = static_cast<Random2DIndexPattern*> (ip);
79 os << indentation;
80 printStaticIndexMatrix(os, ip->getName(), ip2->getValues());
81 }
82 }
83}
84
85template<class Base>
86void LanguageLatex<Base>::printStaticIndexArray(std::ostringstream& os,
87 const std::string& name,
88 const std::vector<size_t>& values) {
89 os << name << " = \\left\\{";
90 if (!values.empty()) {
91 os << values[0];
92 for (size_t i = 1; i < values.size(); i++) {
93 os << ", " << values[i];
94 }
95 }
96 os << "\\right\\}" << _endEq << " % size: " << values.size() << _endline;
97}
98
99template<class Base>
100void LanguageLatex<Base>::printStaticIndexMatrix(std::ostringstream& os,
101 const std::string& name,
102 const std::map<size_t, std::map<size_t, size_t> >& values) {
103 size_t m = 0;
104 size_t n = 0;
105
106 std::map<size_t, std::map<size_t, size_t> >::const_iterator it;
107 std::map<size_t, size_t>::const_iterator ity2z;
108
109 if (!values.empty()) {
110 m = values.rbegin()->first + 1;
111
112 for (it = values.begin(); it != values.end(); ++it) {
113 if (!it->second.empty())
114 n = std::max<size_t>(n, it->second.rbegin()->first + 1);
115 }
116 }
117
118 os << name << " = \\left\\{";
119 size_t x = 0;
120 for (it = values.begin(); it != values.end(); ++it) {
121 if (it->first != x) {
122 while (it->first != x) {
123 os << "{},";
124 x++;
125 }
126 }
127
128 os << "{";
129
130 size_t y = 0;
131 for (ity2z = it->second.begin(); ity2z != it->second.end(); ++ity2z) {
132 if (ity2z->first != y) {
133 while (ity2z->first != y) {
134 os << "0,";
135 y++;
136 }
137 }
138
139 os << ity2z->second;
140 if (ity2z->first != it->second.rbegin()->first) os << ",";
141
142 y++;
143 }
144
145 os << "}";
146 if (it->first != values.rbegin()->first) os << ",";
147
148 x++;
149 }
150 os << "\\right\\}" << _endEq << "% size: " << m << " x " << n << _endline;
151}
152
153template<class Base>
154inline std::string LanguageLatex<Base>::indexPattern2String(const IndexPattern& ip,
155 const OperationNode<Base>& index) {
156 return indexPattern2String(ip,{&index});
157}
158
159template<class Base>
160inline std::string LanguageLatex<Base>::indexPattern2String(const IndexPattern& ip,
161 const std::vector<const OperationNode<Base>*>& indexes) {
162 std::stringstream ss;
163 switch (ip.getType()) {
164 case IndexPatternType::Linear: // y = x * a + b
165 {
166 CPPADCG_ASSERT_KNOWN(indexes.size() == 1, "Invalid number of indexes")
167 const auto& lip = static_cast<const LinearIndexPattern&> (ip);
168 return linearIndexPattern2String(lip, *indexes[0]);
169 }
170 case IndexPatternType::Sectioned:
171 {
172 CPPADCG_ASSERT_KNOWN(indexes.size() == 1, "Invalid number of indexes")
173 const auto* lip = static_cast<const SectionedIndexPattern*> (&ip);
174 const std::map<size_t, IndexPattern*>& sections = lip->getLinearSections();
175 size_t sSize = sections.size();
176 CPPADCG_ASSERT_UNKNOWN(sSize > 1)
177
178 auto its = sections.begin();
179 for (size_t s = 0; s < sSize - 1; s++) {
180 const IndexPattern* lp = its->second;
181 ++its;
182 size_t xStart = its->first;
183
184 ss << "\\left(" << (*indexes[0]->getName()) << "<" << xStart << "\\right)? "
185 << indexPattern2String(*lp, *indexes[0]) << ": ";
186 }
187 ss << indexPattern2String(*its->second, *indexes[0]);
188
189 return ss.str();
190 }
191
192 case IndexPatternType::Plane2D: // y = f(x) + f(z)
193 {
194 CPPADCG_ASSERT_KNOWN(indexes.size() >= 1, "Invalid number of indexes")
195 std::string indexExpr;
196 const auto& pip = static_cast<const Plane2DIndexPattern&> (ip);
197 bool useParens = pip.getPattern1() != nullptr && pip.getPattern2() != nullptr;
198
199 if (useParens) indexExpr += "\\left(";
200
201 if (pip.getPattern1() != nullptr)
202 indexExpr += indexPattern2String(*pip.getPattern1(), *indexes[0]);
203
204 if (useParens) indexExpr += "\\right) + \\left(";
205
206 if (pip.getPattern2() != nullptr)
207 indexExpr += indexPattern2String(*pip.getPattern2(), *indexes.back());
208
209 if (useParens) indexExpr += "\\right)";
210
211 return indexExpr;
212 }
213 case IndexPatternType::Random1D:
214 {
215 CPPADCG_ASSERT_KNOWN(indexes.size() == 1, "Invalid number of indexes")
216 const auto& rip = static_cast<const Random1DIndexPattern&> (ip);
217 CPPADCG_ASSERT_KNOWN(!rip.getName().empty(), "Invalid name for array")
218 return rip.getName() + "\\left[" + (*indexes[0]->getName()) + "\\right]";
219 }
220 case IndexPatternType::Random2D:
221 {
222 CPPADCG_ASSERT_KNOWN(indexes.size() == 2, "Invalid number of indexes")
223 const auto& rip = static_cast<const Random2DIndexPattern&> (ip);
224 CPPADCG_ASSERT_KNOWN(!rip.getName().empty(), "Invalid name for array")
225 return rip.getName() + "\\left[" + (*indexes[0]->getName()) + "\\right]\\left[" + (*indexes[1]->getName()) + "\\right]";
226 }
227 default:
228 CPPADCG_ASSERT_UNKNOWN(false); // should never reach this
229 return "";
230 }
231}
232
233template<class Base>
234inline std::string LanguageLatex<Base>::linearIndexPattern2String(const LinearIndexPattern& lip,
235 const OperationNode<Base>& index) {
236 long dy = lip.getLinearSlopeDy();
237 long dx = lip.getLinearSlopeDx();
238 long b = lip.getLinearConstantTerm();
239 long xOffset = lip.getXOffset();
240
241 std::stringstream ss;
242 if (dy != 0) {
243 if (xOffset != 0) {
244 ss << "\\left(";
245 }
246 ss << (*index.getName());
247 if (xOffset != 0) {
248 ss << " - " << xOffset << "\\right)";
249 }
250
251 if (dx != 1) {
252 ss << " / " << dx;
253 }
254 if (dy != 1) {
255 ss << " \\cdot " << dy;
256 }
257 } else if (b == 0) {
258 ss << "0"; // when dy == 0 and b == 0
259 }
260
261 if (b != 0) {
262 if (dy != 0)
263 ss << " + ";
264 ss << b;
265 }
266 return ss.str();
267}
268
269} // END cg namespace
270} // END CppAD namespace
271
272#endif
void printRandomIndexPatternDeclaration(std::ostringstream &os, const std::string &identation, const std::set< RandomIndexPattern * > &randomPatterns)