33 using namespace CppAD::cg::loops;
37 size_t n = _fun.Domain();
41 handler.setZeroDependents(
false);
48 std::vector<OperationNode<Base>*>
localNodes(4);
54 size_t nonIndexdedEqSize = _funNoLoops !=
nullptr ? _funNoLoops->getOrigDependentIndexes().size() : 0;
59 map<LoopModel<Base>*, std::vector<JacobianWithLoopsRowInfo> >
loopEqInfo;
61 size_t nnz = _jacSparsity.rows.size();
62 std::vector<size_t> rows(nnz);
63 std::vector<size_t> cols(nnz);
64 std::vector<size_t> locations(nnz);
67 for (
const auto&
itI : elements) {
69 const std::vector<size_t>&
r =
itI.second;
71 for (
size_t e = 0;
e <
r.size();
e++) {
78 CPPADCG_ASSERT_UNKNOWN(
p == nnz);
80 analyseSparseJacobianWithLoops(rows, cols, locations,
83 std::vector<CGBase> x(
n);
86 for (
size_t i = 0;
i <
n;
i++) {
94 py.setValue(Base(1.0));
105 std::vector<CGBase>
tmps;
108 std::vector<map<size_t, CGBase> >
dzDx(_funNoLoops !=
nullptr ? _funNoLoops->getTemporaryDependentCount() : 0);
113 if (_funNoLoops !=
nullptr) {
119 std::vector<CGBase>
depNL = _funNoLoops->getTape().Forward(0, x);
122 for (
size_t i = 0;
i <
tmps.size();
i++)
131 const std::vector<size_t>&
dependentIndexes = _funNoLoops->getOrigDependentIndexes();
132 map<size_t, std::vector<CGBase> >
jacNl;
138 std::vector<CGBase>& row =
jacNl[
i];
142 size_t j =
itjv.first;
146 CPPADCG_ASSERT_UNKNOWN(locations.size() == 1);
147 size_t e = *locations.begin();
151 _nonLoopRev1Elements[
i].insert(
e);
160 size_t j =
itjv.first;
168 typename map<size_t, std::vector<CGBase> >::iterator
itJ;
170 createReverseOneWithLoopsNL(
handler,
itJ->first,
itJ->second);
177 typename map<LoopModel<Base>*, std::vector<JacobianWithLoopsRowInfo> >::iterator
itl2Eq;
180 const std::vector<JacobianWithLoopsRowInfo>&
info =
itl2Eq->second;
186 _cache <<
"model (reverse one, loop " <<
lModel.getLoopId() <<
")";
187 std::string
jobName = _cache.str();
192 startingJob(
"'" +
jobName +
"'", JobTimer::GRAPH);
206 for (
size_t tapeI = 0; tapeI <
info.size(); tapeI++) {
219 if (
i < _fun.Range())
234 std::vector<IfElseInfo<Base> > ifElses;
240 iterationIndexOp, ifElses,
260 if (
i < _fun.Range()) {
263 for (
const auto&
itc :
rowInfo.indexedPositions) {
265 if (
positionsC[
it] != (std::numeric_limits<size_t>::max)())
268 for (
const auto&
itc :
rowInfo.nonIndexedPositions) {
270 if (
positionsC[
it] != (std::numeric_limits<size_t>::max)())
284 langC.setParameterPrecision(_parameterPrecision);
287 std::ostringstream
code;
288 std::unique_ptr<VariableNameGenerator<Base> > nameGen(createVariableNameGenerator(
"dw"));
295 _cache <<
"model (reverse one, loop " <<
lModel.getLoopId() <<
", group " << tapeI <<
")";
300 generateFunctionNameLoopRev1(_cache,
lModel, tapeI);
303 std::string
argsDcl =
langC.generateFunctionArgumentsDcl();
306 _cache <<
"#include <stdlib.h>\n"
307 "#include <math.h>\n"
312 nameGenHess.customFunctionVariableDeclarations(_cache);
313 _cache <<
langC.generateIndependentVariableDeclaration() <<
"\n";
314 _cache <<
langC.generateDependentVariableDeclaration() <<
"\n";
315 _cache <<
langC.generateTemporaryVariableDeclaration(
false,
false,
316 handler.getExternalFuncMaxForwardOrder(),
317 handler.getExternalFuncMaxReverseOrder()) <<
"\n";
318 nameGenHess.prepareCustomFunctionVariables(_cache);
321 _cache <<
code.str();
323 nameGenHess.finalizeCustomFunctionVariables(_cache);
342 string functionRev1 = _name +
"_" + FUNCTION_SPARSE_REVERSE_ONE;
343 _sources[
functionRev1 +
".c"] = generateGlobalForRevWithLoopsFunctionSource(elements,
344 _loopRev1Groups, _nonLoopRev1Elements,
346 generateFunctionNameLoopRev1);
351 generateSparsity1DSource2(_name +
"_" + FUNCTION_REVERSE_ONE_SPARSITY, elements);
352 _sources[_name +
"_" + FUNCTION_REVERSE_ONE_SPARSITY +
".c"] = _cache.str();