1 #ifndef CPPAD_CG_LOOP_FREE_MODEL_INCLUDED 2 #define CPPAD_CG_LOOP_FREE_MODEL_INCLUDED 31 using Arg = Argument<Base>;
32 using VectorSet = std::vector<std::set<size_t> >;
42 std::map<size_t, size_t> dependentOrig2Local;
69 const std::vector<size_t>& dependentOrigIndexes) :
71 dependentIndexes_(dependentOrigIndexes),
73 hessSparsity_(false) {
74 CPPADCG_ASSERT_KNOWN(fun !=
nullptr,
"fun cannot be null");
75 CPPADCG_ASSERT_KNOWN(dependentOrigIndexes.size() <= fun->Range(),
"invalid size");
77 for (
size_t il = 0; il < dependentIndexes_.size(); il++)
78 dependentOrig2Local[dependentIndexes_[il]] = il;
88 inline size_t getTapeDependentCount()
const {
92 inline size_t getTemporaryDependentCount()
const {
93 return fun_->Range() - dependentIndexes_.size();
96 inline size_t getTapeIndependentCount()
const {
97 return fun_->Domain();
108 inline size_t getLocalDependentIndex(
size_t origI)
const {
109 return dependentOrig2Local.at(origI);
112 inline void evalJacobianSparsity() {
114 jacTapeSparsity_ = jacobianSparsitySet<VectorSet, CGB>(*fun_);
119 inline const VectorSet& getJacobianSparsity()
const {
123 inline void evalHessianSparsity() {
124 if (!hessSparsity_) {
125 size_t mo = dependentIndexes_.size();
126 size_t m = fun_->Range();
127 size_t n = fun_->Domain();
130 std::set<size_t> eqs;
132 for (
size_t i = 0; i < mo; i++)
133 eqs.insert(eqs.end(), i);
135 hessTapeOrigEqSparsity_ = hessianSparsitySet<std::vector<std::set<size_t> >,
CGB>(*
fun_, eqs);
141 for (
size_t i = mo; i < m; i++)
142 eqs.insert(eqs.end(), i);
143 hessTapeTempSparsity_ = hessianSparsitySet<std::vector<std::set<size_t> >,
CGB>(*
fun_, eqs);
145 hessTapeTempSparsity_.resize(n);
148 hessSparsity_ =
true;
152 inline const VectorSet& getHessianTempEqsSparsity()
const {
153 CPPADCG_ASSERT_UNKNOWN(hessSparsity_);
157 inline const VectorSet& getHessianOrigEqsSparsity()
const {
158 CPPADCG_ASSERT_UNKNOWN(hessSparsity_);
173 const std::set<size_t>& iterations,
179 if (iterations.size() == iterCount) {
187 if (value.isIdenticalZero())
197 set<size_t> usedIter;
198 OperationNode<Base>* cond = loops::createIndexConditionExpressionOp<Base>(handler, iterations, usedIter, iterCount - 1, iterationIndexOp);
203 OperationNode<Base>* tmpAssign1 = handler.makeNode(CGOpCode::LoopIndexedTmp,{tmpArg, asArgument(value)});
204 OperationNode<Base>* ifAssign = handler.makeNode(CGOpCode::CondResult,{*ifStart, *tmpAssign1});
209 OperationNode<Base>* tmpAssign2 = handler.makeNode(CGOpCode::LoopIndexedTmp,{tmpArg, Base(0)});
210 OperationNode<Base>* elseAssign = handler.makeNode(CGOpCode::CondResult,{*elseStart, *tmpAssign2});
236 const std::vector<CGB>& x,
237 std::vector<CGB>& temps,
238 const VectorSet& noLoopEvalJacSparsity,
239 bool individualColoring) {
243 CPPADCG_ASSERT_UNKNOWN(hessSparsity_);
245 size_t mo = dependentIndexes_.size();
246 size_t m = getTapeDependentCount();
247 size_t n = fun_->Domain();
249 std::vector<std::vector<CGB> > vwNoLoop(loopHessInfo.size());
250 std::vector<map<size_t, map<size_t, CGB> > > vhessNoLoop(loopHessInfo.size());
255 std::vector<std::set<size_t> > noLoopEvalHessTempsSparsity(n);
257 for (
const auto& itLoop2Info : loopHessInfo) {
260 addMatrixSparsity(info.noLoopEvalHessTempsSparsity, noLoopEvalHessTempsSparsity);
262 std::vector<size_t> hesRow, hesCol;
263 generateSparsityIndexes(noLoopEvalHessTempsSparsity, hesRow, hesCol);
266 for (
const auto& itLoop2Info : loopHessInfo) {
272 size_t nEqGroups = eqGroups.size();
274 std::vector<CGB>& wNoLoop = vwNoLoop[l];
276 for (
size_t inl = 0; inl < mo; inl++) {
277 wNoLoop[inl] = Base(0);
280 for (
size_t inl = mo; inl < m; inl++) {
284 if (posK !=
nullptr) {
286 for (
size_t g = 0; g < nEqGroups; g++) {
291 for (
size_t tapeI : group.
tapeI) {
292 const map<size_t, CGB>& row = info.
dyiDzk[tapeI];
293 typename map<size_t, CGB>::const_iterator itCol = row.find(posK->tape);
294 if (itCol != row.end()) {
295 const CGB& dydz = itCol->second;
296 v += dydz * info.w[tapeI];
307 *info.iterationIndexOp);
318 std::vector<map<size_t, CGB> > dyDx;
319 generateLoopForJacHes(*fun_, x, vwNoLoop, temps,
320 getJacobianSparsity(),
321 noLoopEvalJacSparsity,
323 hessTapeTempSparsity_,
324 noLoopEvalHessTempsSparsity,
329 map<size_t, map<size_t, CGB> > dzDx;
330 for (
size_t inl = mo; inl < m; inl++) {
338 for (
auto& itLoop2Info : loopHessInfo) {
340 info.dzDxx = vhessNoLoop[l];
348 const std::vector<CGB>& w,
349 const VectorSet& noLoopEvalHessSparsity,
350 const std::vector<std::map<
size_t, std::set<size_t> > >& noLoopEvalHessLocations,
351 std::vector<CGB>& hess) {
355 CPPADCG_ASSERT_UNKNOWN(hessSparsity_);
357 std::vector<CGB> wNoLoop(getTapeDependentCount());
358 std::vector<CGB> hessNoLoop;
363 std::vector<size_t> row, col;
364 generateSparsityIndexes(noLoopEvalHessSparsity, row, col);
366 if (row.size() > 0) {
367 hessNoLoop.resize(row.size());
369 for (
size_t inl = 0; inl < dependentIndexes_.size(); inl++) {
370 wNoLoop[inl] = w[dependentIndexes_[inl]];
373 CppAD::sparse_hessian_work work;
377 work.color_method =
"cppad.general";
378 fun_->SparseHessian(x, wNoLoop, hessTapeOrigEqSparsity_, row, col, hessNoLoop, work);
381 for (
size_t el = 0; el < row.size(); el++) {
384 const set<size_t>& locations = noLoopEvalHessLocations[j1].at(j2);
385 for (
size_t itE : locations)
386 hess[itE] = hessNoLoop[el];
const std::vector< size_t > & getOrigDependentIndexes() const
VectorSet jacTapeSparsity_
VectorSet hessTapeOrigEqSparsity_
void calculateHessian4OrignalEquations(const std::vector< CGB > &x, const std::vector< CGB > &w, const VectorSet &noLoopEvalHessSparsity, const std::vector< std::map< size_t, std::set< size_t > > > &noLoopEvalHessLocations, std::vector< CGB > &hess)
std::vector< size_t > dependentIndexes_
std::vector< std::map< size_t, CG< Base > > > dyiDzk
const LoopPosition * getTempIndepIndexes(size_t k) const
std::map< size_t, std::map< size_t, CGB > > calculateJacobianHessianUsedByLoops(CodeHandler< Base > &handler, std::map< LoopModel< Base > *, loops::HessianWithLoopsInfo< Base > > &loopHessInfo, const std::vector< CGB > &x, std::vector< CGB > &temps, const VectorSet &noLoopEvalJacSparsity, bool individualColoring)
const size_t getIterationCount() const
const std::vector< IterEquationGroup< Base > > & getEquationsGroups() const
CG< Base > createConditionalOperation(CodeHandler< Base > &handler, const std::set< size_t > &iterations, size_t iterCount, const CG< Base > &value, IndexOperationNode< Base > &iterationIndexOp)
LoopFreeModel(ADFun< CGB > *fun, const std::vector< size_t > &dependentOrigIndexes)
VectorSet hessTapeTempSparsity_
std::set< size_t > tapeI
equations indexes in tape of the loop model
std::set< size_t > iterations
iterations which only have these equations defined