31 using pairss = std::pair<size_t, size_t>;
33 static const std::string ITERATION_INDEX_NAME;
35 static const std::set<size_t> EMPTYSET;
45 const bool containsAtoms_;
49 const size_t iterationCount_;
57 std::vector<std::vector<LoopPosition> > dependentIndexes_;
61 std::vector<std::vector<LoopPosition> > indexedIndepIndexes_;
65 std::vector<LoopPosition> nonIndexedIndepIndexes_;
70 std::vector<LoopPosition> temporaryIndependents_;
75 std::map<size_t, LoopIndexedPosition> depOrigIndexes_;
79 std::vector<IterEquationGroup<Base> > equationGroups_;
80 std::vector<std::set<const IterEquationGroup<Base>*> > iteration2eqGroups_;
84 std::vector<std::map<size_t, std::set<size_t> > > iteration2orig2indexedIndepIndexes_;
88 std::map<size_t, LoopPosition*> orig2nonIndexedIndepIndexes_;
92 std::map<size_t, LoopPosition*> orig2tempIndepIndexes_;
96 std::vector<IndexPattern*> indepIndexPatterns_;
100 std::vector<IndexPattern*> depIndexPatterns_;
104 std::vector<std::set<size_t> > jacTapeSparsity_;
109 std::vector<std::set<size_t> > hessTapeSparsity_;
132 loopId_(createNewLoopId()),
143 hessSparsity_(
false) {
144 CPPADCG_ASSERT_KNOWN(
fun !=
nullptr,
"fun cannot be null");
149 for (
size_t i = 0;
i < m_;
i++) {
150 for (
size_t it = 0;
it < iterationCount_;
it++) {
153 if (
orig != (std::numeric_limits<size_t>::max)())
155 dependentIndexes_[
i][
it].original,
165 size_t lm = dependentIndexes_.size();
167 for (
size_t i = 0;
i <
lm;
i++) {
168 std::set<size_t> iterations;
169 for (
size_t it = 0;
it < iterationCount_;
it++) {
170 if (dependentIndexes_[
i][
it].original != (std::numeric_limits<size_t>::max)()) {
171 iterations.insert(
it);
178 iteration2eqGroups_.resize(iterationCount_);
183 const std::set<size_t>& iterations =
itEqeIt->first;
192 for (
size_t itIt : iterations) {
193 iteration2eqGroups_[
itIt].insert(&group);
203 for (
size_t it = 0;
it < iterationCount_;
it++) {
207 if (
orig != (std::numeric_limits<size_t>::max)())
208 iteration2orig2indexedIndepIndexes_[
it][
orig].insert(
j);
217 orig2nonIndexedIndepIndexes_[
orig] = &nonIndexedIndepIndexes_[
j];
224 orig2tempIndepIndexes_[
k] = &temporaryIndependents_[
j];
246 return containsAtoms_;
255 return iterationCount_;
285 return fun_->Domain();
292 return dependentIndexes_;
299 return equationGroups_;
302 inline const std::vector<std::set<const IterEquationGroup<Base>*> >& getIterationEquationsGroup()
const {
303 return iteration2eqGroups_;
310 return indexedIndepIndexes_;
317 return nonIndexedIndepIndexes_;
325 return temporaryIndependents_;
335 return depOrigIndexes_.at(
origI);
338 inline const std::map<size_t, LoopIndexedPosition>& getOriginalDependentIndexes()
const {
339 return depOrigIndexes_;
346 std::map<size_t, LoopPosition*>::const_iterator
it = orig2nonIndexedIndepIndexes_.find(
origJ);
347 if (
it != orig2nonIndexedIndepIndexes_.end()) {
358 std::map<size_t, LoopPosition*>::const_iterator
it = orig2tempIndepIndexes_.find(
k);
359 if (
it != orig2tempIndepIndexes_.end()) {
375 CPPADCG_ASSERT_UNKNOWN(iteration < iteration2orig2indexedIndepIndexes_.size());
377 const std::map<size_t, std::set<size_t> >&
itOrigs = iteration2orig2indexedIndepIndexes_[iteration];
378 std::map<size_t, std::set<size_t> >::const_iterator
it =
itOrigs.find(
origJ);
397 const std::map<size_t, std::set<size_t> >&
itOrigs = iteration2orig2indexedIndepIndexes_[
iter];
398 std::map<size_t, std::set<size_t> >::const_iterator
it =
itOrigs.find(
origJ);
407 inline void detectIndexPatterns() {
408 if (indepIndexPatterns_.size() > 0)
411 indepIndexPatterns_.resize(indexedIndepIndexes_.size());
412 for (
size_t j = 0;
j < indepIndexPatterns_.size();
j++) {
413 std::map<size_t, size_t> indexes;
414 for (
size_t it = 0;
it < iterationCount_;
it++) {
415 size_t orig = indexedIndepIndexes_[
j][
it].original;
416 if (
orig != (std::numeric_limits<size_t>::max)())
422 depIndexPatterns_.resize(dependentIndexes_.size());
423 for (
size_t j = 0;
j < depIndexPatterns_.size();
j++) {
424 std::map<size_t, size_t> indexes;
425 for (
size_t it = 0;
it < iterationCount_;
it++) {
426 size_t e = dependentIndexes_[
j][
it].original;
427 if (
e != (std::numeric_limits<size_t>::max)())
435 inline const std::vector<IndexPattern*>& getDependentIndexPatterns()
const {
436 return depIndexPatterns_;
439 inline const std::vector<IndexPattern*>& getIndependentIndexPatterns()
const {
440 return indepIndexPatterns_;
443 inline bool isTemporary(
size_t tapeJ)
const {
444 size_t nIndexed = indexedIndepIndexes_.size();
445 size_t nNonIndexed = nonIndexedIndepIndexes_.size();
450 inline bool isIndexedIndependent(
size_t tapeJ)
const {
451 return tapeJ < indexedIndepIndexes_.size();
454 inline void evalJacobianSparsity() {
461 inline const std::vector<std::set<size_t> >& getJacobianSparsity()
const {
462 return jacTapeSparsity_;
465 inline void evalHessianSparsity() {
466 if (!hessSparsity_) {
467 size_t n = fun_->Domain();
468 hessTapeSparsity_.resize(
n);
470 for (
size_t g = 0;
g < equationGroups_.size();
g++) {
471 equationGroups_[
g].evalHessianSparsity();
472 const std::vector<std::set<size_t> >&
ghess = equationGroups_[
g].getHessianSparsity();
473 for (
size_t j = 0;
j <
n;
j++) {
474 hessTapeSparsity_[
j].insert(
ghess[
j].begin(),
ghess[
j].end());
478 hessSparsity_ =
true;
482 inline const std::vector<std::set<size_t> >& getHessianSparsity()
const {
483 return hessTapeSparsity_;
486 virtual ~LoopModel() {
488 for (
size_t i = 0;
i < indepIndexPatterns_.size();
i++) {
489 delete indepIndexPatterns_[
i];
491 for (
size_t i = 0;
i < depIndexPatterns_.size();
i++) {
492 delete depIndexPatterns_[
i];
496 static inline void printOriginalVariableIndexes(std::ostringstream&
ss,
497 const std::vector<LoopPosition>& indexes) {
500 ss << indexes[
iter].original;
506 static size_t createNewLoopId() {
508 static size_t count = 0;
LoopModel(ADFun< CGB > *fun, bool containsAtoms, size_t iterationCount, const std::vector< std::vector< size_t > > &dependentOrigIndexes, const std::vector< std::vector< size_t > > &indexedIndepOrigIndexes, const std::vector< size_t > &nonIndexedIndepOrigIndexes, const std::vector< size_t > &temporaryIndependents)