1 #ifndef CPPAD_CG_LOOP_FREE_MODEL_INCLUDED 2 #define CPPAD_CG_LOOP_FREE_MODEL_INCLUDED 32 using Arg = Argument<Base>;
33 using VectorSet = std::vector<std::set<size_t> >;
43 std::map<size_t, size_t> dependentOrig2Local;
70 const std::vector<size_t>& dependentOrigIndexes) :
72 dependentIndexes_(dependentOrigIndexes),
74 hessSparsity_(false) {
75 CPPADCG_ASSERT_KNOWN(fun !=
nullptr,
"fun cannot be null")
76 CPPADCG_ASSERT_KNOWN(dependentOrigIndexes.size() <= fun->Range(),
"invalid size")
78 for (
size_t il = 0; il < dependentIndexes_.size(); il++)
79 dependentOrig2Local[dependentIndexes_[il]] = il;
89 inline size_t getTapeDependentCount()
const {
93 inline size_t getTemporaryDependentCount()
const {
94 return fun_->Range() - dependentIndexes_.size();
97 inline size_t getTapeIndependentCount()
const {
98 return fun_->Domain();
109 inline size_t getLocalDependentIndex(
size_t origI)
const {
110 return dependentOrig2Local.at(origI);
113 inline void evalJacobianSparsity() {
115 jacTapeSparsity_ = jacobianSparsitySet<VectorSet, CGB>(*fun_);
120 inline const VectorSet& getJacobianSparsity()
const {
124 inline void evalHessianSparsity() {
125 if (!hessSparsity_) {
126 size_t mo = dependentIndexes_.size();
127 size_t m = fun_->Range();
128 size_t n = fun_->Domain();
131 std::set<size_t> eqs;
133 for (
size_t i = 0; i < mo; i++)
134 eqs.insert(eqs.end(), i);
136 hessTapeOrigEqSparsity_ = hessianSparsitySet<std::vector<std::set<size_t> >,
CGB>(*
fun_, eqs);
142 for (
size_t i = mo; i < m; i++)
143 eqs.insert(eqs.end(), i);
144 hessTapeTempSparsity_ = hessianSparsitySet<std::vector<std::set<size_t> >,
CGB>(*
fun_, eqs);
146 hessTapeTempSparsity_.resize(n);
149 hessSparsity_ =
true;
153 inline const VectorSet& getHessianTempEqsSparsity()
const {
154 CPPADCG_ASSERT_UNKNOWN(hessSparsity_)
158 inline const VectorSet& getHessianOrigEqsSparsity()
const {
159 CPPADCG_ASSERT_UNKNOWN(hessSparsity_)
174 const std::set<size_t>& iterations,
180 if (iterations.size() == iterCount) {
188 if (value.isIdenticalZero())
198 set<size_t> usedIter;
199 OperationNode<Base>* cond = loops::createIndexConditionExpressionOp<Base>(handler, iterations, usedIter, iterCount - 1, iterationIndexOp);
204 OperationNode<Base>* tmpAssign1 = handler.makeNode(CGOpCode::LoopIndexedTmp,{tmpArg, asArgument(value)});
205 OperationNode<Base>* ifAssign = handler.makeNode(CGOpCode::CondResult,{*ifStart, *tmpAssign1});
210 OperationNode<Base>* tmpAssign2 = handler.makeNode(CGOpCode::LoopIndexedTmp,{tmpArg, Base(0)});
211 OperationNode<Base>* elseAssign = handler.makeNode(CGOpCode::CondResult,{*elseStart, *tmpAssign2});
237 const std::vector<CGB>& x,
238 std::vector<CGB>& temps,
239 const VectorSet& noLoopEvalJacSparsity,
240 bool individualColoring) {
244 CPPADCG_ASSERT_UNKNOWN(hessSparsity_)
246 size_t mo = dependentIndexes_.size();
247 size_t m = getTapeDependentCount();
248 size_t n = fun_->Domain();
250 std::vector<std::vector<CGB> > vwNoLoop(loopHessInfo.size());
251 std::vector<map<size_t, map<size_t, CGB> > > vhessNoLoop(loopHessInfo.size());
256 std::vector<std::set<size_t> > noLoopEvalHessTempsSparsity(n);
258 for (
const auto& itLoop2Info : loopHessInfo) {
261 addMatrixSparsity(info.noLoopEvalHessTempsSparsity, noLoopEvalHessTempsSparsity);
263 std::vector<size_t> hesRow, hesCol;
264 generateSparsityIndexes(noLoopEvalHessTempsSparsity, hesRow, hesCol);
267 for (
const auto& itLoop2Info : loopHessInfo) {
273 size_t nEqGroups = eqGroups.size();
275 std::vector<CGB>& wNoLoop = vwNoLoop[l];
277 for (
size_t inl = 0; inl < mo; inl++) {
278 wNoLoop[inl] = Base(0);
281 for (
size_t inl = mo; inl < m; inl++) {
285 if (posK !=
nullptr) {
287 for (
size_t g = 0; g < nEqGroups; g++) {
292 for (
size_t tapeI : group.
tapeI) {
293 const map<size_t, CGB>& row = info.
dyiDzk[tapeI];
294 typename map<size_t, CGB>::const_iterator itCol = row.find(posK->tape);
295 if (itCol != row.end()) {
296 const CGB& dydz = itCol->second;
297 v += dydz * info.w[tapeI];
308 *info.iterationIndexOp);
319 std::vector<map<size_t, CGB> > dyDx;
320 generateLoopForJacHes(*fun_, x, vwNoLoop, temps,
321 getJacobianSparsity(),
322 noLoopEvalJacSparsity,
324 hessTapeTempSparsity_,
325 noLoopEvalHessTempsSparsity,
330 map<size_t, map<size_t, CGB> > dzDx;
331 for (
size_t inl = mo; inl < m; inl++) {
339 for (
auto& itLoop2Info : loopHessInfo) {
341 info.dzDxx = vhessNoLoop[l];
349 const std::vector<CGB>& w,
350 const VectorSet& noLoopEvalHessSparsity,
351 const std::vector<std::map<
size_t, std::set<size_t> > >& noLoopEvalHessLocations,
352 std::vector<CGB>& hess) {
356 CPPADCG_ASSERT_UNKNOWN(hessSparsity_)
358 std::vector<CGB> wNoLoop(getTapeDependentCount());
359 std::vector<CGB> hessNoLoop;
364 std::vector<size_t> row, col;
365 generateSparsityIndexes(noLoopEvalHessSparsity, row, col);
368 hessNoLoop.resize(row.size());
370 for (
size_t inl = 0; inl < dependentIndexes_.size(); inl++) {
371 wNoLoop[inl] = w[dependentIndexes_[inl]];
374 CppAD::sparse_hessian_work work;
378 work.color_method =
"cppad.general";
379 fun_->SparseHessian(x, wNoLoop, hessTapeOrigEqSparsity_, row, col, hessNoLoop, work);
382 for (
size_t el = 0; el < row.size(); el++) {
385 const set<size_t>& locations = noLoopEvalHessLocations[j1].at(j2);
386 for (
size_t itE : locations)
387 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