44 #ifndef ROL_PROBLEM_DEF_HPP
45 #define ROL_PROBLEM_DEF_HPP
51 template<
typename Real>
55 : isFinalized_(false), hasBounds_(false),
56 hasEquality_(false), hasInequality_(false),
57 hasLinearEquality_(false), hasLinearInequality_(false),
58 cnt_econ_(0), cnt_icon_(0), cnt_linear_econ_(0), cnt_linear_icon_(0),
59 obj_(nullPtr), xprim_(nullPtr), xdual_(nullPtr), bnd_(nullPtr),
60 con_(nullPtr), mul_(nullPtr), res_(nullPtr), proj_(nullPtr),
71 template<
typename Real>
73 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
74 ">>> ROL::Problem: Cannot add bounds after problem is finalized!");
80 template<
typename Real>
82 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
83 ">>> ROL::Problem: Cannot remove bounds after problem is finalized!");
89 template<
typename Real>
91 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
92 ">>> ROL::Problem: Cannot add prox objective after problem is finalized!");
98 template<
typename Real>
100 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
101 ">>> ROL::Problem: Cannot remove prox objective after problem is finalized!");
103 INPUT_prox_ = nullPtr;
107 template<
typename Real>
113 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
114 ">>> ROL::Problem: Cannot add constraint after problem is finalized!");
116 if (reset) INPUT_con_.clear();
118 auto it = INPUT_con_.find(name);
119 ROL_TEST_FOR_EXCEPTION(it != INPUT_con_.end(),std::invalid_argument,
120 ">>> ROL::Problem: Constraint names must be distinct!");
127 template<
typename Real>
134 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
135 ">>> ROL::Problem: Cannot add constraint after problem is finalized!");
137 if (reset) INPUT_con_.clear();
139 auto it = INPUT_con_.find(name);
140 ROL_TEST_FOR_EXCEPTION(it != INPUT_con_.end(),std::invalid_argument,
141 ">>> ROL::Problem: Constraint names must be distinct!");
144 hasInequality_ =
true;
148 template<
typename Real>
150 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
151 ">>> ROL::Problem: Cannot remove constraint after problem is finalized!");
153 auto it = INPUT_con_.find(name);
154 if (it!=INPUT_con_.end()) {
155 if (it->second.bounds==nullPtr) cnt_econ_--;
157 INPUT_con_.erase(it);
159 if (cnt_econ_==0) hasEquality_ =
false;
160 if (cnt_icon_==0) hasInequality_ =
false;
163 template<
typename Real>
169 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
170 ">>> ROL::Problem: Cannot add linear constraint after problem is finalized!");
172 if (reset) INPUT_linear_con_.clear();
174 auto it = INPUT_linear_con_.find(name);
175 ROL_TEST_FOR_EXCEPTION(it != INPUT_linear_con_.end(),std::invalid_argument,
176 ">>> ROL::Problem: Linear constraint names must be distinct!");
179 hasLinearEquality_ =
true;
183 template<
typename Real>
190 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
191 ">>> ROL::Problem: Cannot add linear constraint after problem is finalized!");
193 if (reset) INPUT_linear_con_.clear();
195 auto it = INPUT_linear_con_.find(name);
196 ROL_TEST_FOR_EXCEPTION(it != INPUT_linear_con_.end(),std::invalid_argument,
197 ">>> ROL::Problem: Linear constraint names must be distinct!");
199 INPUT_linear_con_.insert({name,
ConstraintData<Real>(linear_icon,linear_imul,linear_ires,linear_ibnd)});
200 hasLinearInequality_ =
true;
204 template<
typename Real>
206 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
207 ">>> ROL::Problem: Cannot remove linear inequality after problem is finalized!");
209 auto it = INPUT_linear_con_.find(name);
210 if (it!=INPUT_linear_con_.end()) {
211 if (it->second.bounds==nullPtr) cnt_linear_econ_--;
212 else cnt_linear_icon_--;
213 INPUT_linear_con_.erase(it);
215 if (cnt_linear_econ_==0) hasLinearEquality_ =
false;
216 if (cnt_linear_icon_==0) hasLinearInequality_ =
false;
219 template<
typename Real>
221 ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
222 ">>> ROL::Problem: Cannot set polyhedral projection algorithm after problem is finalized!");
227 template<
typename Real>
230 std::unordered_map<std::string,ConstraintData<Real>> con, lcon, icon;
231 bool hasEquality = hasEquality_;
232 bool hasLinearEquality = hasLinearEquality_;
233 bool hasInequality = hasInequality_;
234 bool hasLinearInequality = hasLinearInequality_;
235 con.insert(INPUT_con_.begin(),INPUT_con_.end());
236 if (lumpConstraints) {
237 con.insert(INPUT_linear_con_.begin(),INPUT_linear_con_.end());
238 hasEquality = (hasEquality || hasLinearEquality);
239 hasInequality = (hasInequality || hasLinearInequality);
240 hasLinearEquality =
false;
241 hasLinearInequality =
false;
244 lcon.insert(INPUT_linear_con_.begin(),INPUT_linear_con_.end());
248 bool proxCompatible =
false;
249 if (!hasLinearEquality && !hasLinearInequality) {
251 if (!hasEquality && !hasInequality && !hasBounds_) {
254 xprim_ = INPUT_xprim_;
255 xdual_ = INPUT_xdual_;
260 if (hasProx_) { prox_ = INPUT_prox_; }
261 else { prox_ = nullPtr; }
262 proxCompatible =
true;
264 else if (!hasEquality && !hasInequality && hasBounds_) {
267 xprim_ = INPUT_xprim_;
268 xdual_ = INPUT_xdual_;
274 else if (hasEquality && !hasInequality && !hasBounds_) {
278 xprim_ = INPUT_xprim_;
279 xdual_ = INPUT_xdual_;
290 obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
301 if (!hasBounds_ && !hasLinearInequality) {
306 if (!hasEquality && !hasInequality) {
308 obj_ = rlc_->transform(INPUT_obj_);
309 xprim_ = xfeas_->clone(); xprim_->zero();
317 for (
auto it = con.begin(); it != con.end(); ++it) {
320 it->second.multiplier,it->second.residual,it->second.bounds)));
322 Ptr<Vector<Real>> xtmp = xfeas_->clone(); xtmp->zero();
325 xdual_ = cm1.getDualOptVector();
326 con_ = cm1.getConstraint();
327 mul_ = cm1.getMultiplier();
328 res_ = cm1.getResidual();
329 if (!hasInequality) {
331 obj_ = rlc_->transform(INPUT_obj_);
336 obj_ = makePtr<SlacklessObjective<Real>>(rlc_->transform(INPUT_obj_));
337 bnd_ = cm1.getBoundConstraint();
341 else if ((hasBounds_ || hasLinearInequality) && !hasEquality && !hasInequality) {
346 obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
354 proj_ = PolyhedralProjectionFactory<Real>(*xprim_,*xdual_,bnd_,
362 obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
370 proj_ = PolyhedralProjectionFactory<Real>(*xprim_,*xdual_,bnd_,
376 std::stringstream out;
377 out <<
">>> ROL::Problem: Cannot solve ";
378 if (problemType_ ==
TYPE_B) out <<
"TypeB";
379 else if (problemType_ ==
TYPE_E) out <<
"TypeE";
380 else if (problemType_ ==
TYPE_EB) out <<
"TypeG";
381 else out <<
"TypeU with linear constraints";
382 out <<
" problems with a prox objective!";
383 ROL_TEST_FOR_EXCEPTION(hasProx_&&!proxCompatible,std::invalid_argument,out.str());
387 outStream << std::endl;
388 outStream <<
" ROL::Problem::finalize" << std::endl;
389 outStream <<
" Problem Summary:" << std::endl;
390 outStream <<
" Has Bound Constraint? .............. " << (hasBounds_ ?
"yes" :
"no") << std::endl;
391 outStream <<
" Has Equality Constraint? ........... " << (hasEquality ?
"yes" :
"no") << std::endl;
394 for (
auto it = con.begin(); it != con.end(); ++it) {
395 if (it->second.bounds==nullPtr) {
397 outStream <<
" Names: ........................... ";
403 outStream << it->first << std::endl;
406 outStream <<
" Total: ........................... " << cnt_econ_+(lumpConstraints ? cnt_linear_econ_ : 0) << std::endl;
408 outStream <<
" Has Inequality Constraint? ......... " << (hasInequality ?
"yes" :
"no") << std::endl;
411 for (
auto it = con.begin(); it != con.end(); ++it) {
412 if (it->second.bounds!=nullPtr) {
414 outStream <<
" Names: ........................... ";
420 outStream << it->first << std::endl;
423 outStream <<
" Total: ........................... " << cnt_icon_+(lumpConstraints ? cnt_linear_icon_ : 0) << std::endl;
425 if (!lumpConstraints) {
426 outStream <<
" Has Linear Equality Constraint? .... " << (hasLinearEquality ?
"yes" :
"no") << std::endl;
427 if (hasLinearEquality) {
429 for (
auto it = lcon.begin(); it != lcon.end(); ++it) {
430 if (it->second.bounds==nullPtr) {
432 outStream <<
" Names: ........................... ";
438 outStream << it->first << std::endl;
441 outStream <<
" Total: ........................... " << cnt_linear_econ_ << std::endl;
443 outStream <<
" Has Linear Inequality Constraint? .. " << (hasLinearInequality ?
"yes" :
"no") << std::endl;
444 if (hasLinearInequality) {
446 for (
auto it = lcon.begin(); it != lcon.end(); ++it) {
447 if (it->second.bounds!=nullPtr) {
449 outStream <<
" Names: ........................... ";
455 outStream << it->first << std::endl;
458 outStream <<
" Total: ........................... " << cnt_linear_icon_ << std::endl;
461 outStream << std::endl;
466 outStream << std::endl;
467 outStream <<
" ROL::Problem::finalize" << std::endl;
468 outStream <<
" Problem already finalized!" << std::endl;
469 outStream << std::endl;
474 template<
typename Real>
480 template<
typename Real>
486 template<
typename Real>
492 template<
typename Real>
498 template<
typename Real>
504 template<
typename Real>
510 template<
typename Real>
516 template<
typename Real>
522 template<
typename Real>
528 template<
typename Real>
530 std::ios_base::fmtflags state(outStream.flags());
532 outStream << std::setprecision(8) << std::scientific;
533 outStream << std::endl;
534 outStream <<
" ROL::Problem::checkLinearity" << std::endl;
536 const Real one(1), two(2), eps(1e-2*std::sqrt(ROL_EPSILON<Real>()));
537 Real tol(std::sqrt(ROL_EPSILON<Real>())), cnorm(0), err(0), maxerr(0);
538 Ptr<Vector<Real>> x = INPUT_xprim_->clone(); x->randomize(-one,one);
539 Ptr<Vector<Real>> y = INPUT_xprim_->clone(); y->randomize(-one,one);
540 Ptr<Vector<Real>> z = INPUT_xprim_->clone(); z->zero();
541 Ptr<Vector<Real>> xy = INPUT_xprim_->clone();
542 Real alpha = two*
static_cast<Real
>(rand())/static_cast<Real>(RAND_MAX)-one;
543 xy->set(*x); xy->axpy(alpha,*y);
544 Ptr<Vector<Real>> c1, c2;
545 for (
auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
546 c1 = it->second.residual->clone();
547 c2 = it->second.residual->clone();
549 it->second.constraint->value(*c1,*xy,tol);
552 it->second.constraint->value(*c2,*x,tol);
555 it->second.constraint->value(*c2,*y,tol);
556 c1->axpy(-alpha,*c2);
558 it->second.constraint->value(*c2,*z,tol);
561 maxerr = std::max(err,maxerr);
563 outStream <<
" Constraint " << it->first;
564 outStream <<
": ||c(x+alpha*y) - (c(x)+alpha*(c(y)-c(0)))|| = " << err << std::endl;
565 if (err > eps*cnorm) {
566 outStream <<
" Constraint " << it->first <<
" may not be linear!" << std::endl;
571 outStream << std::endl;
573 outStream.flags(state);
577 template<
typename Real>
580 Ptr<Vector<Real>> x, y;
582 x = INPUT_xprim_->clone(); x->randomize(-one,one);
583 y = INPUT_xprim_->clone(); y->randomize(-one,one);
585 outStream << std::endl <<
" Check primal optimization space vector" << std::endl;
587 INPUT_xprim_->checkVector(*x,*y,printToStream,outStream);
590 x = INPUT_xdual_->clone(); x->randomize(-one,one);
591 y = INPUT_xdual_->clone(); y->randomize(-one,one);
593 outStream << std::endl <<
" Check dual optimization space vector" << std::endl;
595 INPUT_xdual_->checkVector(*x,*y,printToStream,outStream);
598 for (
auto it = INPUT_con_.begin(); it != INPUT_con_.end(); ++it) {
600 x = it->second.residual->clone(); x->randomize(-one,one);
601 y = it->second.residual->clone(); y->randomize(-one,one);
603 outStream << std::endl <<
" " << it->first <<
": Check primal constraint space vector" << std::endl;
605 it->second.residual->checkVector(*x,*y,printToStream,outStream);
608 x = it->second.multiplier->clone(); x->randomize(-one,one);
609 y = it->second.multiplier->clone(); y->randomize(-one,one);
611 outStream << std::endl <<
" " << it->first <<
": Check dual constraint space vector" << std::endl;
613 it->second.multiplier->checkVector(*x,*y,printToStream,outStream);
617 for (
auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
619 x = it->second.residual->clone(); x->randomize(-one,one);
620 y = it->second.residual->clone(); y->randomize(-one,one);
622 outStream << std::endl <<
" " << it->first <<
": Check primal linear constraint space vector" << std::endl;
624 it->second.residual->checkVector(*x,*y,printToStream,outStream);
627 x = it->second.multiplier->clone(); x->randomize(-one,one);
628 y = it->second.multiplier->clone(); y->randomize(-one,one);
630 outStream << std::endl <<
" " << it->first <<
": Check dual linear constraint space vector" << std::endl;
632 it->second.multiplier->checkVector(*x,*y,printToStream,outStream);
636 template<
typename Real>
639 Ptr<Vector<Real>> x, d, v, g, c, w;
641 x = INPUT_xprim_->clone(); x->randomize(-one,one);
642 d = INPUT_xprim_->clone(); d->randomize(-one,one);
643 v = INPUT_xprim_->clone(); v->randomize(-one,one);
644 g = INPUT_xdual_->clone(); g->randomize(-one,one);
646 outStream << std::endl <<
" Check objective function" << std::endl << std::endl;
648 INPUT_obj_->checkGradient(*x,*g,*d,printToStream,outStream);
649 INPUT_obj_->checkHessVec(*x,*g,*d,printToStream,outStream);
650 INPUT_obj_->checkHessSym(*x,*g,*d,*v,printToStream,outStream);
653 for (
auto it = INPUT_con_.begin(); it != INPUT_con_.end(); ++it) {
654 c = it->second.residual->clone(); c->randomize(-one,one);
655 w = it->second.multiplier->clone(); w->randomize(-one,one);
657 outStream << std::endl <<
" " << it->first <<
": Check constraint function" << std::endl << std::endl;
659 it->second.constraint->checkApplyJacobian(*x,*v,*c,printToStream,outStream);
660 it->second.constraint->checkAdjointConsistencyJacobian(*w,*v,*x,printToStream,outStream);
661 it->second.constraint->checkApplyAdjointHessian(*x,*w,*v,*g,printToStream,outStream);
665 for (
auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
666 c = it->second.residual->clone(); c->randomize(-one,one);
667 w = it->second.multiplier->clone(); w->randomize(-one,one);
669 outStream << std::endl <<
" " << it->first <<
": Check constraint function" << std::endl << std::endl;
671 it->second.constraint->checkApplyJacobian(*x,*v,*c,printToStream,outStream);
672 it->second.constraint->checkAdjointConsistencyJacobian(*w,*v,*x,printToStream,outStream);
673 it->second.constraint->checkApplyAdjointHessian(*x,*w,*v,*g,printToStream,outStream);
677 template<
typename Real>
679 checkVectors(printToStream,outStream);
680 if (hasLinearEquality_ || hasLinearInequality_) {
681 checkLinearity(printToStream,outStream);
683 checkDerivatives(printToStream,outStream);
686 template<
typename Real>
691 template<
typename Real>
693 isFinalized_ =
false;
698 template<
typename Real>
700 if (rlc_ != nullPtr) {
701 if (!hasInequality_) {
702 rlc_->project(*INPUT_xprim_,*xprim_);
703 INPUT_xprim_->plus(*rlc_->getFeasibleVector());
708 rlc_->project(*INPUT_xprim_,*xprim);
709 INPUT_xprim_->plus(*rlc_->getFeasibleVector());
716 #endif // ROL_NEWOPTIMIZATIONPROBLEM_DEF_HPP
void removeProxObjective()
Remove an existing prox objective.
void check(bool printToStream=false, std::ostream &outStream=std::cout) const
Run vector, linearity and derivative checks for user-supplied vectors, objective function and constra...
Provides the interface to evaluate objective functions.
const Ptr< Constraint< Real > > & getConstraint()
Get the equality constraint.
void checkDerivatives(bool printToStream=false, std::ostream &outStream=std::cout) const
Run derivative checks for user-supplied objective function and constraints.
const Ptr< Vector< Real > > & getPrimalOptimizationVector()
Get the primal optimization space vector.
void addBoundConstraint(const Ptr< BoundConstraint< Real >> &bnd)
Add a bound constraint.
ROL::Ptr< const Vector< Real > > get(size_type i) const
void addLinearConstraint(std::string name, const Ptr< Constraint< Real >> &linear_econ, const Ptr< Vector< Real >> &linear_emul, const Ptr< Vector< Real >> &linear_eres=nullPtr, bool reset=false)
Add a linear equality constraint.
void removeBoundConstraint()
Remove an existing bound constraint.
Defines the linear algebra of vector space on a generic partitioned vector.
const Ptr< BoundConstraint< Real > > & getBoundConstraint() const
void removeLinearConstraint(std::string name)
Remove an existing linear constraint.
const Ptr< BoundConstraint< Real > > & getBoundConstraint()
Get the bound constraint.
const Ptr< Constraint< Real > > & getConstraint() const
Defines the linear algebra or vector space interface.
void addProxObjective(const Ptr< ProxObjective< Real >> &prox)
Add a prox objective.
virtual void finalize(bool lumpConstraints=false, bool printToStream=false, std::ostream &outStream=std::cout)
Tranform user-supplied constraints to consist of only bounds and equalities. Optimization problem can...
Ptr< Objective< Real > > INPUT_obj_
const Ptr< Vector< Real > > & getLinearResidual() const
bool isFinalized() const
Indicate whether or no finalize has been called.
Ptr< Vector< Real > > INPUT_xprim_
const Ptr< Objective< Real > > & getObjective()
Get the objective function.
Problem(const Ptr< Objective< Real >> &obj, const Ptr< Vector< Real >> &x, const Ptr< Vector< Real >> &g=nullPtr)
Default constructor for OptimizationProblem.
std::unordered_map< std::string, ConstraintData< Real > > INPUT_linear_con_
std::unordered_map< std::string, ConstraintData< Real > > INPUT_con_
Ptr< Vector< Real > > INPUT_xdual_
const Ptr< Vector< Real > > & getResidualVector()
Get the primal constraint space vector.
const Ptr< Vector< Real > > & getMultiplierVector()
Get the dual constraint space vector.
void finalizeIteration()
Transform the optimization variables to the native parameterization after an optimization algorithm h...
Provides a wrapper for multiple constraints.
const Ptr< Vector< Real > > & getMultiplier() const
Provides the interface to apply upper and lower bound constraints.
Real checkLinearity(bool printToStream=false, std::ostream &outStream=std::cout) const
Check if user-supplied linear constraints are affine.
void addConstraint(std::string name, const Ptr< Constraint< Real >> &econ, const Ptr< Vector< Real >> &emul, const Ptr< Vector< Real >> &eres=nullPtr, bool reset=false)
Add an equality constraint.
const Ptr< PolyhedralProjection< Real > > & getPolyhedralProjection()
Get the polyhedral projection object. This is a null pointer if no linear constraints and/or bounds a...
EProblem getProblemType()
Get the optimization problem type (U, B, E, or G).
void removeConstraint(std::string name)
Remove an existing constraint.
const Ptr< Vector< Real > > & getDualOptVector() const
Ptr< BoundConstraint< Real > > INPUT_bnd_
virtual void edit()
Resume editting optimization problem after finalize has been called.
const Ptr< Vector< Real > > & getOptVector() const
const Ptr< Constraint< Real > > & getLinearConstraint() const
const Ptr< Vector< Real > > & getDualOptimizationVector()
Get the dual optimization space vector.
const Ptr< Vector< Real > > & getLinearMultiplier() const
void checkVectors(bool printToStream=false, std::ostream &outStream=std::cout) const
Run vector checks for user-supplied vectors.
const Ptr< Vector< Real > > & getResidual() const
Defines the general constraint operator interface.
void setProjectionAlgorithm(ParameterList &parlist)
Set polyhedral projection algorithm.
bool hasInequality() const