61 using namespace CppAD::cg::loops;
63 size_t nonIndexdedEqSize = _funNoLoops !=
nullptr ? _funNoLoops->getOrigDependentIndexes().size() : 0;
69 l->evalJacobianSparsity();
70 l->evalHessianSparsity();
73 if (_funNoLoops !=
nullptr) {
74 _funNoLoops->evalJacobianSparsity();
75 _funNoLoops->evalHessianSparsity();
78 size_t m = _fun.Range();
79 size_t n = _fun.Domain();
93 loopHessInfol.noLoopEvalHessTempsSparsity.resize(_funNoLoops !=
nullptr ?
n : 0);
113 for (
size_t eh = 0;
eh < nnz;
eh++) {
118 if (_funNoLoops !=
nullptr) {
120 const std::vector<std::set<size_t> >&
dydxx = _funNoLoops->getHessianOrigEqsSparsity();
121 if (!
dydxx.empty()) {
133 size_t nIter =
loop->getIterationCount();
135 const std::vector<IterEquationGroup<Base> >&
eqGroups =
loop->getEquationsGroups();
136 const std::vector<set<size_t> >&
loopJac =
loop->getJacobianSparsity();
153 const std::vector<set<size_t> >&
groupHess = group.getHessianSparsity();
161 for (
size_t iteration = 0; iteration <
iter2tapeJJ.size(); iteration++) {
176 std::vector<HessianElement>&
positions =
loopInfo.equationGroups[
g].indexedIndexedPositions[tape];
183 loopInfo.equationGroups[
g].evalHessSparsity[tape.first].insert(tape.second);
193 if (
posJ2 !=
nullptr) {
195 const std::vector<set<size_t> >&
iter2tapeJ1OrigJ2 = group.getHessianIndexedNonIndexedTapeIndexes(
j1,
j2);
213 (*positions)[iteration].location =
e;
214 (*positions)[iteration].row =
j1;
215 (*positions)[iteration].count++;
227 if (_funNoLoops !=
nullptr) {
230 size_t iteration =
itIter.first;
232 const set<const IterEquationGroup<Base>*>&
groups =
loop->getIterationEquationsGroup()[iteration];
239 const std::vector<set<size_t> >&
groupHess = group.getHessianSparsity();
254 const set<size_t>& sparsity = _funNoLoops->getJacobianSparsity()[
nonIndexdedEqSize +
k];
255 if (sparsity.find(
j2) != sparsity.end()) {
258 size_t tapeK =
loop->getTempIndepIndexes(
k)->tape;
291 if (
posJ1 !=
nullptr) {
296 const std::vector<set<size_t> >&
iter2TapeJ2 = group.getHessianNonIndexedIndexedTapeIndexes(
j1,
j2);
297 for (
size_t iteration = 0; iteration <
iter2TapeJ2.size(); iteration++) {
325 const set<pairss>&
orig1orig2 = group.getHessianNonIndexedNonIndexedIndexes();
329 loopInfo.equationGroups[
g].nonIndexedNonIndexedEvals.insert(
orig);
344 if (_funNoLoops !=
nullptr &&
posJ1 !=
nullptr) {
349 const set<size_t>&
hessRow = group.getHessianSparsity()[
posJ1->tape];
364 CPPADCG_ASSERT_KNOWN(
loopInfo.nonIndexedNonIndexedPosition.find(
orig) ==
loopInfo.nonIndexedNonIndexedPosition.end(),
365 "Repeated hessian elements requested")
369 size_t tapeK =
loop->getTempIndepIndexes(
k)->tape;
381 if (_funNoLoops !=
nullptr) {
382 const std::vector<set<size_t> >&
gJac = _funNoLoops->getJacobianSparsity();
383 size_t nk = _funNoLoops->getTemporaryDependentCount();
384 size_t nOrigEq = _funNoLoops->getTapeDependentCount() -
nk;
386 const std::vector<set<size_t> >&
dzdxx = _funNoLoops->getHessianTempEqsSparsity();
390 for (
size_t k1 = 0;
k1 <
nk;
k1++) {
396 if (
posK1 ==
nullptr) {
408 const std::vector<set<size_t> >&
groupHess = group.getHessianSparsity();
411 const map<size_t, set<size_t> >&
tapeJ22Iter = group.getHessianTempIndexedTapeIndexes(
k1,
j2);
414 const set<size_t>& iterations =
ittj22iter.second;
419 for (
size_t iteration : iterations) {
420 std::vector<HessianElement>*
positions =
nullptr;
440 (*positions)[iteration].location =
e;
441 (*positions)[iteration].row =
j1;
442 (*positions)[iteration].count++;
460 if (
posJ2 !=
nullptr) {
461 const set<size_t>&
hessRow = group.getHessianSparsity()[
posK1->tape];
466 CPPADCG_ASSERT_KNOWN(
loopInfo.nonIndexedNonIndexedPosition.find(
orig) ==
loopInfo.nonIndexedNonIndexedPosition.end(),
467 "Repeated hessian elements requested")
483 const set<size_t>&
hessRow = group.getHessianSparsity()[
posK1->tape];
494 CPPADCG_ASSERT_KNOWN(
loopInfo.nonIndexedNonIndexedPosition.find(
orig) ==
loopInfo.nonIndexedNonIndexedPosition.end(),
495 "Repeated hessian elements requested")
522 CPPADCG_ASSERT_KNOWN(
loopInfo.nonIndexedNonIndexedPosition.find(
orig) ==
loopInfo.nonIndexedNonIndexedPosition.end(),
523 "Repeated hessian elements requested")
559 std::vector<CGBase>& x,
560 std::vector<CGBase>& w,
566 using namespace CppAD::cg::loops;
568 handler.setZeroDependents(
true);
570 size_t nonIndexdedEqSize = _funNoLoops !=
nullptr ? _funNoLoops->getOrigDependentIndexes().size() : 0;
572 size_t maxLoc = _hessSparsity.rows.size();
573 std::vector<CGBase> hess(
maxLoc);
599 if (_funNoLoops !=
nullptr) {
646 _cache <<
"model (Jacobian + Hessian, loop " <<
lModel.getLoopId() <<
")";
647 std::string
jobName = _cache.str();
649 startingJob(
"'" +
jobName +
"'", JobTimer::GRAPH);
661 map<size_t, map<size_t, CGBase> >
dzDx;
663 if (_funNoLoops !=
nullptr) {
665 std::vector<CGBase>
yNL(
fun.Range());
670 startingJob(
"'model (Jacobian + Hessian, temporaries)'", JobTimer::GRAPH);
672 dzDx = _funNoLoops->calculateJacobianHessianUsedByLoops(
handler,
691 _funNoLoops->calculateHessian4OrignalEquations(x, w,
706 for (
size_t g = 0;
g <
info.equationGroups.size();
g++) {
709 infog.indexedTempPositions.size() +
710 infog.nonIndexedIndexedPositions.size();
722 for (
size_t g = 0;
g <
info.equationGroups.size();
g++) {
729 for (
const auto&
it :
infog.indexedIndexedPositions) {
732 const std::vector<HessianElement>&
positions =
it.second;
736 *
info.iterationIndexOp,
info.ifElses));
743 for (
const auto&
it :
infog.indexedNonIndexedPositions) {
746 const std::vector<HessianElement>&
positions =
it.second;
750 *
info.iterationIndexOp,
info.ifElses));
756 if (!
infog.indexedTempPositions.empty()) {
757 for (
const auto&
itEval :
infog.indexedTempEvals) {
760 const set<size_t>&
ks =
itEval.second;
763 if (
itPos !=
infog.indexedTempPositions.end()) {
767 for (
size_t k :
ks) {
774 *
info.iterationIndexOp,
info.ifElses));
782 for (
const auto&
it :
infog.nonIndexedIndexedPositions) {
785 const std::vector<HessianElement>&
positions =
it.second;
789 *
info.iterationIndexOp,
info.ifElses));
800 if (!
infog.tempIndexedPositions.empty()) {
801 for (
const auto&
itEval :
infog.indexedTempEvals) {
804 const set<size_t>&
ks =
itEval.second;
807 if (
itPos !=
infog.tempIndexedPositions.end()) {
810 for (
size_t k :
ks) {
817 *
info.iterationIndexOp,
info.ifElses));
827 for (
const auto&
orig2PosIt :
info.nonIndexedNonIndexedPosition) {
838 handler.manageLoopDependentIndexPattern(pattern);
848 for (
size_t g = 0;
g <
info.equationGroups.size();
g++) {
854 if (
infog.nonIndexedNonIndexedEvals.find(
orig) !=
infog.nonIndexedNonIndexedEvals.end()) {
862 if (
itNT !=
infog.nonIndexedTempEvals.end()) {
863 const set<size_t>&
ks =
itNT->second;
865 for (
size_t k :
ks) {
878 if (
itTN !=
infog.tempNonIndexedEvals.end()) {
879 const set<size_t>&
ks =
itTN->second;
881 for (
size_t k1 :
ks) {
892 const map<size_t, set<size_t> >&
k1k2 =
itTT->second;
898 const set<size_t>&
k2s =
itzz.second;
902 for (
size_t k2 :
k2s) {
917 *
info.iterationIndexOp,
info.ifElses);
928 const auto itTT2 =
info.nonLoopNonIndexedNonIndexed.find(
orig);
929 if (
itTT2 !=
info.nonLoopNonIndexedNonIndexed.end()) {
949 if (hess[
e].isIdenticalZero()) {
952 }
else if (hess[
e].getOperationNode() !=
nullptr && hess[
e].getOperationNode()->getOperationType() == CGOpCode::DependentMultiAssign) {
953 hess[
e].getOperationNode()->getArguments().push_back(*
info.loopEnd);
956 hess[
e] =
handler.createCG(*
handler.makeNode(CGOpCode::DependentMultiAssign,{asArgument(hess[e]), *info.loopEnd}));
961 for (
size_t g = 0;
g <
info.equationGroups.size();
g++) {
962 info.equationGroups[
g].hess.clear();
977 if (hess[
it2.second].isVariable())
980 hess[
it2.first] = hess[
it2.second].getValue();