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
49namespace ROL {
50
51template<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
71template<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
80template<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
89template<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
98template<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
107template<typename Real>
108void 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
127template<typename Real>
128void 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
148template<typename Real>
149void 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
163template<typename Real>
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
183template<typename Real>
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
204template<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
219template<typename Real>
220void 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
227template<typename Real>
228void 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();
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
474template<typename Real>
475const Ptr<Objective<Real>>& Problem<Real>::getObjective() {
476 finalize();
477 return obj_;
478}
479
480template<typename Real>
482 finalize();
483 return xprim_;
484}
485
486template<typename Real>
488 finalize();
489 return xdual_;
490}
491
492template<typename Real>
493const Ptr<BoundConstraint<Real>>& Problem<Real>::getBoundConstraint() {
494 finalize();
495 return bnd_;
496}
497
498template<typename Real>
499const Ptr<Constraint<Real>>& Problem<Real>::getConstraint() {
500 finalize();
501 return con_;
502}
503
504template<typename Real>
505const Ptr<Vector<Real>>& Problem<Real>::getMultiplierVector() {
506 finalize();
507 return mul_;
508}
509
510template<typename Real>
511const Ptr<Vector<Real>>& Problem<Real>::getResidualVector() {
512 finalize();
513 return res_;
514}
515
516template<typename Real>
517const Ptr<PolyhedralProjection<Real>>& Problem<Real>::getPolyhedralProjection() {
518 finalize();
519 return proj_;
520}
521
522template<typename Real>
524 finalize();
525 return problemType_;
526}
527
528template<typename Real>
529Real 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
577template<typename Real>
578void 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
636template<typename Real>
637void 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
677template<typename Real>
678void 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
686template<typename Real>
688 return isFinalized_;
689}
690
691template<typename Real>
693 isFinalized_ = false;
694 rlc_ = nullPtr;
695 proj_ = nullPtr;
696}
697
698template<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
const Ptr< Obj > obj_
Provides the interface to apply upper and lower bound constraints.
Provides a wrapper for multiple constraints.
const Ptr< Constraint< Real > > & getLinearConstraint() const
const Ptr< Vector< Real > > & getMultiplier() const
const Ptr< Vector< Real > > & getLinearResidual() const
const Ptr< Vector< Real > > & getDualOptVector() const
const Ptr< BoundConstraint< Real > > & getBoundConstraint() const
const Ptr< Constraint< Real > > & getConstraint() const
const Ptr< Vector< Real > > & getLinearMultiplier() const
const Ptr< Vector< Real > > & getOptVector() const
const Ptr< Vector< Real > > & getResidual() const
Defines the general constraint operator interface.
Provides the interface to evaluate objective functions.
Defines the linear algebra of vector space on a generic partitioned vector.
ROL::Ptr< const Vector< Real > > get(size_type i) const
Ptr< BoundConstraint< Real > > INPUT_bnd_
const Ptr< PolyhedralProjection< Real > > & getPolyhedralProjection()
Get the polyhedral projection object. This is a null pointer if no linear constraints and/or bounds a...
Ptr< Objective< Real > > INPUT_obj_
const Ptr< Vector< Real > > & getPrimalOptimizationVector()
Get the primal optimization space vector.
void removeConstraint(std::string name)
Remove an existing constraint.
const Ptr< Vector< Real > > & getDualOptimizationVector()
Get the dual optimization space vector.
void removeLinearConstraint(std::string name)
Remove an existing linear constraint.
bool isFinalized() const
Indicate whether or no finalize has been called.
const Ptr< Vector< Real > > & getMultiplierVector()
Get the dual constraint space vector.
const Ptr< Constraint< Real > > & getConstraint()
Get the equality constraint.
void checkVectors(bool printToStream=false, std::ostream &outStream=std::cout) const
Run vector checks for user-supplied vectors.
std::unordered_map< std::string, ConstraintData< Real > > INPUT_linear_con_
void removeBoundConstraint()
Remove an existing bound constraint.
EProblem getProblemType()
Get the optimization problem type (U, B, E, or G).
void addProxObjective(const Ptr< ProxObjective< Real > > &prox)
Add a prox objective.
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 addBoundConstraint(const Ptr< BoundConstraint< Real > > &bnd)
Add a bound constraint.
void setProjectionAlgorithm(ParameterList &parlist)
Set polyhedral projection algorithm.
void finalizeIteration()
Transform the optimization variables to the native parameterization after an optimization algorithm h...
Ptr< Vector< Real > > INPUT_xdual_
std::unordered_map< std::string, ConstraintData< Real > > INPUT_con_
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.
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...
Ptr< Vector< Real > > INPUT_xprim_
void removeProxObjective()
Remove an existing prox objective.
void checkDerivatives(bool printToStream=false, std::ostream &outStream=std::cout) const
Run derivative checks for user-supplied objective function and constraints.
const Ptr< Objective< Real > > & getObjective()
Get the objective function.
const Ptr< BoundConstraint< Real > > & getBoundConstraint()
Get the bound constraint.
const Ptr< Vector< Real > > & getResidualVector()
Get the primal constraint space vector.
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...
virtual void edit()
Resume editting optimization problem after finalize has been called.
Real checkLinearity(bool printToStream=false, std::ostream &outStream=std::cout) const
Check if user-supplied linear constraints are affine.
Problem(const Ptr< Objective< Real > > &obj, const Ptr< Vector< Real > > &x, const Ptr< Vector< Real > > &g=nullPtr)
Default constructor for OptimizationProblem.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:84
EProblem
Definition: ROL_Types.hpp:257
@ TYPE_U
Definition: ROL_Types.hpp:258
@ TYPE_E
Definition: ROL_Types.hpp:260
@ TYPE_EB
Definition: ROL_Types.hpp:261
@ TYPE_B
Definition: ROL_Types.hpp:259