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