/** \brief Apply Hessian approximation to vector. This function applies the Hessian of the Moreau-Yosida penalty to the vector \f$v\f$. @param[out] hv is the the action of the Hessian on \f$v\f$. @param[in] v is the direction vector. @param[in] x is the current iterate. @param[in] tol is a tolerance for inexact Moreau-Yosida penalty computation. */ void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) { // Apply objective Hessian to a vector obj_->hessVec(hv,v,x,tol); // Add Hessian of the Moreau-Yosida penalty if ( con_->isActivated() ) { Real one = 1.0; computePenalty(x); v_->set(v); con_->pruneLowerActive(*v_,*xlam_); v_->scale(-one); v_->plus(v); dv_->set(v_->dual()); dv2_->set(*dv_); con_->pruneLowerActive(*dv_,*xlam_); dv_->scale(-one); dv_->plus(*dv2_); hv.axpy(mu_,*dv_); v_->set(v); con_->pruneUpperActive(*v_,*xlam_); v_->scale(-one); v_->plus(v); dv_->set(v_->dual()); dv2_->set(*dv_); con_->pruneUpperActive(*dv_,*xlam_); dv_->scale(-one); dv_->plus(*dv2_); hv.axpy(mu_,*dv_); } }
/** \brief Compute gradient. This function returns the Moreau-Yosida penalty gradient. @param[out] g is the gradient. @param[in] x is the current iterate. @param[in] tol is a tolerance for inexact Moreau-Yosida penalty computation. */ void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) { // Compute gradient of objective function obj_->gradient(*g_,x,tol); ngval_++; g.set(*g_); // Add gradient of the Moreau-Yosida penalty if ( con_->isActivated() ) { computePenalty(x); g.axpy(-mu_,*dl1_); g.axpy(mu_,*du1_); } }
/** \brief Compute value. This function returns the Moreau-Yosida penalty value. @param[in] x is the current iterate. @param[in] tol is a tolerance for inexact Moreau-Yosida penalty computation. */ Real value( const Vector<Real> &x, Real &tol ) { Real half = 0.5; // Compute objective function value fval_ = obj_->value(x,tol); nfval_++; // Add value of the Moreau-Yosida penalty Real fval = fval_; if ( con_->isActivated() ) { computePenalty(x); fval += half*mu_*(l1_->dot(*l1_) + u1_->dot(*u1_)); } return fval; }
void updateMultipliers(Real mu, const ROL::Vector<Real> &x) { if ( con_->isActivated() ) { Real one = 1.0; computePenalty(x); lam_->set(*u1_); lam_->axpy(-one,*l1_); lam_->scale(mu_); mu_ = mu; } nfval_ = 0; ngval_ = 0; isConEvaluated_ = false; }
vector<int> discreteEmbed(const PtGraph &graph, const vector<Sphere> &spheres, const Skeleton &skeleton, const vector<vector<int> > &possibilities) { int i, j; FP fp(graph, skeleton, spheres); fp.footBase = 1.; for(i = 0; i < (int)graph.verts.size(); ++i) fp.footBase = min(fp.footBase, graph.verts[i][1]); vector<PenaltyFunction *> penaltyFunctions = getPenaltyFunctions(&fp); int toMatch = skeleton.cGraph().verts.size(); std::cout << "Matching!" << endl; priority_queue<PartialMatch> todo; PartialMatch output(graph.verts.size()); todo.push(output); int maxSz = 0; while(!todo.empty()) { PartialMatch cur = todo.top(); todo.pop(); int idx = cur.match.size(); int curSz = (int)log((double)todo.size()); if(curSz > maxSz) { maxSz = curSz; if(maxSz > 3) std::cout << "Reached " << todo.size() << endl; } if(idx == toMatch) { output = cur; std::cout << "Found: residual = " << cur.penalty << endl; break; } for(i = 0; i < (int)possibilities[idx].size(); ++i) { int candidate = possibilities[idx][i]; int k; double extraPenalty = computePenalty(penaltyFunctions, cur, candidate); if(extraPenalty < 0) std::cout << "ERR = " << extraPenalty << endl; if(cur.penalty + extraPenalty < 1.) { PartialMatch next = cur; next.match.push_back(candidate); next.penalty += extraPenalty; next.heuristic = next.penalty; //compute taken vertices and edges if(idx > 0) { vector<int> path = fp.paths.path(candidate, next.match[skeleton.cPrev()[idx]]); for(j = 0; j < (int)path.size(); ++j) next.vTaken[path[j]] = true; } //compute heuristic for(j = idx + 1; j < toMatch; ++j) { if(skeleton.cPrev()[j] > idx) continue; double minP = 1e37; for(k = 0; k < (int)possibilities[j].size(); ++k) { minP = min(minP, computePenalty(penaltyFunctions, next, possibilities[j][k], j)); } next.heuristic += minP; if(next.heuristic > 1.) break; } if(next.heuristic > 1.) continue; todo.push(next); } } } if(output.match.size() == 0) { std::cout << "No Match" << endl; } for(i = 0; i < (int)penaltyFunctions.size(); ++i) delete penaltyFunctions[i]; return output.match; }