ROL
algorithm/ROL_Problem_Def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_PROBLEM_DEF_HPP
11 #define ROL_PROBLEM_DEF_HPP
12 
13 #include <iostream>
14 
15 namespace ROL {
16 
17 template<typename Real>
18 Problem<Real>::Problem( const Ptr<Objective<Real>> &obj,
19  const Ptr<Vector<Real>> &x,
20  const Ptr<Vector<Real>> &g)
21  : isFinalized_(false), hasBounds_(false),
22  hasEquality_(false), hasInequality_(false),
23  hasLinearEquality_(false), hasLinearInequality_(false),
24  hasProximableObjective_(false),
25  cnt_econ_(0), cnt_icon_(0), cnt_linear_econ_(0), cnt_linear_icon_(0),
26  obj_(nullPtr), nobj_(nullPtr), xprim_(nullPtr), xdual_(nullPtr), bnd_(nullPtr),
27  con_(nullPtr), mul_(nullPtr), res_(nullPtr), proj_(nullPtr),
28  problemType_(TYPE_U) {
29  INPUT_obj_ = obj;
30  INPUT_nobj_ = nullPtr;
31  INPUT_xprim_ = x;
32  INPUT_bnd_ = nullPtr;
33  INPUT_con_.clear();
34  INPUT_linear_con_.clear();
35  if (g==nullPtr) INPUT_xdual_ = x->dual().clone();
36  else INPUT_xdual_ = g;
37 }
38 
39 template<typename Real>
40 void Problem<Real>::addBoundConstraint(const Ptr<BoundConstraint<Real>> &bnd) {
41  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
42  ">>> ROL::Problem: Cannot add bounds after problem is finalized!");
43 
44  INPUT_bnd_ = bnd;
45  hasBounds_ = true;
46 }
47 
48 template<typename Real>
50  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
51  ">>> ROL::Problem: Cannot remove bounds after problem is finalized!");
52 
53  INPUT_bnd_ = nullPtr;
54  hasBounds_ = false;
55 }
56 
57 template<typename Real>
59  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
60  ">>> ROL::Problem: Cannot add regularizer after problem is finalized!");
61 
62  INPUT_nobj_ = nobj;
63  hasProximableObjective_ = true;
64 }
65 
66 template<typename Real>
68  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
69  ">>> ROL::Problem: Cannot remove regularizer after problem is finalized!");
70 
71  INPUT_nobj_ = nullPtr;
72  hasProximableObjective_ = false;
73 }
74 template<typename Real>
75 void Problem<Real>::addConstraint( std::string name,
76  const Ptr<Constraint<Real>> &econ,
77  const Ptr<Vector<Real>> &emul,
78  const Ptr<Vector<Real>> &eres,
79  bool reset) {
80  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
81  ">>> ROL::Problem: Cannot add constraint after problem is finalized!");
82 
83  if (reset) INPUT_con_.clear();
84 
85  auto it = INPUT_con_.find(name);
86  ROL_TEST_FOR_EXCEPTION(it != INPUT_con_.end(),std::invalid_argument,
87  ">>> ROL::Problem: Constraint names must be distinct!");
88 
89  INPUT_con_.insert({name,ConstraintData<Real>(econ,emul,eres)});
90  hasEquality_ = true;
91  cnt_econ_++;
92 }
93 
94 template<typename Real>
95 void Problem<Real>::addConstraint( std::string name,
96  const Ptr<Constraint<Real>> &icon,
97  const Ptr<Vector<Real>> &imul,
98  const Ptr<BoundConstraint<Real>> &ibnd,
99  const Ptr<Vector<Real>> &ires,
100  bool reset) {
101  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
102  ">>> ROL::Problem: Cannot add constraint after problem is finalized!");
103 
104  if (reset) INPUT_con_.clear();
105 
106  auto it = INPUT_con_.find(name);
107  ROL_TEST_FOR_EXCEPTION(it != INPUT_con_.end(),std::invalid_argument,
108  ">>> ROL::Problem: Constraint names must be distinct!");
109 
110  INPUT_con_.insert({name,ConstraintData<Real>(icon,imul,ires,ibnd)});
111  hasInequality_ = true;
112  cnt_icon_++;
113 }
114 
115 template<typename Real>
116 void Problem<Real>::removeConstraint(std::string name) {
117  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
118  ">>> ROL::Problem: Cannot remove constraint after problem is finalized!");
119 
120  auto it = INPUT_con_.find(name);
121  if (it!=INPUT_con_.end()) {
122  if (it->second.bounds==nullPtr) cnt_econ_--;
123  else cnt_icon_--;
124  INPUT_con_.erase(it);
125  }
126  if (cnt_econ_==0) hasEquality_ = false;
127  if (cnt_icon_==0) hasInequality_ = false;
128 }
129 
130 template<typename Real>
131 void Problem<Real>::addLinearConstraint( std::string name,
132  const Ptr<Constraint<Real>> &linear_econ,
133  const Ptr<Vector<Real>> &linear_emul,
134  const Ptr<Vector<Real>> &linear_eres,
135  bool reset) {
136  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
137  ">>> ROL::Problem: Cannot add linear constraint after problem is finalized!");
138 
139  if (reset) INPUT_linear_con_.clear();
140 
141  auto it = INPUT_linear_con_.find(name);
142  ROL_TEST_FOR_EXCEPTION(it != INPUT_linear_con_.end(),std::invalid_argument,
143  ">>> ROL::Problem: Linear constraint names must be distinct!");
144 
145  INPUT_linear_con_.insert({name,ConstraintData<Real>(linear_econ,linear_emul,linear_eres)});
146  hasLinearEquality_ = true;
147  cnt_linear_econ_++;
148 }
149 
150 template<typename Real>
151 void Problem<Real>::addLinearConstraint( std::string name,
152  const Ptr<Constraint<Real>> &linear_icon,
153  const Ptr<Vector<Real>> &linear_imul,
154  const Ptr<BoundConstraint<Real>> &linear_ibnd,
155  const Ptr<Vector<Real>> &linear_ires,
156  bool reset) {
157  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
158  ">>> ROL::Problem: Cannot add linear constraint after problem is finalized!");
159 
160  if (reset) INPUT_linear_con_.clear();
161 
162  auto it = INPUT_linear_con_.find(name);
163  ROL_TEST_FOR_EXCEPTION(it != INPUT_linear_con_.end(),std::invalid_argument,
164  ">>> ROL::Problem: Linear constraint names must be distinct!");
165 
166  INPUT_linear_con_.insert({name,ConstraintData<Real>(linear_icon,linear_imul,linear_ires,linear_ibnd)});
167  hasLinearInequality_ = true;
168  cnt_linear_icon_++;
169 }
170 
171 template<typename Real>
172 void Problem<Real>::removeLinearConstraint(std::string name) {
173  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
174  ">>> ROL::Problem: Cannot remove linear inequality after problem is finalized!");
175 
176  auto it = INPUT_linear_con_.find(name);
177  if (it!=INPUT_linear_con_.end()) {
178  if (it->second.bounds==nullPtr) cnt_linear_econ_--;
179  else cnt_linear_icon_--;
180  INPUT_linear_con_.erase(it);
181  }
182  if (cnt_linear_econ_==0) hasLinearEquality_ = false;
183  if (cnt_linear_icon_==0) hasLinearInequality_ = false;
184 }
185 
186 template<typename Real>
187 void Problem<Real>::setProjectionAlgorithm(ParameterList &list) {
188  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
189  ">>> ROL::Problem: Cannot set polyhedral projection algorithm after problem is finalized!");
190 
191  ppa_list_ = list;
192 }
193 
194 template<typename Real>
195 void Problem<Real>::finalize(bool lumpConstraints, bool printToStream, std::ostream &outStream) {
196  if (!isFinalized_) {
197  std::unordered_map<std::string,ConstraintData<Real>> con, lcon, icon;
198  bool hasEquality = hasEquality_;
199  bool hasLinearEquality = hasLinearEquality_;
200  bool hasInequality = hasInequality_;
201  bool hasLinearInequality = hasLinearInequality_;
202  bool hasProximableObjective = hasProximableObjective_;
203  con.insert(INPUT_con_.begin(),INPUT_con_.end());
204  if (lumpConstraints) {
205  con.insert(INPUT_linear_con_.begin(),INPUT_linear_con_.end());
206  hasEquality = (hasEquality || hasLinearEquality);
207  hasInequality = (hasInequality || hasLinearInequality);
208  hasLinearEquality = false;
209  hasLinearInequality = false;
210  }
211  else {
212  lcon.insert(INPUT_linear_con_.begin(),INPUT_linear_con_.end());
213  }
214  // Transform optimization problem
215  //std::cout << hasBounds_ << " " << hasEquality << " " << hasInequality << " " << hasLinearEquality << " " << hasLinearInequality << std::endl;
216  nobj_ = nullPtr;
217  if (hasProximableObjective){
218  if (!hasEquality && !hasInequality && !hasBounds_ && !hasLinearEquality && !hasLinearInequality){
219  problemType_ = TYPE_P;
220  obj_ = INPUT_obj_;
221  nobj_ = INPUT_nobj_;
222  xprim_ = INPUT_xprim_;
223  xdual_ = INPUT_xdual_;
224  bnd_ = nullPtr;
225  con_ = nullPtr;
226  mul_ = nullPtr;
227  res_ = nullPtr;
228  }
229  else {
230  throw Exception::NotImplemented(">>> ROL::TypeP - with constraints is not supported");
231  }
232  }
233  else {
234  if (!hasLinearEquality && !hasLinearInequality) {
235  proj_ = nullPtr;
236  if (!hasEquality && !hasInequality && !hasBounds_ ) {
237  problemType_ = TYPE_U;
238  obj_ = INPUT_obj_;
239  xprim_ = INPUT_xprim_;
240  xdual_ = INPUT_xdual_;
241  bnd_ = nullPtr;
242  con_ = nullPtr;
243  mul_ = nullPtr;
244  res_ = nullPtr;
245  }
246  else if (!hasEquality && !hasInequality && hasBounds_) {
247  problemType_ = TYPE_B;
248  obj_ = INPUT_obj_;
249  xprim_ = INPUT_xprim_;
250  xdual_ = INPUT_xdual_;
251  bnd_ = INPUT_bnd_;
252  con_ = nullPtr;
253  mul_ = nullPtr;
254  res_ = nullPtr;
255  }
256  else if (hasEquality && !hasInequality && !hasBounds_) {
257  ConstraintAssembler<Real> cm(con,INPUT_xprim_,INPUT_xdual_);
258  problemType_ = TYPE_E;
259  obj_ = INPUT_obj_;
260  xprim_ = INPUT_xprim_;
261  xdual_ = INPUT_xdual_;
262  bnd_ = nullPtr;
263  con_ = cm.getConstraint();
264  mul_ = cm.getMultiplier();
265  res_ = cm.getResidual();
266  }
267  else {
268  ConstraintAssembler<Real> cm(con,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_);
269  problemType_ = TYPE_EB;
270  obj_ = INPUT_obj_;
271  if (cm.hasInequality()) {
272  obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
273  }
274  xprim_ = cm.getOptVector();
275  xdual_ = cm.getDualOptVector();
276  bnd_ = cm.getBoundConstraint();
277  con_ = cm.getConstraint();
278  mul_ = cm.getMultiplier();
279  res_ = cm.getResidual();
280  }
281  }
282  else {
283  if (!hasBounds_ && !hasLinearInequality) {
284  ConstraintAssembler<Real> cm(lcon,INPUT_xprim_,INPUT_xdual_);
285  xfeas_ = cm.getOptVector()->clone(); xfeas_->set(*cm.getOptVector());
286  rlc_ = makePtr<ReduceLinearConstraint<Real>>(cm.getConstraint(),xfeas_,cm.getResidual());
287  proj_ = nullPtr;
288  if (!hasEquality && !hasInequality) {
289  problemType_ = TYPE_U;
290  obj_ = rlc_->transform(INPUT_obj_);
291  xprim_ = xfeas_->clone(); xprim_->zero();
292  xdual_ = cm.getDualOptVector();
293  bnd_ = nullPtr;
294  con_ = nullPtr;
295  mul_ = nullPtr;
296  res_ = nullPtr;
297  }
298  else {
299  for (auto it = con.begin(); it != con.end(); ++it) {
300  icon.insert(std::pair<std::string,ConstraintData<Real>>(it->first,
301  ConstraintData<Real>(rlc_->transform(it->second.constraint),
302  it->second.multiplier,it->second.residual,it->second.bounds)));
303  }
304  Ptr<Vector<Real>> xtmp = xfeas_->clone(); xtmp->zero();
305  ConstraintAssembler<Real> cm1(icon,xtmp,cm.getDualOptVector());
306  xprim_ = cm1.getOptVector();
307  xdual_ = cm1.getDualOptVector();
308  con_ = cm1.getConstraint();
309  mul_ = cm1.getMultiplier();
310  res_ = cm1.getResidual();
311  if (!hasInequality) {
312  problemType_ = TYPE_E;
313  obj_ = rlc_->transform(INPUT_obj_);
314  bnd_ = nullPtr;
315  }
316  else {
317  problemType_ = TYPE_EB;
318  obj_ = makePtr<SlacklessObjective<Real>>(rlc_->transform(INPUT_obj_));
319  bnd_ = cm1.getBoundConstraint();
320  }
321  }
322  }
323  else if ((hasBounds_ || hasLinearInequality) && !hasEquality && !hasInequality) {
324  ConstraintAssembler<Real> cm(lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_);
325  problemType_ = TYPE_B;
326  obj_ = INPUT_obj_;
327  if (cm.hasInequality()) {
328  obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
329  }
330  xprim_ = cm.getOptVector();
331  xdual_ = cm.getDualOptVector();
332  bnd_ = cm.getBoundConstraint();
333  con_ = nullPtr;
334  mul_ = nullPtr;
335  res_ = nullPtr;
336  proj_ = PolyhedralProjectionFactory<Real>(*xprim_,*xdual_,bnd_,
337  cm.getConstraint(),*cm.getMultiplier(),*cm.getResidual(),ppa_list_);
338  }
339  else {
340  ConstraintAssembler<Real> cm(con,lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_);
341  problemType_ = TYPE_EB;
342  obj_ = INPUT_obj_;
343  if (cm.hasInequality()) {
344  obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
345  }
346  xprim_ = cm.getOptVector();
347  xdual_ = cm.getDualOptVector();
348  con_ = cm.getConstraint();
349  mul_ = cm.getMultiplier();
350  res_ = cm.getResidual();
351  bnd_ = cm.getBoundConstraint();
352  proj_ = PolyhedralProjectionFactory<Real>(*xprim_,*xdual_,bnd_,
353  cm.getLinearConstraint(),*cm.getLinearMultiplier(),
354  *cm.getLinearResidual(),ppa_list_);
355  }
356  }
357  }
358  isFinalized_ = true;
359  if (printToStream) {
360  outStream << std::endl;
361  outStream << " ROL::Problem::finalize" << std::endl;
362  outStream << " Problem Summary:" << std::endl;
363  outStream << " Has Proximable Objective? .......... " << (hasProximableObjective ? "yes" : "no") << std::endl;
364  outStream << " Has Bound Constraint? .............. " << (hasBounds_ ? "yes" : "no") << std::endl;
365  outStream << " Has Equality Constraint? ........... " << (hasEquality ? "yes" : "no") << std::endl;
366  if (hasEquality) {
367  int cnt = 0;
368  for (auto it = con.begin(); it != con.end(); ++it) {
369  if (it->second.bounds==nullPtr) {
370  if (cnt==0) {
371  outStream << " Names: ........................... ";
372  cnt++;
373  }
374  else {
375  outStream << " ";
376  }
377  outStream << it->first << std::endl;
378  }
379  }
380  outStream << " Total: ........................... " << cnt_econ_+(lumpConstraints ? cnt_linear_econ_ : 0) << std::endl;
381  }
382  outStream << " Has Inequality Constraint? ......... " << (hasInequality ? "yes" : "no") << std::endl;
383  if (hasInequality) {
384  int cnt = 0;
385  for (auto it = con.begin(); it != con.end(); ++it) {
386  if (it->second.bounds!=nullPtr) {
387  if (cnt==0) {
388  outStream << " Names: ........................... ";
389  cnt++;
390  }
391  else {
392  outStream << " ";
393  }
394  outStream << it->first << std::endl;
395  }
396  }
397  outStream << " Total: ........................... " << cnt_icon_+(lumpConstraints ? cnt_linear_icon_ : 0) << std::endl;
398  }
399  if (!lumpConstraints) {
400  outStream << " Has Linear Equality Constraint? .... " << (hasLinearEquality ? "yes" : "no") << std::endl;
401  if (hasLinearEquality) {
402  int cnt = 0;
403  for (auto it = lcon.begin(); it != lcon.end(); ++it) {
404  if (it->second.bounds==nullPtr) {
405  if (cnt==0) {
406  outStream << " Names: ........................... ";
407  cnt++;
408  }
409  else {
410  outStream << " ";
411  }
412  outStream << it->first << std::endl;
413  }
414  }
415  outStream << " Total: ........................... " << cnt_linear_econ_ << std::endl;
416  }
417  outStream << " Has Linear Inequality Constraint? .. " << (hasLinearInequality ? "yes" : "no") << std::endl;
418  if (hasLinearInequality) {
419  int cnt = 0;
420  for (auto it = lcon.begin(); it != lcon.end(); ++it) {
421  if (it->second.bounds!=nullPtr) {
422  if (cnt==0) {
423  outStream << " Names: ........................... ";
424  cnt++;
425  }
426  else {
427  outStream << " ";
428  }
429  outStream << it->first << std::endl;
430  }
431  }
432  outStream << " Total: ........................... " << cnt_linear_icon_ << std::endl;
433  }
434  }
435  outStream << std::endl;
436  }
437  }
438  else {
439  if (printToStream) {
440  outStream << std::endl;
441  outStream << " ROL::Problem::finalize" << std::endl;
442  outStream << " Problem already finalized!" << std::endl;
443  outStream << std::endl;
444  }
445  }
446 }
447 
448 template<typename Real>
449 const Ptr<Objective<Real>>& Problem<Real>::getObjective() {
450  finalize();
451  return obj_;
452 }
453 
454 template<typename Real>
455 const Ptr<Objective<Real>>& Problem<Real>::getProximableObjective(){
456  finalize();
457  return nobj_;
458 }
459 
460 template<typename Real>
461 const Ptr<Vector<Real>>& Problem<Real>::getPrimalOptimizationVector() {
462  finalize();
463  return xprim_;
464 }
465 
466 template<typename Real>
467 const Ptr<Vector<Real>>& Problem<Real>::getDualOptimizationVector() {
468  finalize();
469  return xdual_;
470 }
471 
472 template<typename Real>
473 const Ptr<BoundConstraint<Real>>& Problem<Real>::getBoundConstraint() {
474  finalize();
475  return bnd_;
476 }
477 
478 template<typename Real>
479 const Ptr<Constraint<Real>>& Problem<Real>::getConstraint() {
480  finalize();
481  return con_;
482 }
483 
484 template<typename Real>
485 const Ptr<Vector<Real>>& Problem<Real>::getMultiplierVector() {
486  finalize();
487  return mul_;
488 }
489 
490 template<typename Real>
491 const Ptr<Vector<Real>>& Problem<Real>::getResidualVector() {
492  finalize();
493  return res_;
494 }
495 
496 template<typename Real>
497 const Ptr<PolyhedralProjection<Real>>& Problem<Real>::getPolyhedralProjection() {
498  finalize();
499  return proj_;
500 }
501 
502 template<typename Real>
504  finalize();
505  return problemType_;
506 }
507 
508 template<typename Real>
509 Real Problem<Real>::checkLinearity(bool printToStream, std::ostream &outStream) const {
510  std::ios_base::fmtflags state(outStream.flags());
511  if (printToStream) {
512  outStream << std::setprecision(8) << std::scientific;
513  outStream << std::endl;
514  outStream << " ROL::Problem::checkLinearity" << std::endl;
515  }
516  const Real one(1), two(2), eps(1e-2*std::sqrt(ROL_EPSILON<Real>()));
517  Real tol(std::sqrt(ROL_EPSILON<Real>())), cnorm(0), err(0), maxerr(0);
518  Ptr<Vector<Real>> x = INPUT_xprim_->clone(); x->randomize(-one,one);
519  Ptr<Vector<Real>> y = INPUT_xprim_->clone(); y->randomize(-one,one);
520  Ptr<Vector<Real>> z = INPUT_xprim_->clone(); z->zero();
521  Ptr<Vector<Real>> xy = INPUT_xprim_->clone();
522  Real alpha = two*static_cast<Real>(rand())/static_cast<Real>(RAND_MAX)-one;
523  xy->set(*x); xy->axpy(alpha,*y);
524  Ptr<Vector<Real>> c1, c2;
525  for (auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
526  c1 = it->second.residual->clone();
527  c2 = it->second.residual->clone();
528  it->second.constraint->update(*xy,UpdateType::Temp);
529  it->second.constraint->value(*c1,*xy,tol);
530  cnorm = c1->norm();
531  it->second.constraint->update(*x,UpdateType::Temp);
532  it->second.constraint->value(*c2,*x,tol);
533  c1->axpy(-one,*c2);
534  it->second.constraint->update(*y,UpdateType::Temp);
535  it->second.constraint->value(*c2,*y,tol);
536  c1->axpy(-alpha,*c2);
537  it->second.constraint->update(*z,UpdateType::Temp);
538  it->second.constraint->value(*c2,*z,tol);
539  c1->axpy(alpha,*c2);
540  err = c1->norm();
541  maxerr = std::max(err,maxerr);
542  if (printToStream) {
543  outStream << " Constraint " << it->first;
544  outStream << ": ||c(x+alpha*y) - (c(x)+alpha*(c(y)-c(0)))|| = " << err << std::endl;
545  if (err > eps*cnorm) {
546  outStream << " Constraint " << it->first << " may not be linear!" << std::endl;
547  }
548  }
549  }
550  if (printToStream) {
551  outStream << std::endl;
552  }
553  outStream.flags(state);
554  return maxerr;
555 }
556 
557 template<typename Real>
558 void Problem<Real>::checkVectors(bool printToStream, std::ostream &outStream) const {
559  const Real one(1);
560  Ptr<Vector<Real>> x, y;
561  // Primal optimization space vector
562  x = INPUT_xprim_->clone(); x->randomize(-one,one);
563  y = INPUT_xprim_->clone(); y->randomize(-one,one);
564  if (printToStream) {
565  outStream << std::endl << " Check primal optimization space vector" << std::endl;
566  }
567  INPUT_xprim_->checkVector(*x,*y,printToStream,outStream);
568 
569  // Dual optimization space vector
570  x = INPUT_xdual_->clone(); x->randomize(-one,one);
571  y = INPUT_xdual_->clone(); y->randomize(-one,one);
572  if (printToStream) {
573  outStream << std::endl << " Check dual optimization space vector" << std::endl;
574  }
575  INPUT_xdual_->checkVector(*x,*y,printToStream,outStream);
576 
577  // Check constraint space vectors
578  for (auto it = INPUT_con_.begin(); it != INPUT_con_.end(); ++it) {
579  // Primal constraint space vector
580  x = it->second.residual->clone(); x->randomize(-one,one);
581  y = it->second.residual->clone(); y->randomize(-one,one);
582  if (printToStream) {
583  outStream << std::endl << " " << it->first << ": Check primal constraint space vector" << std::endl;
584  }
585  it->second.residual->checkVector(*x,*y,printToStream,outStream);
586 
587  // Dual optimization space vector
588  x = it->second.multiplier->clone(); x->randomize(-one,one);
589  y = it->second.multiplier->clone(); y->randomize(-one,one);
590  if (printToStream) {
591  outStream << std::endl << " " << it->first << ": Check dual constraint space vector" << std::endl;
592  }
593  it->second.multiplier->checkVector(*x,*y,printToStream,outStream);
594  }
595 
596  // Check constraint space vectors
597  for (auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
598  // Primal constraint space vector
599  x = it->second.residual->clone(); x->randomize(-one,one);
600  y = it->second.residual->clone(); y->randomize(-one,one);
601  if (printToStream) {
602  outStream << std::endl << " " << it->first << ": Check primal linear constraint space vector" << std::endl;
603  }
604  it->second.residual->checkVector(*x,*y,printToStream,outStream);
605 
606  // Dual optimization space vector
607  x = it->second.multiplier->clone(); x->randomize(-one,one);
608  y = it->second.multiplier->clone(); y->randomize(-one,one);
609  if (printToStream) {
610  outStream << std::endl << " " << it->first << ": Check dual linear constraint space vector" << std::endl;
611  }
612  it->second.multiplier->checkVector(*x,*y,printToStream,outStream);
613  }
614 }
615 
616 template<typename Real>
617 void Problem<Real>::checkDerivatives(bool printToStream, std::ostream &outStream, const Ptr<Vector<Real>> &x0, Real scale) const {
618  const Real one(1);
619  Ptr<Vector<Real>> x, d, v, g, c, w;
620  // Objective check
621  x = x0;
622  if (x == nullPtr) { x = INPUT_xprim_->clone(); x->randomize(-one,one); }
623  d = INPUT_xprim_->clone(); d->randomize(-scale,scale);
624  v = INPUT_xprim_->clone(); v->randomize(-scale,scale);
625  g = INPUT_xdual_->clone(); g->randomize(-scale,scale);
626  if (printToStream)
627  outStream << std::endl << " Check objective function" << std::endl << std::endl;
628  INPUT_obj_->checkGradient(*x,*g,*d,printToStream,outStream);
629  INPUT_obj_->checkHessVec(*x,*g,*d,printToStream,outStream);
630  INPUT_obj_->checkHessSym(*x,*g,*d,*v,printToStream,outStream);
631  //TODO: Proximable Objective Check
632  // Constraint check
633  for (auto it = INPUT_con_.begin(); it != INPUT_con_.end(); ++it) {
634  c = it->second.residual->clone(); c->randomize(-scale,scale);
635  w = it->second.multiplier->clone(); w->randomize(-scale,scale);
636  if (printToStream)
637  outStream << std::endl << " " << it->first << ": Check constraint function" << std::endl << std::endl;
638  it->second.constraint->checkApplyJacobian(*x,*v,*c,printToStream,outStream);
639  it->second.constraint->checkAdjointConsistencyJacobian(*w,*v,*x,printToStream,outStream);
640  it->second.constraint->checkApplyAdjointHessian(*x,*w,*v,*g,printToStream,outStream);
641  }
642 
643  // Linear constraint check
644  for (auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
645  c = it->second.residual->clone(); c->randomize(-scale,scale);
646  w = it->second.multiplier->clone(); w->randomize(-scale,scale);
647  if (printToStream)
648  outStream << std::endl << " " << it->first << ": Check constraint function" << std::endl << std::endl;
649  it->second.constraint->checkApplyJacobian(*x,*v,*c,printToStream,outStream);
650  it->second.constraint->checkAdjointConsistencyJacobian(*w,*v,*x,printToStream,outStream);
651  it->second.constraint->checkApplyAdjointHessian(*x,*w,*v,*g,printToStream,outStream);
652  }
653 }
654 
655 template<typename Real>
656 void Problem<Real>::check(bool printToStream, std::ostream &outStream, const Ptr<Vector<Real>> &x0, Real scale) const {
657  checkVectors(printToStream,outStream);
658  if (hasLinearEquality_ || hasLinearInequality_)
659  checkLinearity(printToStream,outStream);
660  checkDerivatives(printToStream,outStream,x0,scale);
661 // if (hasProximableObjective)
662 // checkProximableObjective(printToStream, outStream);
663 }
664 
665 template<typename Real>
666 bool Problem<Real>::isFinalized() const {
667  return isFinalized_;
668 }
669 
670 template<typename Real>
671 void Problem<Real>::edit() {
672  isFinalized_ = false;
673  rlc_ = nullPtr;
674  proj_ = nullPtr;
675 }
676 
677 template<typename Real>
679  if (rlc_ != nullPtr) {
680  if (!hasInequality_) {
681  rlc_->project(*INPUT_xprim_,*xprim_);
682  INPUT_xprim_->plus(*rlc_->getFeasibleVector());
683  }
684  else {
685  Ptr<Vector<Real>> xprim = dynamic_cast<PartitionedVector<Real>&>(*xprim_).get(0)->clone();
686  xprim->set(*dynamic_cast<PartitionedVector<Real>&>(*xprim_).get(0));
687  rlc_->project(*INPUT_xprim_,*xprim);
688  INPUT_xprim_->plus(*rlc_->getFeasibleVector());
689  }
690  }
691 }
692 
693 } // namespace ROL
694 
695 #endif // ROL_NEWOPTIMIZATIONPROBLEM_DEF_HPP
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.
Ptr< Objective< Real > > INPUT_nobj_
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.
void removeLinearConstraint(std::string name)
Remove an existing linear constraint.
const Ptr< BoundConstraint< Real > > & getBoundConstraint()
Get the bound constraint.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
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_
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...
void addProximableObjective(const Ptr< Objective< Real >> &nobj)
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.
Ptr< BoundConstraint< Real > > INPUT_bnd_
virtual void edit()
Resume editting optimization problem after finalize has been called.
const Ptr< Objective< Real > > & getProximableObjective()
Get proximable objective.
const Ptr< Vector< Real > > & getDualOptimizationVector()
Get the dual optimization space vector.
void checkVectors(bool printToStream=false, std::ostream &outStream=std::cout) const
Run vector checks for user-supplied vectors.
EProblem
Definition: ROL_Types.hpp:223
const Ptr< Obj > obj_
Defines the general constraint operator interface.
void setProjectionAlgorithm(ParameterList &parlist)
Set polyhedral projection algorithm.