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