CppADCodeGen 2.4.3
A C++ Algorithmic Differentiation Package with Source Code Generation
Loading...
Searching...
No Matches
model_c_source_gen_hes.hpp
1#ifndef CPPAD_CG_MODEL_C_SOURCE_GEN_HES_INCLUDED
2#define CPPAD_CG_MODEL_C_SOURCE_GEN_HES_INCLUDED
3/* --------------------------------------------------------------------------
4 * CppADCodeGen: C++ Algorithmic Differentiation with Source Code Generation:
5 * Copyright (C) 2012 Ciengis
6 *
7 * CppADCodeGen is distributed under multiple licenses:
8 *
9 * - Eclipse Public License Version 1.0 (EPL1), and
10 * - GNU General Public License Version 3 (GPL3).
11 *
12 * EPL1 terms and conditions can be found in the file "epl-v10.txt", while
13 * terms and conditions for the GPL3 can be found in the file "gpl3.txt".
14 * ----------------------------------------------------------------------------
15 * Author: Joao Leal
16 */
17
18namespace CppAD {
19namespace cg {
20
21template<class Base>
22void ModelCSourceGen<Base>::generateHessianSource() {
23 using std::vector;
24
25 const std::string jobName = "Hessian";
26
27 startingJob("'" + jobName + "'", JobTimer::GRAPH);
28
29 CodeHandler<Base> handler;
30 handler.setJobTimer(_jobTimer);
31
32 size_t m = _fun.Range();
33 size_t n = _fun.Domain();
34
35
36 // independent variables
37 vector<CGBase> indVars(n);
38 handler.makeVariables(indVars);
39 if (_x.size() > 0) {
40 for (size_t i = 0; i < n; i++) {
41 indVars[i].setValue(_x[i]);
42 }
43 }
44
45 // multipliers
46 vector<CGBase> w(m);
47 handler.makeVariables(w);
48 if (_x.size() > 0) {
49 for (size_t i = 0; i < m; i++) {
50 w[i].setValue(Base(1.0));
51 }
52 }
53
54 vector<CGBase> hess = _fun.Hessian(indVars, w);
55
56 // make use of the symmetry of the Hessian in order to reduce operations
57 for (size_t i = 0; i < n; i++) {
58 for (size_t j = 0; j < i; j++) {
59 hess[i * n + j] = hess[j * n + i];
60 }
61 }
62
63 finishedJob();
64
65 LanguageC<Base> langC(_baseTypeName);
66 langC.setMaxAssignmentsPerFunction(_maxAssignPerFunc, &_sources);
67 langC.setMaxOperationsPerAssignment(_maxOperationsPerAssignment);
68 langC.setParameterPrecision(_parameterPrecision);
69 langC.setGenerateFunction(_name + "_" + FUNCTION_HESSIAN);
70
71 std::ostringstream code;
72 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator("hess"));
73 LangCDefaultHessianVarNameGenerator<Base> nameGenHess(nameGen.get(), n);
74
75 handler.generateCode(code, langC, hess, nameGenHess, _atomicFunctions, jobName);
76}
77
78template<class Base>
79void ModelCSourceGen<Base>::generateSparseHessianSource(MultiThreadingType multiThreadingType) {
83 determineHessianSparsity();
84
85 if (_sparseHessianReusesRev2 && _reverseTwo) {
86 generateSparseHessianSourceFromRev2(multiThreadingType);
87 } else {
88 generateSparseHessianSourceDirectly();
89 }
90}
91
92template<class Base>
94 using std::vector;
95
96 const std::string jobName = "sparse Hessian";
97 size_t m = _fun.Range();
98 size_t n = _fun.Domain();
99
104 std::vector<size_t> evalRows, evalCols;
105 determineSecondOrderElements4Eval(evalRows, evalCols);
106
107 std::map<size_t, std::map<size_t, size_t> > locations;
108 for (size_t e = 0; e < evalRows.size(); e++) {
109 size_t j1 = evalRows[e];
110 size_t j2 = evalCols[e];
111 std::map<size_t, std::map<size_t, size_t> >::iterator itJ1 = locations.find(j1);
112 if (itJ1 == locations.end()) {
113 locations[j1][j2] = e;
114 } else {
115 std::map<size_t, size_t>& j22e = itJ1->second;
116 if (j22e.find(j2) == j22e.end()) {
117 j22e[j2] = e; // OK
118 } else {
119 // repeated elements not allowed
120 throw CGException("Repeated Hessian element requested: ", j1, " ", j2);
121 }
122 }
123 }
124
125 // make use of the symmetry of the Hessian in order to reduce operations
126 std::vector<size_t> lowerHessRows, lowerHessCols, lowerHessOrder;
127 lowerHessRows.reserve(_hessSparsity.rows.size() / 2);
128 lowerHessCols.reserve(lowerHessRows.size());
129 lowerHessOrder.reserve(lowerHessRows.size());
130
131 std::map<size_t, size_t> duplicates; // the elements determined using symmetry
132 std::map<size_t, std::map<size_t, size_t> >::const_iterator itJ;
133 std::map<size_t, size_t>::const_iterator itI;
134 for (size_t e = 0; e < evalRows.size(); e++) {
135 bool add = true;
136 size_t i = evalRows[e];
137 size_t j = evalCols[e];
138 if (i < j) {
139 // find the symmetric value
140 itJ = locations.find(j);
141 if (itJ != locations.end()) {
142 itI = itJ->second.find(i);
143 if (itI != itJ->second.end()) {
144 size_t eSim = itI->second;
145 duplicates[e] = eSim;
146 add = false; // symmetric value being determined
147 }
148 }
149 }
150
151 if (add) {
152 lowerHessRows.push_back(i);
153 lowerHessCols.push_back(j);
154 lowerHessOrder.push_back(e);
155 }
156 }
157
161 startingJob("'" + jobName + "'", JobTimer::GRAPH);
162
163 CodeHandler<Base> handler;
164 handler.setJobTimer(_jobTimer);
165
166 // independent variables
167 vector<CGBase> indVars(n);
168 handler.makeVariables(indVars);
169 if (_x.size() > 0) {
170 for (size_t i = 0; i < n; i++) {
171 indVars[i].setValue(_x[i]);
172 }
173 }
174
175 // multipliers
176 vector<CGBase> w(m);
177 handler.makeVariables(w);
178 if (_x.size() > 0) {
179 for (size_t i = 0; i < m; i++) {
180 w[i].setValue(Base(1.0));
181 }
182 }
183
184 vector<CGBase> hess(_hessSparsity.rows.size());
185 if (_loopTapes.empty()) {
186 CppAD::sparse_hessian_work work;
187 // "cppad.symmetric" may have missing values for functions using atomic
188 // functions which only provide half of the elements
189 // (some values could be zeroed)
190 work.color_method = "cppad.general";
191 vector<CGBase> lowerHess(lowerHessRows.size());
192 _fun.SparseHessian(indVars, w, _hessSparsity.sparsity, lowerHessRows, lowerHessCols, lowerHess, work);
193
194 for (size_t i = 0; i < lowerHessOrder.size(); i++) {
195 hess[lowerHessOrder[i]] = lowerHess[i];
196 }
197
198 // make use of the symmetry of the Hessian in order to reduce operations
199 for (const auto& it2 : duplicates) {
200 hess[it2.first] = hess[it2.second];
201 }
202 } else {
206 hess = prepareSparseHessianWithLoops(handler, indVars, w,
207 lowerHessRows, lowerHessCols, lowerHessOrder,
208 duplicates);
209 }
210
211 finishedJob();
212
213 LanguageC<Base> langC(_baseTypeName);
214 langC.setMaxAssignmentsPerFunction(_maxAssignPerFunc, &_sources);
215 langC.setMaxOperationsPerAssignment(_maxOperationsPerAssignment);
216 langC.setParameterPrecision(_parameterPrecision);
217 langC.setGenerateFunction(_name + "_" + FUNCTION_SPARSE_HESSIAN);
218
219 std::ostringstream code;
220 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator("hess"));
221 LangCDefaultHessianVarNameGenerator<Base> nameGenHess(nameGen.get(), n);
222
223 handler.generateCode(code, langC, hess, nameGenHess, _atomicFunctions, jobName);
224}
225
226template<class Base>
227void ModelCSourceGen<Base>::generateSparseHessianSourceFromRev2(MultiThreadingType multiThreadingType) {
228 using namespace std;
229
234 std::vector<size_t> evalRows, evalCols;
235 determineSecondOrderElements4Eval(evalRows, evalCols);
236
237 std::map<size_t, CompressedVectorInfo> hessInfo;
238
239 // elements[var]{var}
240 for (size_t e = 0; e < evalRows.size(); e++) {
241 hessInfo[evalRows[e]].indexes.push_back(evalCols[e]);
242 }
243
244 // maps each element to its position in the user hessian
245 for (auto& it : hessInfo) {
246 it.second.locations = determineOrderByRow(it.first, it.second.indexes, evalRows, evalCols);
247 }
248
253 for (auto& it : hessInfo) {
254 const std::vector<size_t>& els = it.second.indexes;
255 const std::vector<set<size_t> >& location = it.second.locations;
256 CPPADCG_ASSERT_UNKNOWN(els.size() == location.size());
257 CPPADCG_ASSERT_UNKNOWN(els.size() > 0);
258
259 bool passed = true;
260 size_t hessRowStart = *location[0].begin();
261 for (size_t e = 0; e < els.size(); e++) {
262 if (location[e].size() > 1) {
263 passed = false; // too many elements
264 break;
265 }
266 if (*location[e].begin() != hessRowStart + e) {
267 passed = false; // wrong order
268 break;
269 }
270 }
271 it.second.ordered = passed;
272 }
273
277 size_t maxCompressedSize = 0;
278
279 for (const auto& it : hessInfo) {
280 if (it.second.indexes.size() > maxCompressedSize && !it.second.ordered)
281 maxCompressedSize = it.second.indexes.size();
282 }
283
284 if (!_loopTapes.empty()) {
288 generateSparseHessianWithLoopsSourceFromRev2(hessInfo, maxCompressedSize);
289 return;
290 }
291
292 string functionName = _name + "_" + FUNCTION_SPARSE_HESSIAN;
293 string functionRev2 = _name + "_" + FUNCTION_SPARSE_REVERSE_TWO;
294 string rev2Suffix = "indep";
295
296 if (!_multiThreading || multiThreadingType == MultiThreadingType::NONE) {
297 _sources[functionName + ".c"] = generateSparseHessianRev2SingleThreadSource(functionName, hessInfo, maxCompressedSize, functionRev2, rev2Suffix);
298 } else {
299 _sources[functionName + ".c"] = generateSparseHessianRev2MultiThreadSource(functionName, hessInfo, maxCompressedSize, functionRev2, rev2Suffix, multiThreadingType);
300 }
301 _cache.str("");
302}
303
304template<class Base>
305std::string ModelCSourceGen<Base>::generateSparseHessianRev2SingleThreadSource(const std::string& functionName,
306 std::map<size_t, CompressedVectorInfo> hessInfo,
307 size_t maxCompressedSize,
308 const std::string& functionRev2,
309 const std::string& rev2Suffix) {
310 LanguageC<Base> langC(_baseTypeName);
311 std::string argsDcl = langC.generateDefaultFunctionArgumentsDcl();
312 std::vector<std::string> argsDcl2 = langC.generateDefaultFunctionArgumentsDcl2();
313
314 _cache.str("");
315 _cache << "#include <stdlib.h>\n"
317 generateFunctionDeclarationSource(_cache, functionRev2, rev2Suffix, hessInfo, argsDcl);
318 _cache << "\n";
319 LanguageC<Base>::printFunctionDeclaration(_cache, "void", functionName, argsDcl2);
320 _cache << " {\n"
321 " " << _baseTypeName << " const * inLocal[3];\n"
322 " " << _baseTypeName << " inLocal1 = 1;\n"
323 " " << _baseTypeName << " * outLocal[1];\n";
324 if (maxCompressedSize > 0) {
325 _cache << " " << _baseTypeName << " compressed[" << maxCompressedSize << "];\n";
326 }
327 _cache << " " << _baseTypeName << " * hess = out[0];\n"
328 "\n"
329 " inLocal[0] = in[0];\n"
330 " inLocal[1] = &inLocal1;\n"
331 " inLocal[2] = in[1];\n";
332 if (maxCompressedSize > 0) {
333 _cache << " outLocal[0] = compressed;";
334 }
335
336 langC.setArgumentIn("inLocal");
337 langC.setArgumentOut("outLocal");
338 std::string argsLocal = langC.generateDefaultFunctionArguments();
339 bool previousCompressed = true;
340 for (auto& it : hessInfo) {
341 size_t index = it.first;
342 const std::vector<size_t>& els = it.second.indexes;
343 const std::vector<std::set<size_t> >& location = it.second.locations;
344 CPPADCG_ASSERT_UNKNOWN(els.size() == location.size());
345 CPPADCG_ASSERT_UNKNOWN(els.size() > 0);
346
347 _cache << "\n";
348 bool compressed = !it.second.ordered;
349 if (!compressed) {
350 _cache << " outLocal[0] = &hess[" << *location[0].begin() << "];\n";
351 } else if (!previousCompressed) {
352 _cache << " outLocal[0] = compressed;\n";
353 }
354 _cache << " " << functionRev2 << "_" << rev2Suffix << index << "(" << argsLocal << ");\n";
355 if (compressed) {
356 for (size_t e = 0; e < els.size(); e++) {
357 _cache << " ";
358 for (size_t itl : location[e]) {
359 _cache << "hess[" << itl << "] = ";
360 }
361 _cache << "compressed[" << e << "];\n";
362 }
363 }
364 previousCompressed = compressed;
365 }
366
367 _cache << "\n"
368 "}\n";
369 return _cache.str();
370}
371
372
373template<class Base>
375 std::map<size_t, CompressedVectorInfo> hessInfo,
376 size_t maxCompressedSize,
377 const std::string& functionRev2,
378 const std::string& rev2Suffix,
379 MultiThreadingType multiThreadingType) {
380 CPPADCG_ASSERT_UNKNOWN(_multiThreading);
381 CPPADCG_ASSERT_UNKNOWN(multiThreadingType != MultiThreadingType::NONE);
382
383 LanguageC<Base> langC(_baseTypeName);
384 std::string argsDcl = langC.generateDefaultFunctionArgumentsDcl();
385 std::vector<std::string> argsDcl2 = langC.generateDefaultFunctionArgumentsDcl2();
386
387 _cache.str("");
388 _cache << "#include <stdlib.h>\n"
390 generateFunctionDeclarationSource(_cache, functionRev2, rev2Suffix, hessInfo, argsDcl);
391
392
393 langC.setArgumentIn("inLocal");
394 langC.setArgumentOut("outLocal");
395 std::string argsLocal = langC.generateDefaultFunctionArguments();
396
400 for (const auto& it : hessInfo) {
401 size_t index = it.first;
402 const std::vector<size_t>& els = it.second.indexes;
403 const std::vector<std::set<size_t> >& location = it.second.locations;
404 CPPADCG_ASSERT_UNKNOWN(els.size() == location.size());
405
406 bool compressed = !it.second.ordered;
407 if (!compressed) {
408 continue;
409 }
410
411 std::string functionNameWrap = functionRev2 + "_" + rev2Suffix + std::to_string(index) + "_wrap";
412 LanguageC<Base>::printFunctionDeclaration(_cache, "void", functionNameWrap, argsDcl2);
413 _cache << " {\n"
414 " " << _baseTypeName << " const * inLocal[3];\n"
415 " " << _baseTypeName << " inLocal1 = 1;\n"
416 " " << _baseTypeName << " * outLocal[1];\n"
417 " " << _baseTypeName << " compressed[" << it.second.indexes.size() << "];\n"
418 " " << _baseTypeName << " * hess = out[0];\n"
419 "\n"
420 " inLocal[0] = in[0];\n"
421 " inLocal[1] = &inLocal1;\n"
422 " inLocal[2] = in[1];\n"
423 " outLocal[0] = compressed;\n";
424 _cache << " " << functionRev2 << "_" << rev2Suffix << index << "(" << argsLocal << ");\n";
425 for (size_t e = 0; e < els.size(); e++) {
426 _cache << " ";
427 for (size_t itl : location[e]) {
428 _cache << "hess[" << itl << "] = ";
429 }
430 _cache << "compressed[" << e << "];\n";
431 }
432 _cache << "}\n";
433 }
434
435 _cache << "\n"
436 "typedef void (*cppadcg_function_type) (" << argsDcl << ");\n";
437
438
439 if (multiThreadingType == MultiThreadingType::OPENMP) {
440 _cache << "\n";
441 printFileStartOpenMP(_cache);
442 _cache << "\n";
443
444 } else {
448 assert(multiThreadingType == MultiThreadingType::PTHREADS);
449
450 printFileStartPThreads(_cache, _baseTypeName);
451 }
452
456 _cache << "\n"
457 "void " << functionName << "(" << argsDcl << ") {\n"
458 " static const cppadcg_function_type p[" << hessInfo.size() << "] = {";
459 for (const auto& it : hessInfo) {
460 size_t index = it.first;
461 if (index != hessInfo.begin()->first) _cache << ", ";
462 if (it.second.ordered) {
463 _cache << functionRev2 << "_" << rev2Suffix << index;
464 } else {
465 _cache << functionRev2 << "_" << rev2Suffix << index << "_wrap";
466 }
467 }
468 _cache << "};\n"
469 " static const long offset["<< hessInfo.size() <<"] = {";
470 for (const auto& it : hessInfo) {
471 if (it.first != hessInfo.begin()->first) _cache << ", ";
472 if (it.second.ordered) {
473 _cache << *it.second.locations[0].begin();
474 } else {
475 _cache << "0";
476 }
477 }
478 _cache << "};\n"
479 " " << _baseTypeName << " inLocal1 = 1;\n"
480 " " << _baseTypeName << " const * inLocal[3] = {in[0], &inLocal1, in[1]};\n"
481 " " << _baseTypeName << " * outLocal[1];\n";
482 _cache << " " << _baseTypeName << " * hess = out[0];\n"
483 " long i;\n"
484 "\n";
485
486 if(multiThreadingType == MultiThreadingType::OPENMP) {
487 printFunctionStartOpenMP(_cache, hessInfo.size());
488 _cache << "\n";
489 printLoopStartOpenMP(_cache, hessInfo.size());
490 _cache << " outLocal[0] = &hess[offset[i]];\n"
491 " (*p[i])(" << argsLocal << ");\n";
492 printLoopEndOpenMP(_cache, hessInfo.size());
493 _cache << "\n";
494
495 } else {
496 assert(multiThreadingType == MultiThreadingType::PTHREADS);
497
498 printFunctionStartPThreads(_cache, hessInfo.size());
499 _cache << "\n"
500 " for(i = 0; i < " << hessInfo.size() << "; ++i) {\n"
501 " args[i] = (ExecArgStruct*) malloc(sizeof(ExecArgStruct));\n"
502 " args[i]->func = p[i];\n"
503 " args[i]->in = inLocal;\n"
504 " args[i]->out[0] = &hess[offset[i]];\n"
505 " args[i]->atomicFun = " << langC .getArgumentAtomic() << ";\n"
506 " }\n"
507 "\n";
508 printFunctionEndPThreads(_cache, hessInfo.size());
509 }
510
511 _cache << "\n"
512 "}\n";
513 return _cache.str();
514}
515
516template<class Base>
518 std::vector<size_t>& evalCols) {
524 evalRows.reserve(_hessSparsity.rows.size());
525 evalCols.reserve(_hessSparsity.cols.size());
526
527 for (size_t e = 0; e < _hessSparsity.rows.size(); e++) {
528 size_t i = _hessSparsity.rows[e];
529 size_t j = _hessSparsity.cols[e];
530 if (_hessSparsity.sparsity[i].find(j) == _hessSparsity.sparsity[i].end() &&
531 _hessSparsity.sparsity[j].find(i) != _hessSparsity.sparsity[j].end()) {
532 // only the symmetric value is available
533 // (it can be caused by atomic functions which may only be providing a partial hessian)
534 evalRows.push_back(j);
535 evalCols.push_back(i);
536 } else {
537 evalRows.push_back(i);
538 evalCols.push_back(j);
539 }
540 }
541}
542
543template<class Base>
545 if (_hessSparsity.sparsity.size() > 0) {
546 return;
547 }
548
549 size_t m = _fun.Range();
550 size_t n = _fun.Domain();
551
555 SparsitySetType r(n); // identity matrix
556 for (size_t j = 0; j < n; j++)
557 r[j].insert(j);
558 SparsitySetType jac = _fun.ForSparseJac(n, r);
559
560 SparsitySetType s(1);
561 for (size_t i = 0; i < m; i++) {
562 s[0].insert(i);
563 }
564 _hessSparsity.sparsity = _fun.RevSparseHes(n, s, false);
565 //printSparsityPattern(_hessSparsity.sparsity, "hessian");
566
567 if (_hessianByEquation || _reverseTwo) {
572 std::set<size_t> customVarsInHess;
573 if (_custom_hess.defined) {
574 customVarsInHess.insert(_custom_hess.row.begin(), _custom_hess.row.end());
575 customVarsInHess.insert(_custom_hess.col.begin(), _custom_hess.col.end());
576
577 r = SparsitySetType(n); //clear r
578 for (size_t j : customVarsInHess) {
579 r[j].insert(j);
580 }
581 jac = _fun.ForSparseJac(n, r);
582 }
583
587 const std::vector<Color> colors = colorByRow(customVarsInHess, jac);
588
592 _hessSparsities.resize(m);
593 for (size_t i = 0; i < m; i++) {
594 _hessSparsities[i].sparsity.resize(n);
595 }
596
597 for (size_t c = 0; c < colors.size(); c++) {
598 const Color& color = colors[c];
599
600 // first-order
601 r = SparsitySetType(n); //clear r
602 for (size_t j : color.forbiddenRows) {
603 r[j].insert(j);
604 }
605 _fun.ForSparseJac(n, r);
606
607 // second-order
608 s[0].clear();
609 const std::set<size_t>& equations = color.rows;
610 for (size_t i : equations) {
611 s[0].insert(i);
612 }
613
614 SparsitySetType sparsityc = _fun.RevSparseHes(n, s, false);
615
619 const std::map<size_t, size_t>& var2Eq = color.column2Row;
620 for (size_t j : color.forbiddenRows) { //used variables
621 if (sparsityc[j].size() > 0) {
622 size_t i = var2Eq.at(j);
623 _hessSparsities[i].sparsity[j].insert(sparsityc[j].begin(),
624 sparsityc[j].end());
625 }
626 }
627
628 }
629
630 for (size_t i = 0; i < m; i++) {
631 LocalSparsityInfo& hessSparsitiesi = _hessSparsities[i];
632
633 if (!_custom_hess.defined) {
634 generateSparsityIndexes(hessSparsitiesi.sparsity,
635 hessSparsitiesi.rows, hessSparsitiesi.cols);
636
637 } else {
638 size_t nnz = _custom_hess.row.size();
639 for (size_t e = 0; e < nnz; e++) {
640 size_t i1 = _custom_hess.row[e];
641 size_t i2 = _custom_hess.col[e];
642 if (hessSparsitiesi.sparsity[i1].find(i2) != hessSparsitiesi.sparsity[i1].end()) {
643 hessSparsitiesi.rows.push_back(i1);
644 hessSparsitiesi.cols.push_back(i2);
645 }
646 }
647 }
648 }
649
650 }
651
652 if (!_custom_hess.defined) {
653 generateSparsityIndexes(_hessSparsity.sparsity,
654 _hessSparsity.rows, _hessSparsity.cols);
655
656 } else {
657 _hessSparsity.rows = _custom_hess.row;
658 _hessSparsity.cols = _custom_hess.col;
659 }
660}
661
662template<class Base>
664 determineHessianSparsity();
665
666 generateSparsity2DSource(_name + "_" + FUNCTION_HESSIAN_SPARSITY, _hessSparsity);
667 _sources[_name + "_" + FUNCTION_HESSIAN_SPARSITY + ".c"] = _cache.str();
668 _cache.str("");
669
670 if (_hessianByEquation || _reverseTwo) {
671 generateSparsity2DSource2(_name + "_" + FUNCTION_HESSIAN_SPARSITY2, _hessSparsities);
672 _sources[_name + "_" + FUNCTION_HESSIAN_SPARSITY2 + ".c"] = _cache.str();
673 _cache.str("");
674 }
675}
676
677} // END cg namespace
678} // END CppAD namespace
679
680#endif
void makeVariables(VectorCG &variables)
virtual void generateCode(std::ostream &out, Language< Base > &lang, CppAD::vector< CGB > &dependent, VariableNameGenerator< Base > &nameGen, const std::string &jobName="source")
virtual void setParameterPrecision(size_t p)
static void printFunctionDeclaration(std::ostringstream &out, const std::string &returnType, const std::string &functionName, const std::vector< std::string > &arguments, const std::vector< std::string > &arguments2={})
void setMaxOperationsPerAssignment(size_t maxOperationsPerAssignment)
virtual void setMaxAssignmentsPerFunction(size_t maxAssignmentsPerFunction, std::map< std::string, std::string > *sources)
std::set< size_t > rows
all row with this color
std::set< size_t > forbiddenRows
used columns
std::map< size_t, size_t > column2Row
maps column indexes to the corresponding row
virtual std::string generateSparseHessianRev2MultiThreadSource(const std::string &functionName, std::map< size_t, CompressedVectorInfo > hessInfo, size_t maxCompressedSize, const std::string &functionRev2, const std::string &rev2Suffix, MultiThreadingType multiThreadingType)
virtual void determineSecondOrderElements4Eval(std::vector< size_t > &userRows, std::vector< size_t > &userCols)
virtual void generateSparseHessianSourceFromRev2(MultiThreadingType multiThreadingType)
virtual void generateSparseHessianSource(MultiThreadingType multiThreadingType)