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
15namespace ROL {
16
17template<typename Real>
18Problem<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
39template<typename Real>
40void 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
48template<typename Real>
49void Problem<Real>::removeBoundConstraint() {
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
57template<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
66template<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}
74template<typename Real>
75void 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
94template<typename Real>
95void 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
115template<typename Real>
116void 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
130template<typename Real>
131void 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
150template<typename Real>
151void 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
171template<typename Real>
172void 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
186template<typename Real>
187void 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
194template<typename Real>
195void 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
448template<typename Real>
449const Ptr<Objective<Real>>& Problem<Real>::getObjective() {
450 finalize();
451 return obj_;
452}
453
454template<typename Real>
455const Ptr<Objective<Real>>& Problem<Real>::getProximableObjective(){
456 finalize();
457 return nobj_;
458}
459
460template<typename Real>
461const Ptr<Vector<Real>>& Problem<Real>::getPrimalOptimizationVector() {
462 finalize();
463 return xprim_;
464}
465
466template<typename Real>
467const Ptr<Vector<Real>>& Problem<Real>::getDualOptimizationVector() {
468 finalize();
469 return xdual_;
470}
471
472template<typename Real>
473const Ptr<BoundConstraint<Real>>& Problem<Real>::getBoundConstraint() {
474 finalize();
475 return bnd_;
476}
477
478template<typename Real>
479const Ptr<Constraint<Real>>& Problem<Real>::getConstraint() {
480 finalize();
481 return con_;
482}
483
484template<typename Real>
485const Ptr<Vector<Real>>& Problem<Real>::getMultiplierVector() {
486 finalize();
487 return mul_;
488}
489
490template<typename Real>
491const Ptr<Vector<Real>>& Problem<Real>::getResidualVector() {
492 finalize();
493 return res_;
494}
495
496template<typename Real>
497const Ptr<PolyhedralProjection<Real>>& Problem<Real>::getPolyhedralProjection() {
498 finalize();
499 return proj_;
500}
501
502template<typename Real>
503EProblem Problem<Real>::getProblemType() {
504 finalize();
505 return problemType_;
506}
507
508template<typename Real>
509Real 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
557template<typename Real>
558void 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
616template<typename Real>
617void 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
655template<typename Real>
656void 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
665template<typename Real>
666bool Problem<Real>::isFinalized() const {
667 return isFinalized_;
668}
669
670template<typename Real>
671void Problem<Real>::edit() {
672 isFinalized_ = false;
673 rlc_ = nullPtr;
674 proj_ = nullPtr;
675}
676
677template<typename Real>
678void Problem<Real>::finalizeIteration() {
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
const Ptr< Obj > obj_
Defines the general constraint operator interface.
Provides the interface to evaluate objective functions.
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.
@ TYPE_U
@ TYPE_E
@ TYPE_EB
@ TYPE_P
@ TYPE_B