ROL
poisson-inversion/example_02.cpp
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#include "ROL_StdVector.hpp"
16#include "ROL_Objective.hpp"
17#include "ROL_Bounds.hpp"
18#include "ROL_Algorithm.hpp"
21#include "ROL_StatusTest.hpp"
22#include "ROL_Types.hpp"
24#include "ROL_Stream.hpp"
25
26
27#include "Teuchos_GlobalMPISession.hpp"
28
29#include <fstream>
30#include <iostream>
31#include <algorithm>
32
33template<class Real>
35
36 typedef std::vector<Real> vector;
39
40 typedef typename vector::size_type uint;
41
42
43private:
46
47 Real hu_;
48 Real hz_;
49
50 Real u0_;
51 Real u1_;
52
53 Real alpha_;
54
56 Teuchos::SerialDenseMatrix<int, Real> H_;
57
58 ROL::Ptr<const vector> getVector( const V& x ) {
59
60 return dynamic_cast<const SV&>(x).getVector();
61 }
62
63 ROL::Ptr<vector> getVector( V& x ) {
64
65 return dynamic_cast<SV&>(x).getVector();
66 }
67
68public:
69
70 /* CONSTRUCTOR */
71 Objective_PoissonInversion(int nz = 32, Real alpha = 1.e-4)
72 : nz_(nz), u0_(1.0), u1_(0.0), alpha_(alpha), useCorrection_(false) {
73 nu_ = nz_-1;
74 hu_ = 1.0/((Real)nu_+1.0);
75 hz_ = hu_;
76 }
77
78 void apply_mass(std::vector<Real> &Mz, const std::vector<Real> &z ) {
79 Mz.resize(nu_,0.0);
80 for (uint i=0; i<nu_; i++) {
81 if ( i == 0 ) {
82 Mz[i] = hu_/6.0*(2.0*z[i] + z[i+1]);
83 }
84 else if ( i == nu_-1 ) {
85 Mz[i] = hu_/6.0*(z[i-1] + 2.0*z[i]);
86 }
87 else {
88 Mz[i] = hu_/6.0*(z[i-1] + 4.0*z[i] + z[i+1]);
89 }
90 }
91 }
92
93 Real evaluate_target(Real x) {
94 return (x <= 0.5) ? 1.0 : 0.0;
95 }
96
97 void apply_linearized_control_operator( std::vector<Real> &Bd, const std::vector<Real> &z,
98 const std::vector<Real> &d, const std::vector<Real> &u,
99 bool addBC = true ) {
100 Bd.clear();
101 Bd.resize(nu_,0.0);
102 for (uint i = 0; i < nu_; i++) {
103 if ( i == 0 ) {
104 Bd[i] = 1.0/hu_*( u[i]*d[i] + (u[i]-u[i+1])*d[i+1] );
105 }
106 else if ( i == nu_-1 ) {
107 Bd[i] = 1.0/hu_*( (u[i]-u[i-1])*d[i] + u[i]*d[i+1] );
108 }
109 else {
110 Bd[i] = 1.0/hu_*( (u[i]-u[i-1])*d[i] + (u[i]-u[i+1])*d[i+1] );
111 }
112 }
113 if ( addBC ) {
114 Bd[ 0] -= u0_*d[ 0]/hu_;
115 Bd[nu_-1] -= u1_*d[nz_-1]/hu_;
116 }
117 }
118
119 void apply_transposed_linearized_control_operator( std::vector<Real> &Bd, const std::vector<Real> &z,
120 const std::vector<Real> &d, const std::vector<Real> &u,
121 bool addBC = true ) {
122 Bd.clear();
123 Bd.resize(nz_,0.0);
124 for (uint i = 0; i < nz_; i++) {
125 if ( i == 0 ) {
126 Bd[i] = 1.0/hu_*u[i]*d[i];
127 }
128 else if ( i == nz_-1 ) {
129 Bd[i] = 1.0/hu_*u[i-1]*d[i-1];
130 }
131 else {
132 Bd[i] = 1.0/hu_*( (u[i]-u[i-1])*(d[i]-d[i-1]) );
133 }
134 }
135 if ( addBC ) {
136 Bd[ 0] -= u0_*d[ 0]/hu_;
137 Bd[nz_-1] -= u1_*d[nu_-1]/hu_;
138 }
139 }
140
141 /* STATE AND ADJOINT EQUATION DEFINTIONS */
142 void solve_state_equation(std::vector<Real> &u, const std::vector<Real> &z) {
143 // Get Diagonal and Off-Diagonal Entries of PDE Jacobian
144 std::vector<Real> d(nu_,1.0);
145 std::vector<Real> o(nu_-1,1.0);
146 for ( uint i = 0; i < nu_; i++ ) {
147 d[i] = (z[i] + z[i+1])/hu_;
148 if ( i < nu_-1 ) {
149 o[i] *= -z[i+1]/hu_;
150 }
151 }
152 // Set right hand side
153 u.clear();
154 u.resize(nu_,0.0);
155 u[ 0] = z[ 0]/hu_ * u0_;
156 u[nu_-1] = z[nz_-1]/hu_ * u1_;
157 // Solve Tridiagonal System Using LAPACK's SPD Tridiagonal Solver
158 Teuchos::LAPACK<int,Real> lp;
159 int info;
160 int ldb = nu_;
161 int nhrs = 1;
162 lp.PTTRF(nu_,&d[0],&o[0],&info);
163 lp.PTTRS(nu_,nhrs,&d[0],&o[0],&u[0],ldb,&info);
164 }
165
166 void solve_adjoint_equation(std::vector<Real> &p, const std::vector<Real> &u, const std::vector<Real> &z) {
167 // Get Diagonal and Off-Diagonal Entries of PDE Jacobian
168 vector d(nu_,1.0);
169 vector o(nu_-1,1.0);
170 for ( uint i = 0; i < nu_; i++ ) {
171 d[i] = (z[i] + z[i+1])/hu_;
172 if ( i < nu_-1 ) {
173 o[i] *= -z[i+1]/hu_;
174 }
175 }
176 // Set right hand side
177 vector r(nu_,0.0);
178 for (uint i = 0; i < nu_; i++) {
179 r[i] = -(u[i]-evaluate_target((Real)(i+1)*hu_));
180 }
181 p.clear();
182 p.resize(nu_,0.0);
183 apply_mass(p,r);
184 // Solve Tridiagonal System Using LAPACK's SPD Tridiagonal Solver
185 Teuchos::LAPACK<int,Real> lp;
186 int info;
187 int ldb = nu_;
188 int nhrs = 1;
189 lp.PTTRF(nu_,&d[0],&o[0],&info);
190 lp.PTTRS(nu_,nhrs,&d[0],&o[0],&p[0],ldb,&info);
191 }
192
193 void solve_state_sensitivity_equation(std::vector<Real> &w, const std::vector<Real> &v,
194 const std::vector<Real> &u, const std::vector<Real> &z) {
195 // Get Diagonal and Off-Diagonal Entries of PDE Jacobian
196 vector d(nu_,1.0);
197 vector o(nu_-1,1.0);
198 for ( uint i = 0; i < nu_; i++ ) {
199 d[i] = (z[i] + z[i+1])/hu_;
200 if ( i < nu_-1 ) {
201 o[i] *= -z[i+1]/hu_;
202 }
203 }
204 // Set right hand side
205 w.clear();
206 w.resize(nu_,0.0);
208 // Solve Tridiagonal System Using LAPACK's SPD Tridiagonal Solver
209 Teuchos::LAPACK<int,Real> lp;
210 int info;
211 int ldb = nu_;
212 int nhrs = 1;
213 lp.PTTRF(nu_,&d[0],&o[0],&info);
214 lp.PTTRS(nu_,nhrs,&d[0],&o[0],&w[0],ldb,&info);
215 }
216
217 void solve_adjoint_sensitivity_equation(std::vector<Real> &q, const std::vector<Real> &w,
218 const std::vector<Real> &v, const std::vector<Real> &p,
219 const std::vector<Real> &u, const std::vector<Real> &z) {
220 // Get Diagonal and Off-Diagonal Entries of PDE Jacobian
221 vector d(nu_,1.0);
222 vector o(nu_-1,1.0);
223 for ( uint i = 0; i < nu_; i++ ) {
224 d[i] = (z[i] + z[i+1])/hu_;
225 if ( i < nu_-1 ) {
226 o[i] *= -z[i+1]/hu_;
227 }
228 }
229 // Set right hand side
230 q.clear();
231 q.resize(nu_,0.0);
232 apply_mass(q,w);
233 std::vector<Real> res(nu_,0.0);
234 apply_linearized_control_operator(res,z,v,p,false);
235 for (uint i = 0; i < nu_; i++) {
236 q[i] -= res[i];
237 }
238 // Solve Tridiagonal System Using LAPACK's SPD Tridiagonal Solver
239 Teuchos::LAPACK<int,Real> lp;
240 int info;
241 int ldb = nu_;
242 int nhrs = 1;
243 lp.PTTRF(nu_,&d[0],&o[0],&info);
244 lp.PTTRS(nu_,nhrs,&d[0],&o[0],&q[0],ldb,&info);
245 }
246
247 void update(const ROL::Vector<Real> &z, bool flag, int iter) {
248
249
250
251 if ( flag && useCorrection_ ) {
252 Real tol = std::sqrt(ROL::ROL_EPSILON<Real>());
253 H_.shape(nz_,nz_);
254 ROL::Ptr<V> e = z.clone();
255 ROL::Ptr<V> h = z.clone();
256 for ( uint i = 0; i < nz_; i++ ) {
257 e = z.basis(i);
258 hessVec_true(*h,*e,z,tol);
259 for ( uint j = 0; j < nz_; j++ ) {
260 e = z.basis(j);
261 (H_)(j,i) = e->dot(*h);
262 }
263 }
264 std::vector<vector> eigenvals = ROL::computeEigenvalues<Real>(H_);
265 std::sort((eigenvals[0]).begin(), (eigenvals[0]).end());
266 Real inertia = (eigenvals[0])[0];
267 Real correction = 0.0;
268 if ( inertia <= 0.0 ) {
269 correction = (1.0+std::sqrt(ROL::ROL_EPSILON<Real>()))*std::abs(inertia);
270 if ( inertia == 0.0 ) {
271 uint cnt = 0;
272 while ( eigenvals[0][cnt] == 0.0 ) {
273 cnt++;
274 }
275 correction = std::sqrt(ROL::ROL_EPSILON<Real>())*eigenvals[0][cnt];
276 if ( cnt == nz_-1 ) {
277 correction = 1.0;
278 }
279 }
280 for ( uint i = 0; i < nz_; i++ ) {
281 (H_)(i,i) += correction;
282 }
283 }
284 }
285 }
286
287 /* OBJECTIVE FUNCTION DEFINITIONS */
288 Real value( const ROL::Vector<Real> &z, Real &tol ) {
289
290
291 ROL::Ptr<const vector> zp = getVector(z);
292
293 // SOLVE STATE EQUATION
294 vector u(nu_,0.0);
296
297 // EVALUATE OBJECTIVE
298 Real val = 0.0;
299 for (uint i=0; i<nz_;i++) {
300 val += hz_*alpha_*0.5*(*zp)[i]*(*zp)[i];
301 }
302 Real res = 0.0;
303 Real res1 = 0.0;
304 Real res2 = 0.0;
305 Real res3 = 0.0;
306 for (uint i=0; i<nu_; i++) {
307 if ( i == 0 ) {
308 res1 = u[i]-evaluate_target((Real)(i+1)*hu_);
309 res2 = u[i+1]-evaluate_target((Real)(i+2)*hu_);
310 res = hu_/6.0*(2.0*res1 + res2)*res1;
311 }
312 else if ( i == nu_-1 ) {
313 res1 = u[i-1]-evaluate_target((Real)i*hu_);
314 res2 = u[i]-evaluate_target((Real)(i+1)*hu_);
315 res = hu_/6.0*(res1 + 2.0*res2)*res2;
316 }
317 else {
318 res1 = u[i-1]-evaluate_target((Real)i*hu_);
319 res2 = u[i]-evaluate_target((Real)(i+1)*hu_);
320 res3 = u[i+1]-evaluate_target((Real)(i+2)*hu_);
321 res = hu_/6.0*(res1 + 4.0*res2 + res3)*res2;
322 }
323 val += 0.5*res;
324 }
325 return val;
326 }
327
328 void gradient( ROL::Vector<Real> &g, const ROL::Vector<Real> &z, Real &tol ) {
329
330
331
332 ROL::Ptr<const vector> zp = getVector(z);
333 ROL::Ptr<vector> gp = getVector(g);
334
335 // SOLVE STATE EQUATION
336 vector u(nu_,0.0);
338
339 // SOLVE ADJOINT EQUATION
340 vector p(nu_,0.0);
341 solve_adjoint_equation(p,u,*zp);
342
343 // Apply Transpose of Linearized Control Operator
345 // Build Gradient
346 for ( uint i = 0; i < nz_; i++ ) {
347 (*gp)[i] += hz_*alpha_*(*zp)[i];
348 }
349 }
350
351 void hessVec( ROL::Vector<Real> &hv, const ROL::Vector<Real> &v, const ROL::Vector<Real> &z, Real &tol ) {
352 if ( useCorrection_ ) {
353 hessVec_inertia(hv,v,z,tol);
354 }
355 else {
356 hessVec_true(hv,v,z,tol);
357 }
358 }
359
360 void activateInertia(void) {
361 useCorrection_ = true;
362 }
363
364 void deactivateInertia(void) {
365 useCorrection_ = false;
366 }
367
368 void hessVec_true( ROL::Vector<Real> &hv, const ROL::Vector<Real> &v, const ROL::Vector<Real> &z, Real &tol ) {
369
370
371
372 ROL::Ptr<const vector> vp = getVector(v);
373 ROL::Ptr<const vector> zp = getVector(z);
374 ROL::Ptr<vector> hvp = getVector(hv);
375
376 // SOLVE STATE EQUATION
377 vector u(nu_,0.0);
379
380 // SOLVE ADJOINT EQUATION
381 vector p(nu_,0.0);
382 solve_adjoint_equation(p,u,*zp);
383
384 // SOLVE STATE SENSITIVITY EQUATION
385 vector w(nu_,0.0);
387 // SOLVE ADJOINT SENSITIVITY EQUATION
388 vector q(nu_,0.0);
389 solve_adjoint_sensitivity_equation(q,w,*vp,p,u,*zp);
390
391 // Apply Transpose of Linearized Control Operator
393
394 // Apply Transpose of Linearized Control Operator
395 std::vector<Real> tmp(nz_,0.0);
397 for (uint i=0; i < nz_; i++) {
398 (*hvp)[i] -= tmp[i];
399 }
400 // Regularization hessVec
401 for (uint i=0; i < nz_; i++) {
402 (*hvp)[i] += hz_*alpha_*(*vp)[i];
403 }
404 }
405
406 void hessVec_inertia( ROL::Vector<Real> &hv, const ROL::Vector<Real> &v, const ROL::Vector<Real> &z, Real &tol ) {
407
408
409 using ROL::constPtrCast;
410
411 ROL::Ptr<vector> hvp = getVector(hv);
412
413
414 ROL::Ptr<vector> vp = ROL::constPtrCast<vector>(getVector(v));
415
416 Teuchos::SerialDenseVector<int, Real> hv_teuchos(Teuchos::View, &((*hvp)[0]), static_cast<int>(nz_));
417 Teuchos::SerialDenseVector<int, Real> v_teuchos(Teuchos::View, &(( *vp)[0]), static_cast<int>(nz_));
418 hv_teuchos.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, H_, v_teuchos, 0.0);
419 }
420
421};
422
423
424
425typedef double RealT;
426
427int main(int argc, char *argv[]) {
428
429 typedef std::vector<RealT> vector;
430 typedef ROL::Vector<RealT> V;
431 typedef ROL::StdVector<RealT> SV;
432
433 typedef typename vector::size_type luint;
434
435
436
437 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
438
439 // This little trick lets us print to std::cout only if a (dummy) command-line argument is provided.
440 int iprint = argc - 1;
441 ROL::Ptr<std::ostream> outStream;
442 ROL::nullstream bhs; // outputs nothing
443 if (iprint > 0)
444 outStream = ROL::makePtrFromRef(std::cout);
445 else
446 outStream = ROL::makePtrFromRef(bhs);
447
448 int errorFlag = 0;
449
450 // *** Example body.
451
452 try {
453
454 luint dim = 128; // Set problem dimension.
455 RealT alpha = 1.e-6;
457
458 // Iteration vector.
459 ROL::Ptr<vector> x_ptr = ROL::makePtr<vector>(dim, 0.0);
460 ROL::Ptr<vector> y_ptr = ROL::makePtr<vector>(dim, 0.0);
461
462 // Set initial guess.
463 for (luint i=0; i<dim; i++) {
464 (*x_ptr)[i] = (RealT)rand()/(RealT)RAND_MAX + 1.e2;
465 (*y_ptr)[i] = (RealT)rand()/(RealT)RAND_MAX + 1.e2;
466 }
467
468 SV x(x_ptr);
469 SV y(y_ptr);
470
471 obj.checkGradient(x,y,true);
472 obj.checkHessVec(x,y,true);
473
474 ROL::Ptr<vector> l_ptr = ROL::makePtr<vector>(dim,1.0);
475 ROL::Ptr<vector> u_ptr = ROL::makePtr<vector>(dim,10.0);
476
477 ROL::Ptr<V> lo = ROL::makePtr<SV>(l_ptr);
478 ROL::Ptr<V> up = ROL::makePtr<SV>(u_ptr);
479
480 ROL::Bounds<RealT> icon(lo,up);
481
482 ROL::ParameterList parlist;
483
484 // Krylov parameters.
485 parlist.sublist("General").sublist("Krylov").set("Absolute Tolerance",1.e-8);
486 parlist.sublist("General").sublist("Krylov").set("Relative Tolerance",1.e-4);
487 parlist.sublist("General").sublist("Krylov").set("Iteration Limit",static_cast<int>(dim));
488 // PDAS parameters.
489 parlist.sublist("Step").sublist("Primal Dual Active Set").set("Relative Step Tolerance",1.e-8);
490 parlist.sublist("Step").sublist("Primal Dual Active Set").set("Relative Gradient Tolerance",1.e-6);
491 parlist.sublist("Step").sublist("Primal Dual Active Set").set("Iteration Limit", 10);
492 parlist.sublist("Step").sublist("Primal Dual Active Set").set("Dual Scaling",(alpha>0.0)?alpha:1.e-4);
493 parlist.sublist("General").sublist("Secant").set("Use as Hessian",true);
494 // Status test parameters.
495 parlist.sublist("Status Test").set("Gradient Tolerance",1.e-12);
496 parlist.sublist("Status Test").set("Step Tolerance",1.e-14);
497 parlist.sublist("Status Test").set("Iteration Limit",100);
498
499 ROL::Ptr<ROL::Step<RealT>> step;
500 ROL::Ptr<ROL::StatusTest<RealT>> status;
501
502 // Define algorithm.
503 step = ROL::makePtr<ROL::PrimalDualActiveSetStep<RealT>>(parlist);
504 status = ROL::makePtr<ROL::StatusTest<RealT>>(parlist);
505 ROL::Algorithm<RealT> algo(step,status,false);
506
507 x.zero();
508 obj.deactivateInertia();
509 algo.run(x,obj,icon,true,*outStream);
510
511 // Output control to file.
512 std::ofstream file;
513 file.open("control_PDAS.txt");
514 for ( luint i = 0; i < dim; i++ ) {
515 file << (*x_ptr)[i] << "\n";
516 }
517 file.close();
518
519 // Projected Newtion.
520 // Define step.
521 parlist.sublist("General").sublist("Secant").set("Use as Hessian",false);
522 parlist.sublist("Step").sublist("Trust Region").set("Subproblem Solver", "Truncated CG");
523 parlist.sublist("Step").sublist("Trust Region").set("Initial Radius", 1e3);
524 parlist.sublist("Step").sublist("Trust Region").set("Maximum Radius", 1e8);
525 step = ROL::makePtr<ROL::TrustRegionStep<RealT>>(parlist);
526 status = ROL::makePtr<ROL::StatusTest<RealT>>(parlist);
527 ROL::Algorithm<RealT> algo_tr(step,status,false);
528 // Run Algorithm
529 y.zero();
530 obj.deactivateInertia();
531 algo_tr.run(y,obj,icon,true,*outStream);
532
533 std::ofstream file_tr;
534 file_tr.open("control_TR.txt");
535 for ( luint i = 0; i < dim; i++ ) {
536 file_tr << (*y_ptr)[i] << "\n";
537 }
538 file_tr.close();
539
540 std::vector<RealT> u;
541 obj.solve_state_equation(u,*y_ptr);
542 std::ofstream file_u;
543 file_u.open("state.txt");
544 for ( luint i = 0; i < (dim-1); i++ ) {
545 file_u << u[i] << "\n";
546 }
547 file_u.close();
548
549 ROL::Ptr<V> diff = x.clone();
550 diff->set(x);
551 diff->axpy(-1.0,y);
552 RealT error = diff->norm()/std::sqrt((RealT)dim-1.0);
553 std::cout << "\nError between PDAS solution and TR solution is " << error << "\n";
554 errorFlag = ((error > 1.e2*std::sqrt(ROL::ROL_EPSILON<RealT>())) ? 1 : 0);
555
556 }
557 catch (std::logic_error& err) {
558 *outStream << err.what() << "\n";
559 errorFlag = -1000;
560 }; // end try
561
562 if (errorFlag != 0)
563 std::cout << "End Result: TEST FAILED\n";
564 else
565 std::cout << "End Result: TEST PASSED\n";
566
567 return 0;
568
569}
570
Vector< Real > V
Contains definitions for helper functions in ROL.
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
Contains definitions of custom data types in ROL.
void solve_state_sensitivity_equation(std::vector< Real > &w, const std::vector< Real > &v, const std::vector< Real > &u, const std::vector< Real > &z)
Teuchos::SerialDenseMatrix< int, Real > H_
void solve_state_equation(std::vector< Real > &u, const std::vector< Real > &z)
void solve_adjoint_equation(std::vector< Real > &p, const std::vector< Real > &u, const std::vector< Real > &z)
void update(const ROL::Vector< Real > &z, bool flag, int iter)
Update objective function.
void hessVec(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
Apply Hessian approximation to vector.
void hessVec_inertia(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
ROL::Ptr< const vector > getVector(const V &x)
void apply_transposed_linearized_control_operator(std::vector< Real > &Bd, const std::vector< Real > &z, const std::vector< Real > &d, const std::vector< Real > &u, bool addBC=true)
void hessVec_true(ROL::Vector< Real > &hv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &z, Real &tol)
Real value(const ROL::Vector< Real > &z, Real &tol)
Compute value.
Objective_PoissonInversion(int nz=32, Real alpha=1.e-4)
void gradient(ROL::Vector< Real > &g, const ROL::Vector< Real > &z, Real &tol)
Compute gradient.
void apply_linearized_control_operator(std::vector< Real > &Bd, const std::vector< Real > &z, const std::vector< Real > &d, const std::vector< Real > &u, bool addBC=true)
void apply_mass(std::vector< Real > &Mz, const std::vector< Real > &z)
void solve_adjoint_sensitivity_equation(std::vector< Real > &q, const std::vector< Real > &w, const std::vector< Real > &v, const std::vector< Real > &p, const std::vector< Real > &u, const std::vector< Real > &z)
Provides an interface to run optimization algorithms.
Provides the elementwise interface to apply upper and lower bound constraints.
Provides the interface to evaluate objective functions.
virtual std::vector< std::vector< Real > > checkGradient(const Vector< Real > &x, const Vector< Real > &d, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference gradient check.
virtual std::vector< std::vector< Real > > checkHessVec(const Vector< Real > &x, const Vector< Real > &v, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference Hessian-applied-to-vector check.
Provides the ROL::Vector interface for scalar values, to be used, for example, with scalar constraint...
Defines the linear algebra or vector space interface.
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
int main(int argc, char *argv[])
constexpr auto dim