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