ROL
function/prox/ROL_Problem_Def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #ifndef ROL_PROBLEM_DEF_HPP
45 #define ROL_PROBLEM_DEF_HPP
46 
47 #include <iostream>
48 
49 namespace ROL {
50 
51 template<typename Real>
53  const Ptr<Vector<Real>> &x,
54  const Ptr<Vector<Real>> &g)
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),
61  problemType_(TYPE_U) {
62  INPUT_obj_ = obj;
63  INPUT_xprim_ = x;
64  INPUT_bnd_ = nullPtr;
65  INPUT_con_.clear();
66  INPUT_linear_con_.clear();
67  if (g==nullPtr) INPUT_xdual_ = x->dual().clone();
68  else INPUT_xdual_ = g;
69 }
70 
71 template<typename Real>
73  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
74  ">>> ROL::Problem: Cannot add bounds after problem is finalized!");
75 
76  INPUT_bnd_ = bnd;
77  hasBounds_ = true;
78 }
79 
80 template<typename Real>
82  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
83  ">>> ROL::Problem: Cannot remove bounds after problem is finalized!");
84 
85  INPUT_bnd_ = nullPtr;
86  hasBounds_ = false;
87 }
88 
89 template<typename Real>
91  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
92  ">>> ROL::Problem: Cannot add prox objective after problem is finalized!");
93 
94  INPUT_prox_ = prox;
95  hasProx_ = true;
96 }
97 
98 template<typename Real>
100  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
101  ">>> ROL::Problem: Cannot remove prox objective after problem is finalized!");
102 
103  INPUT_prox_ = nullPtr;
104  hasProx_ = false;
105 }
106 
107 template<typename Real>
108 void Problem<Real>::addConstraint( std::string name,
109  const Ptr<Constraint<Real>> &econ,
110  const Ptr<Vector<Real>> &emul,
111  const Ptr<Vector<Real>> &eres,
112  bool reset) {
113  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
114  ">>> ROL::Problem: Cannot add constraint after problem is finalized!");
115 
116  if (reset) INPUT_con_.clear();
117 
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!");
121 
122  INPUT_con_.insert({name,ConstraintData<Real>(econ,emul,eres)});
123  hasEquality_ = true;
124  cnt_econ_++;
125 }
126 
127 template<typename Real>
128 void Problem<Real>::addConstraint( std::string name,
129  const Ptr<Constraint<Real>> &icon,
130  const Ptr<Vector<Real>> &imul,
131  const Ptr<BoundConstraint<Real>> &ibnd,
132  const Ptr<Vector<Real>> &ires,
133  bool reset) {
134  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
135  ">>> ROL::Problem: Cannot add constraint after problem is finalized!");
136 
137  if (reset) INPUT_con_.clear();
138 
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!");
142 
143  INPUT_con_.insert({name,ConstraintData<Real>(icon,imul,ires,ibnd)});
144  hasInequality_ = true;
145  cnt_icon_++;
146 }
147 
148 template<typename Real>
149 void Problem<Real>::removeConstraint(std::string name) {
150  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
151  ">>> ROL::Problem: Cannot remove constraint after problem is finalized!");
152 
153  auto it = INPUT_con_.find(name);
154  if (it!=INPUT_con_.end()) {
155  if (it->second.bounds==nullPtr) cnt_econ_--;
156  else cnt_icon_--;
157  INPUT_con_.erase(it);
158  }
159  if (cnt_econ_==0) hasEquality_ = false;
160  if (cnt_icon_==0) hasInequality_ = false;
161 }
162 
163 template<typename Real>
164 void Problem<Real>::addLinearConstraint( std::string name,
165  const Ptr<Constraint<Real>> &linear_econ,
166  const Ptr<Vector<Real>> &linear_emul,
167  const Ptr<Vector<Real>> &linear_eres,
168  bool reset) {
169  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
170  ">>> ROL::Problem: Cannot add linear constraint after problem is finalized!");
171 
172  if (reset) INPUT_linear_con_.clear();
173 
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!");
177 
178  INPUT_linear_con_.insert({name,ConstraintData<Real>(linear_econ,linear_emul,linear_eres)});
179  hasLinearEquality_ = true;
180  cnt_linear_econ_++;
181 }
182 
183 template<typename Real>
184 void Problem<Real>::addLinearConstraint( std::string name,
185  const Ptr<Constraint<Real>> &linear_icon,
186  const Ptr<Vector<Real>> &linear_imul,
187  const Ptr<BoundConstraint<Real>> &linear_ibnd,
188  const Ptr<Vector<Real>> &linear_ires,
189  bool reset) {
190  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
191  ">>> ROL::Problem: Cannot add linear constraint after problem is finalized!");
192 
193  if (reset) INPUT_linear_con_.clear();
194 
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!");
198 
199  INPUT_linear_con_.insert({name,ConstraintData<Real>(linear_icon,linear_imul,linear_ires,linear_ibnd)});
200  hasLinearInequality_ = true;
201  cnt_linear_icon_++;
202 }
203 
204 template<typename Real>
206  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
207  ">>> ROL::Problem: Cannot remove linear inequality after problem is finalized!");
208 
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);
214  }
215  if (cnt_linear_econ_==0) hasLinearEquality_ = false;
216  if (cnt_linear_icon_==0) hasLinearInequality_ = false;
217 }
218 
219 template<typename Real>
220 void Problem<Real>::setProjectionAlgorithm(ParameterList &list) {
221  ROL_TEST_FOR_EXCEPTION(isFinalized_,std::invalid_argument,
222  ">>> ROL::Problem: Cannot set polyhedral projection algorithm after problem is finalized!");
223 
224  ppa_list_ = list;
225 }
226 
227 template<typename Real>
228 void Problem<Real>::finalize(bool lumpConstraints, bool printToStream, std::ostream &outStream) {
229  if (!isFinalized_) {
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;
242  }
243  else {
244  lcon.insert(INPUT_linear_con_.begin(),INPUT_linear_con_.end());
245  }
246  // Transform optimization problem
247  //std::cout << hasBounds_ << " " << hasEquality << " " << hasInequality << " " << hasLinearEquality << " " << hasLinearInequality << std::endl;
248  bool proxCompatible = false;
249  if (!hasLinearEquality && !hasLinearInequality) {
250  proj_ = nullPtr;
251  if (!hasEquality && !hasInequality && !hasBounds_) {
252  problemType_ = TYPE_U;
253  obj_ = INPUT_obj_;
254  xprim_ = INPUT_xprim_;
255  xdual_ = INPUT_xdual_;
256  bnd_ = nullPtr;
257  con_ = nullPtr;
258  mul_ = nullPtr;
259  res_ = nullPtr;
260  if (hasProx_) { prox_ = INPUT_prox_; }
261  else { prox_ = nullPtr; }
262  proxCompatible = true;
263  }
264  else if (!hasEquality && !hasInequality && hasBounds_) {
265  problemType_ = TYPE_B;
266  obj_ = INPUT_obj_;
267  xprim_ = INPUT_xprim_;
268  xdual_ = INPUT_xdual_;
269  bnd_ = INPUT_bnd_;
270  con_ = nullPtr;
271  mul_ = nullPtr;
272  res_ = nullPtr;
273  }
274  else if (hasEquality && !hasInequality && !hasBounds_) {
275  ConstraintAssembler<Real> cm(con,INPUT_xprim_,INPUT_xdual_);
276  problemType_ = TYPE_E;
277  obj_ = INPUT_obj_;
278  xprim_ = INPUT_xprim_;
279  xdual_ = INPUT_xdual_;
280  bnd_ = nullPtr;
281  con_ = cm.getConstraint();
282  mul_ = cm.getMultiplier();
283  res_ = cm.getResidual();
284  }
285  else {
286  ConstraintAssembler<Real> cm(con,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_);
287  problemType_ = TYPE_EB;
288  obj_ = INPUT_obj_;
289  if (cm.hasInequality()) {
290  obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
291  }
292  xprim_ = cm.getOptVector();
293  xdual_ = cm.getDualOptVector();
294  bnd_ = cm.getBoundConstraint();
295  con_ = cm.getConstraint();
296  mul_ = cm.getMultiplier();
297  res_ = cm.getResidual();
298  }
299  }
300  else {
301  if (!hasBounds_ && !hasLinearInequality) {
302  ConstraintAssembler<Real> cm(lcon,INPUT_xprim_,INPUT_xdual_);
303  xfeas_ = cm.getOptVector()->clone(); xfeas_->set(*cm.getOptVector());
304  rlc_ = makePtr<ReduceLinearConstraint<Real>>(cm.getConstraint(),xfeas_,cm.getResidual());
305  proj_ = nullPtr;
306  if (!hasEquality && !hasInequality) {
307  problemType_ = TYPE_U;
308  obj_ = rlc_->transform(INPUT_obj_);
309  xprim_ = xfeas_->clone(); xprim_->zero();
310  xdual_ = cm.getDualOptVector();
311  bnd_ = nullPtr;
312  con_ = nullPtr;
313  mul_ = nullPtr;
314  res_ = nullPtr;
315  }
316  else {
317  for (auto it = con.begin(); it != con.end(); ++it) {
318  icon.insert(std::pair<std::string,ConstraintData<Real>>(it->first,
319  ConstraintData<Real>(rlc_->transform(it->second.constraint),
320  it->second.multiplier,it->second.residual,it->second.bounds)));
321  }
322  Ptr<Vector<Real>> xtmp = xfeas_->clone(); xtmp->zero();
323  ConstraintAssembler<Real> cm1(icon,xtmp,cm.getDualOptVector());
324  xprim_ = cm1.getOptVector();
325  xdual_ = cm1.getDualOptVector();
326  con_ = cm1.getConstraint();
327  mul_ = cm1.getMultiplier();
328  res_ = cm1.getResidual();
329  if (!hasInequality) {
330  problemType_ = TYPE_E;
331  obj_ = rlc_->transform(INPUT_obj_);
332  bnd_ = nullPtr;
333  }
334  else {
335  problemType_ = TYPE_EB;
336  obj_ = makePtr<SlacklessObjective<Real>>(rlc_->transform(INPUT_obj_));
337  bnd_ = cm1.getBoundConstraint();
338  }
339  }
340  }
341  else if ((hasBounds_ || hasLinearInequality) && !hasEquality && !hasInequality) {
342  ConstraintAssembler<Real> cm(lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_);
343  problemType_ = TYPE_B;
344  obj_ = INPUT_obj_;
345  if (cm.hasInequality()) {
346  obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
347  }
348  xprim_ = cm.getOptVector();
349  xdual_ = cm.getDualOptVector();
350  bnd_ = cm.getBoundConstraint();
351  con_ = nullPtr;
352  mul_ = nullPtr;
353  res_ = nullPtr;
354  proj_ = PolyhedralProjectionFactory<Real>(*xprim_,*xdual_,bnd_,
355  cm.getConstraint(),*cm.getMultiplier(),*cm.getResidual(),ppa_list_);
356  }
357  else {
358  ConstraintAssembler<Real> cm(con,lcon,INPUT_xprim_,INPUT_xdual_,INPUT_bnd_);
359  problemType_ = TYPE_EB;
360  obj_ = INPUT_obj_;
361  if (cm.hasInequality()) {
362  obj_ = makePtr<SlacklessObjective<Real>>(INPUT_obj_);
363  }
364  xprim_ = cm.getOptVector();
365  xdual_ = cm.getDualOptVector();
366  con_ = cm.getConstraint();
367  mul_ = cm.getMultiplier();
368  res_ = cm.getResidual();
369  bnd_ = cm.getBoundConstraint();
370  proj_ = PolyhedralProjectionFactory<Real>(*xprim_,*xdual_,bnd_,
372  *cm.getLinearResidual(),ppa_list_);
373  }
374  }
375 
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());
384 
385  isFinalized_ = true;
386  if (printToStream) {
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;
392  if (hasEquality) {
393  int cnt = 0;
394  for (auto it = con.begin(); it != con.end(); ++it) {
395  if (it->second.bounds==nullPtr) {
396  if (cnt==0) {
397  outStream << " Names: ........................... ";
398  cnt++;
399  }
400  else {
401  outStream << " ";
402  }
403  outStream << it->first << std::endl;
404  }
405  }
406  outStream << " Total: ........................... " << cnt_econ_+(lumpConstraints ? cnt_linear_econ_ : 0) << std::endl;
407  }
408  outStream << " Has Inequality Constraint? ......... " << (hasInequality ? "yes" : "no") << std::endl;
409  if (hasInequality) {
410  int cnt = 0;
411  for (auto it = con.begin(); it != con.end(); ++it) {
412  if (it->second.bounds!=nullPtr) {
413  if (cnt==0) {
414  outStream << " Names: ........................... ";
415  cnt++;
416  }
417  else {
418  outStream << " ";
419  }
420  outStream << it->first << std::endl;
421  }
422  }
423  outStream << " Total: ........................... " << cnt_icon_+(lumpConstraints ? cnt_linear_icon_ : 0) << std::endl;
424  }
425  if (!lumpConstraints) {
426  outStream << " Has Linear Equality Constraint? .... " << (hasLinearEquality ? "yes" : "no") << std::endl;
427  if (hasLinearEquality) {
428  int cnt = 0;
429  for (auto it = lcon.begin(); it != lcon.end(); ++it) {
430  if (it->second.bounds==nullPtr) {
431  if (cnt==0) {
432  outStream << " Names: ........................... ";
433  cnt++;
434  }
435  else {
436  outStream << " ";
437  }
438  outStream << it->first << std::endl;
439  }
440  }
441  outStream << " Total: ........................... " << cnt_linear_econ_ << std::endl;
442  }
443  outStream << " Has Linear Inequality Constraint? .. " << (hasLinearInequality ? "yes" : "no") << std::endl;
444  if (hasLinearInequality) {
445  int cnt = 0;
446  for (auto it = lcon.begin(); it != lcon.end(); ++it) {
447  if (it->second.bounds!=nullPtr) {
448  if (cnt==0) {
449  outStream << " Names: ........................... ";
450  cnt++;
451  }
452  else {
453  outStream << " ";
454  }
455  outStream << it->first << std::endl;
456  }
457  }
458  outStream << " Total: ........................... " << cnt_linear_icon_ << std::endl;
459  }
460  }
461  outStream << std::endl;
462  }
463  }
464  else {
465  if (printToStream) {
466  outStream << std::endl;
467  outStream << " ROL::Problem::finalize" << std::endl;
468  outStream << " Problem already finalized!" << std::endl;
469  outStream << std::endl;
470  }
471  }
472 }
473 
474 template<typename Real>
475 const Ptr<Objective<Real>>& Problem<Real>::getObjective() {
476  finalize();
477  return obj_;
478 }
479 
480 template<typename Real>
481 const Ptr<Vector<Real>>& Problem<Real>::getPrimalOptimizationVector() {
482  finalize();
483  return xprim_;
484 }
485 
486 template<typename Real>
487 const Ptr<Vector<Real>>& Problem<Real>::getDualOptimizationVector() {
488  finalize();
489  return xdual_;
490 }
491 
492 template<typename Real>
493 const Ptr<BoundConstraint<Real>>& Problem<Real>::getBoundConstraint() {
494  finalize();
495  return bnd_;
496 }
497 
498 template<typename Real>
499 const Ptr<Constraint<Real>>& Problem<Real>::getConstraint() {
500  finalize();
501  return con_;
502 }
503 
504 template<typename Real>
505 const Ptr<Vector<Real>>& Problem<Real>::getMultiplierVector() {
506  finalize();
507  return mul_;
508 }
509 
510 template<typename Real>
511 const Ptr<Vector<Real>>& Problem<Real>::getResidualVector() {
512  finalize();
513  return res_;
514 }
515 
516 template<typename Real>
517 const Ptr<PolyhedralProjection<Real>>& Problem<Real>::getPolyhedralProjection() {
518  finalize();
519  return proj_;
520 }
521 
522 template<typename Real>
524  finalize();
525  return problemType_;
526 }
527 
528 template<typename Real>
529 Real Problem<Real>::checkLinearity(bool printToStream, std::ostream &outStream) const {
530  std::ios_base::fmtflags state(outStream.flags());
531  if (printToStream) {
532  outStream << std::setprecision(8) << std::scientific;
533  outStream << std::endl;
534  outStream << " ROL::Problem::checkLinearity" << std::endl;
535  }
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();
548  it->second.constraint->update(*xy,UpdateType::Temp);
549  it->second.constraint->value(*c1,*xy,tol);
550  cnorm = c1->norm();
551  it->second.constraint->update(*x,UpdateType::Temp);
552  it->second.constraint->value(*c2,*x,tol);
553  c1->axpy(-one,*c2);
554  it->second.constraint->update(*y,UpdateType::Temp);
555  it->second.constraint->value(*c2,*y,tol);
556  c1->axpy(-alpha,*c2);
557  it->second.constraint->update(*z,UpdateType::Temp);
558  it->second.constraint->value(*c2,*z,tol);
559  c1->axpy(alpha,*c2);
560  err = c1->norm();
561  maxerr = std::max(err,maxerr);
562  if (printToStream) {
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;
567  }
568  }
569  }
570  if (printToStream) {
571  outStream << std::endl;
572  }
573  outStream.flags(state);
574  return maxerr;
575 }
576 
577 template<typename Real>
578 void Problem<Real>::checkVectors(bool printToStream, std::ostream &outStream) const {
579  const Real one(1);
580  Ptr<Vector<Real>> x, y;
581  // Primal optimization space vector
582  x = INPUT_xprim_->clone(); x->randomize(-one,one);
583  y = INPUT_xprim_->clone(); y->randomize(-one,one);
584  if (printToStream) {
585  outStream << std::endl << " Check primal optimization space vector" << std::endl;
586  }
587  INPUT_xprim_->checkVector(*x,*y,printToStream,outStream);
588 
589  // Dual optimization space vector
590  x = INPUT_xdual_->clone(); x->randomize(-one,one);
591  y = INPUT_xdual_->clone(); y->randomize(-one,one);
592  if (printToStream) {
593  outStream << std::endl << " Check dual optimization space vector" << std::endl;
594  }
595  INPUT_xdual_->checkVector(*x,*y,printToStream,outStream);
596 
597  // Check constraint space vectors
598  for (auto it = INPUT_con_.begin(); it != INPUT_con_.end(); ++it) {
599  // Primal constraint space vector
600  x = it->second.residual->clone(); x->randomize(-one,one);
601  y = it->second.residual->clone(); y->randomize(-one,one);
602  if (printToStream) {
603  outStream << std::endl << " " << it->first << ": Check primal constraint space vector" << std::endl;
604  }
605  it->second.residual->checkVector(*x,*y,printToStream,outStream);
606 
607  // Dual optimization space vector
608  x = it->second.multiplier->clone(); x->randomize(-one,one);
609  y = it->second.multiplier->clone(); y->randomize(-one,one);
610  if (printToStream) {
611  outStream << std::endl << " " << it->first << ": Check dual constraint space vector" << std::endl;
612  }
613  it->second.multiplier->checkVector(*x,*y,printToStream,outStream);
614  }
615 
616  // Check constraint space vectors
617  for (auto it = INPUT_linear_con_.begin(); it != INPUT_linear_con_.end(); ++it) {
618  // Primal constraint space vector
619  x = it->second.residual->clone(); x->randomize(-one,one);
620  y = it->second.residual->clone(); y->randomize(-one,one);
621  if (printToStream) {
622  outStream << std::endl << " " << it->first << ": Check primal linear constraint space vector" << std::endl;
623  }
624  it->second.residual->checkVector(*x,*y,printToStream,outStream);
625 
626  // Dual optimization space vector
627  x = it->second.multiplier->clone(); x->randomize(-one,one);
628  y = it->second.multiplier->clone(); y->randomize(-one,one);
629  if (printToStream) {
630  outStream << std::endl << " " << it->first << ": Check dual linear constraint space vector" << std::endl;
631  }
632  it->second.multiplier->checkVector(*x,*y,printToStream,outStream);
633  }
634 }
635 
636 template<typename Real>
637 void Problem<Real>::checkDerivatives(bool printToStream, std::ostream &outStream) const {
638  const Real one(1);
639  Ptr<Vector<Real>> x, d, v, g, c, w;
640  // Objective check
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);
645  if (printToStream) {
646  outStream << std::endl << " Check objective function" << std::endl << std::endl;
647  }
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);
651 
652  // Constraint check
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);
656  if (printToStream) {
657  outStream << std::endl << " " << it->first << ": Check constraint function" << std::endl << std::endl;
658  }
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);
662  }
663 
664  // Linear constraint check
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);
668  if (printToStream) {
669  outStream << std::endl << " " << it->first << ": Check constraint function" << std::endl << std::endl;
670  }
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);
674  }
675 }
676 
677 template<typename Real>
678 void Problem<Real>::check(bool printToStream, std::ostream &outStream) const {
679  checkVectors(printToStream,outStream);
680  if (hasLinearEquality_ || hasLinearInequality_) {
681  checkLinearity(printToStream,outStream);
682  }
683  checkDerivatives(printToStream,outStream);
684 }
685 
686 template<typename Real>
688  return isFinalized_;
689 }
690 
691 template<typename Real>
693  isFinalized_ = false;
694  rlc_ = nullPtr;
695  proj_ = nullPtr;
696 }
697 
698 template<typename Real>
700  if (rlc_ != nullPtr) {
701  if (!hasInequality_) {
702  rlc_->project(*INPUT_xprim_,*xprim_);
703  INPUT_xprim_->plus(*rlc_->getFeasibleVector());
704  }
705  else {
706  Ptr<Vector<Real>> xprim = dynamic_cast<PartitionedVector<Real>&>(*xprim_).get(0)->clone();
707  xprim->set(*dynamic_cast<PartitionedVector<Real>&>(*xprim_).get(0));
708  rlc_->project(*INPUT_xprim_,*xprim);
709  INPUT_xprim_->plus(*rlc_->getFeasibleVector());
710  }
711  }
712 }
713 
714 } // namespace ROL
715 
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.
Definition: ROL_Vector.hpp:80
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.
EProblem
Definition: ROL_Types.hpp:257
const Ptr< Obj > obj_
const Ptr< Vector< Real > > & getResidual() const
Defines the general constraint operator interface.
void setProjectionAlgorithm(ParameterList &parlist)
Set polyhedral projection algorithm.