ROL
ROL_HelperFunctions.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
15#ifndef ROL_HELPERFUNCTIONS_HPP
16#define ROL_HELPERFUNCTIONS_HPP
17
18#include "ROL_Vector.hpp"
19#include "ROL_Objective.hpp"
21#include "ROL_Secant.hpp"
22#include "ROL_LinearAlgebra.hpp"
23#include "ROL_LAPACK.hpp"
24
25namespace ROL {
26
27 template<class Real>
28 ROL::LA::Matrix< Real> computeDenseHessian(Objective<Real> &obj, const Vector<Real> &x) {
29
30 Real tol = std::sqrt(ROL_EPSILON<Real>());
31
32 int dim = x.dimension();
33 ROL::LA::Matrix< Real> H(dim, dim);
34
35 ROL::Ptr<Vector<Real> > e = x.clone();
36 ROL::Ptr<Vector<Real> > h = x.dual().clone();
37
38 for (int i=0; i<dim; i++) {
39 e = x.basis(i);
40 obj.hessVec(*h, *e, x, tol);
41 for (int j=0; j<dim; j++) {
42 e = x.basis(j);
43 //H(j,i) = e->dot(h->dual());
44 H(j,i) = e->apply(*h);
45 }
46 }
47
48 return H;
49
50 }
51
52
53 template<class Real>
54 ROL::LA::Matrix< Real> computeScaledDenseHessian(Objective<Real> &obj, const Vector<Real> &x) {
55
56 Real tol = std::sqrt(ROL_EPSILON<Real>());
57
58 int dim = x.dimension();
59 ROL::LA::Matrix< Real> H(dim, dim);
60
61 ROL::Ptr<Vector<Real> > ei = x.clone();
62 ROL::Ptr<Vector<Real> > ej = x.dual().clone();
63 ROL::Ptr<Vector<Real> > h = x.dual().clone();
64
65 for (int i=0; i<dim; i++) {
66 ei = ei->basis(i);
67 obj.hessVec(*h, *ei, x, tol);
68 for (int j=0; j<dim; j++) {
69 ej = ej->basis(j);
70 H(j,i) = ej->dot(*h);
71 }
72 }
73
74 return H;
75
76 }
77
78
79 template<class Real>
80 ROL::LA::Matrix< Real> computeDotMatrix(const Vector<Real> &x) {
81
82 int dim = x.dimension();
83 ROL::LA::Matrix< Real> M(dim, dim);
84
85 ROL::Ptr<Vector<Real> > ei = x.clone();
86 ROL::Ptr<Vector<Real> > ej = x.clone();
87
88 for (int i=0; i<dim; i++) {
89 ei = x.basis(i);
90 for (int j=0; j<dim; j++) {
91 ej = x.basis(j);
92 M(j,i) = ej->dot(*ei);
93 }
94 }
95
96 return M;
97
98 }
99
100 template<class Real>
101 std::vector<std::vector<Real> > computeEigenvalues(const ROL::LA::Matrix< Real> & mat) {
102
103 ROL::LAPACK<int, Real> lapack;
104
105 ROL::LA::Matrix< Real> mymat(mat);
106
107 char jobvl = 'N';
108 char jobvr = 'N';
109
110 int n = mat.numRows();
111
112 std::vector<Real> real(n, 0);
113 std::vector<Real> imag(n, 0);
114 std::vector<std::vector<Real> > eigenvals;
115
116 Real* vl = 0;
117 Real* vr = 0;
118
119 int ldvl = 1;
120 int ldvr = 1;
121
122 int lwork = 4*n;
123
124 std::vector<Real> work(lwork, 0);
125
126 int info = 0;
127
128 lapack.GEEV(jobvl, jobvr, n, &mymat(0,0), n, &real[0], &imag[0], vl, ldvl, vr, ldvr, &work[0], lwork, &info);
129
130 eigenvals.push_back(real);
131 eigenvals.push_back(imag);
132
133 return eigenvals;
134
135 }
136
137
138 template<class Real>
139 std::vector<std::vector<Real> > computeGenEigenvalues(const ROL::LA::Matrix< Real> & A,
140 const ROL::LA::Matrix< Real> & B) {
141
142 ROL::LAPACK<int, Real> lapack;
143
144 ROL::LA::Matrix< Real> myA(A);
145 ROL::LA::Matrix< Real> myB(B);
146
147 char jobvl = 'N';
148 char jobvr = 'N';
149
150 int n = A.numRows();
151
152 std::vector<Real> real(n, 0);
153 std::vector<Real> imag(n, 0);
154 std::vector<Real> beta(n, 0);
155 std::vector<std::vector<Real> > eigenvals;
156
157 Real* vl = 0;
158 Real* vr = 0;
159
160 int ldvl = 1;
161 int ldvr = 1;
162
163 int lwork = 10*n;
164
165 std::vector<Real> work(lwork, 0);
166
167 int info = 0;
168
169 lapack.GGEV(jobvl, jobvr, n, &myA(0,0), n, &myB(0,0), n, &real[0], &imag[0], &beta[0],
170 vl, ldvl, vr, ldvr, &work[0], lwork, &info);
171
172 for (int i=0; i<n; i++) {
173 real[i] /= beta[i];
174 imag[i] /= beta[i];
175 }
176
177 eigenvals.push_back(real);
178 eigenvals.push_back(imag);
179
180 return eigenvals;
181
182 }
183
184
185 template<class Real>
186 ROL::LA::Matrix< Real> computeInverse(const ROL::LA::Matrix< Real> & mat) {
187
188 ROL::LAPACK<int, Real> lapack;
189
190 ROL::LA::Matrix< Real> mymat(mat);
191
192 int n = mat.numRows();
193
194 std::vector<int> ipiv(n, 0);
195
196 int lwork = 5*n;
197
198 std::vector<Real> work(lwork, 0);
199
200 int info = 0;
201
202 lapack.GETRF(n, n, &mymat(0,0), n, &ipiv[0], &info);
203 lapack.GETRI(n, &mymat(0,0), n, &ipiv[0], &work[0], lwork, &info);
204
205 return mymat;
206
207 }
208
209
210
211 template<class Real>
212 class ProjectedObjective : public Objective<Real> {
213 private:
214 ROL::Ptr<Objective<Real> > obj_;
215 ROL::Ptr<BoundConstraint<Real> > con_;
216 ROL::Ptr<Secant<Real> > secant_;
217
218 ROL::Ptr<ROL::Vector<Real> > primalV_;
219 ROL::Ptr<ROL::Vector<Real> > dualV_;
221
224 Real eps_;
225
226 public:
228 ROL::Ptr<Secant<Real> > &secant,
229 bool useSecantPrecond = false,
230 bool useSecantHessVec = false,
231 Real eps = 0.0 )
232 : isInitialized_(false), useSecantPrecond_(useSecantPrecond),
233 useSecantHessVec_(useSecantHessVec), eps_(eps) {
234 obj_ = ROL::makePtrFromRef(obj);
235 con_ = ROL::makePtrFromRef(con);
236 secant_ = secant;
237 }
238
239 void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
240 obj_->update(x,flag,iter);
241 con_->update(x,flag,iter);
242 }
243
244 Real value( const Vector<Real> &x, Real &tol ) {
245 return obj_->value(x,tol);
246 }
247
248 void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
249 obj_->gradient(g,x,tol);
250 }
251
252 Real dirDeriv( const Vector<Real> &x, const Vector<Real> &d, Real &tol ) {
253 return obj_->dirDeriv(x,d,tol);
254 }
255
256 void hessVec( Vector<Real> &Hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
257 if ( useSecantHessVec_ ) {
258 secant_->applyB( Hv, v );
259 }
260 else {
261 obj_->hessVec( Hv, v, x, tol );
262 }
263 }
264
265 void invHessVec( Vector<Real> &Hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
266 if ( useSecantHessVec_ ) {
267 secant_->applyH(Hv,v);
268 }
269 else {
270 obj_->invHessVec(Hv,v,x,tol);
271 }
272 }
273
274 void precond( Vector<Real> &Mv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
275 if ( useSecantPrecond_ ) {
276 secant_->applyH( Mv, v );
277 }
278 else {
279 obj_->precond( Mv, v, x, tol );
280 }
281 }
282
295 const Vector<Real> &d, const Vector<Real> &x, Real &tol ) {
296 if ( con_->isActivated() ) {
297 if (!isInitialized_) {
298 primalV_ = x.clone();
299 dualV_ = x.dual().clone();
300 isInitialized_ = true;
301 }
302 // Set vnew to v
303 primalV_->set(v);
304 // Remove elements of vnew corresponding to binding set
305 con_->pruneActive(*primalV_,d,p,eps_);
306 // Apply full Hessian to reduced vector
307 hessVec(Hv,*primalV_,x,tol);
308 // Remove elements of Hv corresponding to binding set
309 con_->pruneActive(Hv,d,p,eps_);
310 // Set vnew to v
311 primalV_->set(v);
312 // Remove Elements of vnew corresponding to complement of binding set
313 con_->pruneInactive(*primalV_,d,p,eps_);
314 dualV_->set(primalV_->dual());
315 con_->pruneInactive(*dualV_,d,p,eps_);
316 // Fill complement of binding set elements in Hp with v
317 Hv.plus(*dualV_);
318 }
319 else {
320 hessVec(Hv,v,x,tol);
321 }
322 }
323
335 const Vector<Real> &x, Real &tol ) {
336 if ( con_->isActivated() ) {
337 if (!isInitialized_) {
338 primalV_ = x.clone();
339 dualV_ = x.dual().clone();
340 isInitialized_ = true;
341 }
342 // Set vnew to v
343 primalV_->set(v);
344 // Remove elements of vnew corresponding to binding set
345 con_->pruneActive(*primalV_,p,eps_);
346 // Apply full Hessian to reduced vector
347 hessVec(Hv,*primalV_,x,tol);
348 // Remove elements of Hv corresponding to binding set
349 con_->pruneActive(Hv,p,eps_);
350 // Set vnew to v
351 primalV_->set(v);
352 // Remove Elements of vnew corresponding to complement of binding set
353 con_->pruneInactive(*primalV_,p,eps_);
354 dualV_->set(primalV_->dual());
355 con_->pruneInactive(*dualV_,p,eps_);
356 // Fill complement of binding set elements in Hp with v
357 Hv.plus(*dualV_);
358 }
359 else {
360 hessVec(Hv,v,x,tol);
361 }
362 }
363
376 const Vector<Real> &d, const Vector<Real> &x, Real &tol ) {
377 if ( con_->isActivated() ) {
378 if (!isInitialized_) {
379 primalV_ = x.clone();
380 dualV_ = x.dual().clone();
381 isInitialized_ = true;
382 }
383 // Set vnew to v
384 dualV_->set(v);
385 // Remove elements of vnew corresponding to binding set
386 con_->pruneActive(*dualV_,d,p,eps_);
387 // Apply full Hessian to reduced vector
388 invHessVec(Hv,*dualV_,x,tol);
389 // Remove elements of Hv corresponding to binding set
390 con_->pruneActive(Hv,d,p,eps_);
391 // Set vnew to v
392 dualV_->set(v);
393 // Remove Elements of vnew corresponding to complement of binding set
394 con_->pruneInactive(*dualV_,d,p,eps_);
395 primalV_->set(dualV_->dual());
396 con_->pruneInactive(*primalV_,d,p,eps_);
397 // Fill complement of binding set elements in Hv with v
398 Hv.plus(*primalV_);
399 }
400 else {
401 invHessVec(Hv,v,x,tol);
402 }
403 }
404
416 const Vector<Real> &x, Real &tol ) {
417 if ( con_->isActivated() ) {
418 if (!isInitialized_) {
419 primalV_ = x.clone();
420 dualV_ = x.dual().clone();
421 isInitialized_ = true;
422 }
423 // Set vnew to v
424 dualV_->set(v);
425 // Remove elements of vnew corresponding to binding set
426 con_->pruneActive(*dualV_,p,eps_);
427 // Apply full Hessian to reduced vector
428 invHessVec(Hv,*dualV_,x,tol);
429 // Remove elements of Hv corresponding to binding set
430 con_->pruneActive(Hv,p,eps_);
431 // Set vnew to v
432 dualV_->set(v);
433 // Remove Elements of vnew corresponding to complement of binding set
434 con_->pruneInactive(*dualV_,p,eps_);
435 primalV_->set(dualV_->dual());
436 con_->pruneInactive(*primalV_,p,eps_);
437 // Fill complement of binding set elements in Hv with v
438 Hv.plus(*primalV_);
439 }
440 else {
441 invHessVec(Hv,v,x,tol);
442 }
443 }
444
456 void reducedPrecond( Vector<Real> &Mv, const Vector<Real> &v, const Vector<Real> &p,
457 const Vector<Real> &d, const Vector<Real> &x, Real &tol ) {
458 if ( con_->isActivated() ) {
459 if (!isInitialized_) {
460 primalV_ = x.clone();
461 dualV_ = x.dual().clone();
462 isInitialized_ = true;
463 }
464 // Set vnew to v
465 dualV_->set(v);
466 // Remove elements of vnew corresponding to binding set
467 con_->pruneActive(*dualV_,d,p,eps_);
468 // Apply full Hessian to reduced vector
469 precond(Mv,*dualV_,x,tol);
470 // Remove elements of Mv corresponding to binding set
471 con_->pruneActive(Mv,d,p,eps_);
472 // Set vnew to v
473 dualV_->set(v);
474 // Remove Elements of vnew corresponding to complement of binding set
475 con_->pruneInactive(*dualV_,d,p,eps_);
476 primalV_->set(dualV_->dual());
477 con_->pruneInactive(*primalV_,d,p,eps_);
478 // Fill complement of binding set elements in Mv with v
479 Mv.plus(*primalV_);
480 }
481 else {
482 precond(Mv,v,x,tol);
483 }
484 }
485
496 void reducedPrecond( Vector<Real> &Mv, const Vector<Real> &v, const Vector<Real> &p,
497 const Vector<Real> &x, Real &tol ) {
498 if ( con_->isActivated() ) {
499 if (!isInitialized_) {
500 primalV_ = x.clone();
501 dualV_ = x.dual().clone();
502 isInitialized_ = true;
503 }
504 // Set vnew to v
505 dualV_->set(v);
506 // Remove elements of vnew corresponding to binding set
507 con_->pruneActive(*dualV_,p,eps_);
508 // Apply full Hessian to reduced vector
509 precond(Mv,*dualV_,x,tol);
510 // Remove elements of Mv corresponding to binding set
511 con_->pruneActive(Mv,p,eps_);
512 // Set vnew to v
513 dualV_->set(v);
514 // Remove Elements of vnew corresponding to complement of binding set
515 con_->pruneInactive(*dualV_,p,eps_);
516 primalV_->set(dualV_->dual());
517 con_->pruneInactive(*primalV_,p,eps_);
518 // Fill complement of binding set elements in Mv with v
519 Mv.plus(*primalV_);
520 }
521 else {
522 precond(Mv,v,x,tol);
523 }
524 }
525
527 con_->project(x);
528 }
529
530 void pruneActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x ) {
531 con_->pruneActive(v,g,x,eps_);
532 }
533
534 void pruneActive( Vector<Real> &v, const Vector<Real> &x ) {
535 con_->pruneActive(v,x,eps_);
536 }
537
538 void pruneInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x ) {
539 con_->pruneInactive(v,g,x,eps_);
540 }
541
543 con_->pruneInactive(v,x,eps_);
544 }
545
546 bool isFeasible( const Vector<Real> &v ) {
547 return con_->isFeasible(v);
548 }
549
550 bool isConActivated(void) {
551 return con_->isActivated();
552 }
553
555 con_->computeProjectedStep(v,x);
556 }
557 };
558
559} // namespace ROL
560
561#endif
Provides the interface to apply upper and lower bound constraints.
Provides the interface to evaluate objective functions.
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
void project(Vector< Real > &x)
ROL::Ptr< ROL::Vector< Real > > dualV_
Real value(const Vector< Real > &x, Real &tol)
Compute value.
void reducedPrecond(Vector< Real > &Mv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &d, const Vector< Real > &x, Real &tol)
Apply the reduced preconditioner to a vector, v. The reduced preconditioner first removes elements ...
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
void reducedInvHessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &x, Real &tol)
Apply the reduced inverse Hessian to a vector, v. The reduced inverse Hessian first removes element...
void reducedInvHessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &d, const Vector< Real > &x, Real &tol)
Apply the reduced inverse Hessian to a vector, v. The reduced inverse Hessian first removes element...
ROL::Ptr< ROL::Vector< Real > > primalV_
bool isFeasible(const Vector< Real > &v)
void pruneActive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x)
ROL::Ptr< BoundConstraint< Real > > con_
void pruneActive(Vector< Real > &v, const Vector< Real > &x)
void reducedHessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &d, const Vector< Real > &x, Real &tol)
Apply the reduced Hessian to a vector, v. The reduced Hessian first removes elements of v correspondi...
void reducedPrecond(Vector< Real > &Mv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &x, Real &tol)
Apply the reduced preconditioner to a vector, v. The reduced preconditioner first removes elements ...
void precond(Vector< Real > &Mv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply preconditioner to vector.
ROL::Ptr< Secant< Real > > secant_
void reducedHessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &p, const Vector< Real > &x, Real &tol)
Apply the reduced Hessian to a vector, v. The reduced Hessian first removes elements of v correspondi...
void pruneInactive(Vector< Real > &v, const Vector< Real > &x)
void invHessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply inverse Hessian approximation to vector.
void computeProjectedStep(Vector< Real > &v, const Vector< Real > &x)
ProjectedObjective(Objective< Real > &obj, BoundConstraint< Real > &con, ROL::Ptr< Secant< Real > > &secant, bool useSecantPrecond=false, bool useSecantHessVec=false, Real eps=0.0)
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update objective function.
void pruneInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x)
Real dirDeriv(const Vector< Real > &x, const Vector< Real > &d, Real &tol)
Compute directional derivative.
ROL::Ptr< Objective< Real > > obj_
void hessVec(Vector< Real > &Hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Provides interface for and implements limited-memory secant operators.
Defines the linear algebra or vector space interface.
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
virtual void plus(const Vector &x)=0
Compute , where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual int dimension() const
Return dimension of the vector space.
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
std::vector< std::vector< Real > > computeEigenvalues(const ROL::LA::Matrix< Real > &mat)
ROL::LA::Matrix< Real > computeDotMatrix(const Vector< Real > &x)
ROL::LA::Matrix< Real > computeScaledDenseHessian(Objective< Real > &obj, const Vector< Real > &x)
std::vector< std::vector< Real > > computeGenEigenvalues(const ROL::LA::Matrix< Real > &A, const ROL::LA::Matrix< Real > &B)
ROL::LA::Matrix< Real > computeDenseHessian(Objective< Real > &obj, const Vector< Real > &x)
ROL::LA::Matrix< Real > computeInverse(const ROL::LA::Matrix< Real > &mat)
constexpr auto dim