39 const std::vector<size_t>& cols,
40 const std::vector<size_t>& location,
47 using namespace loops;
49 CPPADCG_ASSERT_UNKNOWN(rows.size() == cols.size());
50 CPPADCG_ASSERT_UNKNOWN(rows.size() == location.size());
56 l->evalJacobianSparsity();
59 if (_funNoLoops !=
nullptr)
60 _funNoLoops->evalJacobianSparsity();
65 size_t nonIndexdedEqSize = _funNoLoops !=
nullptr ? _funNoLoops->getOrigDependentIndexes().size() : 0;
66 noLoopEvalSparsity.resize(_funNoLoops !=
nullptr ? _funNoLoops->getTapeDependentCount() : 0);
77 size_t nnz = rows.size();
82 for (
size_t el = 0;
el < nnz;
el++) {
85 size_t e = location[
el];
94 const std::map<size_t, LoopIndexedPosition>&
depIndexes = l->getOriginalDependentIndexes();
98 tapeI =
iti->second.tape;
99 iteration =
iti->second.iteration;
104 if (
loop ==
nullptr) {
108 CPPADCG_ASSERT_UNKNOWN(_funNoLoops !=
nullptr);
109 size_t il = _funNoLoops->getLocalDependentIndex(
i);
118 size_t iterations =
loop->getIterationCount();
127 const std::vector<std::set<size_t> >&
loopSparsity =
loop->getJacobianSparsity();
138 const std::set<size_t>&
tapeJs =
loop->getIndexedTapeIndexes(iteration,
j);
145 positions.resize(iterations, (std::numeric_limits<size_t>::max)());
146 if (
positions[iteration] != (std::numeric_limits<size_t>::max)()) {
147 throw CGException(
"Repeated Jacobian elements requested (equation ",
i,
", variable ",
j,
")");
163 positions.resize(iterations, (std::numeric_limits<size_t>::max)());
164 if (
positions[iteration] != (std::numeric_limits<size_t>::max)()) {
165 throw CGException(
"Repeated Jacobian elements requested (equation ",
i,
", variable ",
j,
")");
177 if (_funNoLoops !=
nullptr) {
189 const set<size_t>& sparsity = _funNoLoops->getJacobianSparsity()[
nonIndexdedEqSize +
k];
190 if (sparsity.find(
j) != sparsity.end()) {
194 positions.resize(iterations, (std::numeric_limits<size_t>::max)());
195 if (
positions[iteration] != (std::numeric_limits<size_t>::max)()) {
196 throw CGException(
"Repeated Jacobian elements requested (equation ",
i,
", variable ",
j,
")");
218 const std::vector<CGBase>& x,
221 using namespace CppAD::cg::loops;
224 handler.setZeroDependents(
true);
226 size_t nonIndexdedEqSize = _funNoLoops !=
nullptr ? _funNoLoops->getOrigDependentIndexes().size() : 0;
231 map<LoopModel<Base>*, std::vector<JacobianWithLoopsRowInfo> >
loopEqInfo;
233 size_t nnz = _jacSparsity.rows.size();
234 std::vector<size_t> locations(nnz);
235 for (
size_t e = 0;
e < nnz;
e++)
238 analyseSparseJacobianWithLoops(_jacSparsity.rows, _jacSparsity.cols, locations,
242 std::vector<CGBase> jac(nnz);
252 std::vector<CGBase>
tmps;
255 std::vector<map<size_t, CGBase> >
dzDx(_funNoLoops !=
nullptr ? _funNoLoops->getTemporaryDependentCount() : 0);
259 if (_funNoLoops !=
nullptr) {
265 std::vector<CGBase>
depNL = _funNoLoops->getTape().Forward(0, x);
268 for (
size_t i = 0;
i <
tmps.size();
i++)
274 std::vector<size_t> row, col;
280 fun.SparseJacobianForward(x, _funNoLoops->getJacobianSparsity(), row, col,
jacNoLoop,
work);
282 fun.SparseJacobianReverse(x, _funNoLoops->getJacobianSparsity(), row, col,
jacNoLoop,
work);
285 for (
size_t el = 0;
el < row.size();
el++) {
291 for (
size_t itE : locations)
309 typename map<LoopModel<Base>*, std::vector<JacobianWithLoopsRowInfo> >::iterator
itl2Eq;
312 std::vector<JacobianWithLoopsRowInfo>&
eqs =
itl2Eq->second;
315 std::vector<IfElseInfo<Base> > ifElses;
323 std::set<IndexOperationNode<Base>*>
indexesOps;
332 std::vector<size_t> row, col;
336 if (row.size() == 0) {
348 std::vector<std::map<size_t, CGBase> >
dyiDxtape(
lModel.getTapeDependentCount());
350 size_t tapeI = row[
el];
360 for (
size_t tapeI = 0; tapeI <
eqs.size(); tapeI++) {
370 for (
size_t tapeI = 0; tapeI <
eqs.size(); tapeI++) {
377 *iterationIndexOp, ifElses,
391 jac[
e] =
handler.createCG(*
handler.makeNode(CGOpCode::DependentRefRhs,{e}, {*loopEnd}));
397 moveNonIndexedOutsideLoop(
handler, *loopStart, *loopEnd);
408 const std::vector<std::map<size_t, CGBase> >&
dyiDxtape,
409 const std::vector<std::map<size_t, CGBase> >&
dzDx,
417 using namespace loops;
430 jacVal, iterationIndexOp, ifElses,
446 if (
pos !=
nullptr) {
457 const std::set<size_t>&
ks =
itks->second;
458 for (
size_t k :
ks) {
468 jacVal, iterationIndexOp, ifElses,
void prepareSparseJacobianRowWithLoops(CodeHandler< Base > &handler, LoopModel< Base > &lModel, size_t tapeI, const loops::JacobianWithLoopsRowInfo &rowInfo, const std::vector< std::map< size_t, CGBase > > &dyiDxtape, const std::vector< std::map< size_t, CGBase > > &dzDx, const CGBase &py, IndexOperationNode< Base > &iterationIndexOp, std::vector< loops::IfElseInfo< Base > > &ifElses, size_t &jacLE, std::vector< std::pair< CG< Base >, IndexPattern * > > &indexedLoopResults, std::set< size_t > &allLocations)
void analyseSparseJacobianWithLoops(const std::vector< size_t > &rows, const std::vector< size_t > &cols, const std::vector< size_t > &location, SparsitySetType &noLoopEvalSparsity, std::vector< std::map< size_t, std::set< size_t > > > &noLoopEvalLocations, std::map< LoopModel< Base > *, SparsitySetType > &loopsEvalSparsities, std::map< LoopModel< Base > *, std::vector< loops::JacobianWithLoopsRowInfo > > &loopEqInfo)