ROL
step/interiorpoint/test_03.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
10#define OPTIMIZATION_PROBLEM_REFACTOR
11
12#include "Teuchos_GlobalMPISession.hpp"
13
14#include "ROL_RandomVector.hpp"
15#include "ROL_StdVector.hpp"
16#include "ROL_NonlinearProgram.hpp"
21#include "ROL_KrylovFactory.hpp"
22
23#include "HS_ProblemFactory.hpp"
24
25#include <iomanip>
26
37template<class Real>
38void printVector( const ROL::Vector<Real> &x, std::ostream &outStream ) {
39
40 try {
41 ROL::Ptr<const std::vector<Real> > xp =
42 dynamic_cast<const ROL::StdVector<Real>&>(x).getVector();
43
44 outStream << "Standard Vector" << std::endl;
45 for( size_t i=0; i<xp->size(); ++i ) {
46 outStream << (*xp)[i] << std::endl;
47 }
48 }
49 catch( const std::bad_cast& e ) {
50 outStream << "Partitioned Vector" << std::endl;
51
53 typedef typename PV::size_type size_type;
54
55 const PV &xpv = dynamic_cast<const PV&>(x);
56
57 for( size_type i=0; i<xpv.numVectors(); ++i ) {
58 outStream << "--------------------" << std::endl;
59 printVector( *(xpv.get(i)), outStream );
60 }
61 outStream << "--------------------" << std::endl;
62 }
63}
64
65template<class Real>
66void printMatrix( const std::vector<ROL::Ptr<ROL::Vector<Real> > > &A,
67 const std::vector<ROL::Ptr<ROL::Vector<Real> > > &I,
68 std::ostream &outStream ) {
69 typedef typename std::vector<Real>::size_type luint;
70 luint dim = A.size();
71
72 for( luint i=0; i<dim; ++i ) {
73 for( luint j=0; j<dim; ++j ) {
74 outStream << std::setw(6) << A[j]->dot(*(I[i]));
75 }
76 outStream << std::endl;
77 }
78}
79
80
81template<class Real>
83public:
84 void apply( ROL::Vector<Real> &Hv, const ROL::Vector<Real> &v, Real &tol ) const {
85 Hv.set(v);
86 }
87}; // IdentityOperator
88
89
90typedef double RealT;
91
92int main(int argc, char *argv[]) {
93
94// typedef std::vector<RealT> vector;
95
96 typedef ROL::ParameterList PL;
97
98 typedef ROL::Vector<RealT> V;
100 typedef ROL::Objective<RealT> OBJ;
101 typedef ROL::Constraint<RealT> CON;
102 typedef ROL::BoundConstraint<RealT> BND;
104 typedef ROL::NonlinearProgram<RealT> NLP;
105 typedef ROL::LinearOperator<RealT> LOP;
107 typedef ROL::Krylov<RealT> KRYLOV;
108
109
110 typedef ROL::InteriorPointPenalty<RealT> PENALTY;
112
113
114
115 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
116
117 int iprint = argc - 1;
118 ROL::Ptr<std::ostream> outStream;
119 ROL::nullstream bhs;
120 if( iprint > 0 )
121 outStream = ROL::makePtrFromRef(std::cout);
122 else
123 outStream = ROL::makePtrFromRef(bhs);
124
125 int errorFlag = 0;
126
127 try {
128
129 RealT mu = 0.1;
130
131 RealT tol = std::sqrt(ROL::ROL_EPSILON<RealT>());
132
133 PL parlist;
134
135 PL &iplist = parlist.sublist("Step").sublist("Primal Dual Interior Point");
136 PL &lblist = iplist.sublist("Barrier Objective");
137
138 lblist.set("Use Linear Damping", true); // Not used in this test
139 lblist.set("Linear Damping Coefficient",1.e-4); // Not used in this test
140 lblist.set("Initial Barrier Parameter", mu);
141
142 PL &krylist = parlist.sublist("General").sublist("Krylov");
143
144 krylist.set("Absolute Tolerance", 1.e-6);
145 krylist.set("Relative Tolerance", 1.e-6);
146 krylist.set("Iteration Limit", 50);
147
148 // Create a Conjugate Gradients solver
149 krylist.set("Type","Conjugate Gradients");
150 ROL::Ptr<KRYLOV> cg = ROL::KrylovFactory<RealT>(parlist);
151 HS::ProblemFactory<RealT> problemFactory;
152
153 // Choose an example problem with inequality constraints and
154 // a mixture of finite and infinite bounds
155 ROL::Ptr<NLP> nlp = problemFactory.getProblem(16);
156 ROL::Ptr<OPT> opt = nlp->getOptimizationProblem();
157
158 ROL::Ptr<V> x = opt->getSolutionVector();
159 ROL::Ptr<V> l = opt->getMultiplierVector();
160 ROL::Ptr<V> zl = x->clone(); zl->zero();
161 ROL::Ptr<V> zu = x->clone(); zu->zero();
162
163 ROL::Ptr<V> scratch = x->clone();
164
165 ROL::Ptr<PV> x_pv = ROL::dynamicPtrCast<PV>(x);
166 // New slack variable initialization does not guarantee strict feasibility.
167 // This ensures that the slack variables are the same as the previous
168 // implementation.
169 (*ROL::dynamicPtrCast<ROL::StdVector<RealT> >(x_pv->get(1))->getVector())[0] = 1.0;
170
171 ROL::Ptr<V> sol = CreatePartitionedVector(x,l,zl,zu);
172
173 std::vector< ROL::Ptr<V> > I;
174 std::vector< ROL::Ptr<V> > J;
175
176 for( int k=0; k<sol->dimension(); ++k ) {
177 I.push_back(sol->basis(k));
178 J.push_back(sol->clone());
179 }
180
181 ROL::Ptr<V> u = sol->clone();
182 ROL::Ptr<V> v = sol->clone();
183
184 ROL::Ptr<V> rhs = sol->clone();
185 ROL::Ptr<V> symrhs = sol->clone();
186
187 ROL::Ptr<V> gmres_sol = sol->clone(); gmres_sol->set(*sol);
188 ROL::Ptr<V> cg_sol = sol->clone(); cg_sol->set(*sol);
189
191
192 RandomizeVector(*u,-1.0,1.0);
193 RandomizeVector(*v,-1.0,1.0);
194
195 ROL::Ptr<OBJ> obj = opt->getObjective();
196 ROL::Ptr<CON> con = opt->getConstraint();
197 ROL::Ptr<BND> bnd = opt->getBoundConstraint();
198
199 PENALTY penalty(obj,bnd,parlist);
200
201 ROL::Ptr<const V> maskL = penalty.getLowerMask();
202 ROL::Ptr<const V> maskU = penalty.getUpperMask();
203
204 zl->set(*maskL);
205 zu->set(*maskU);
206
207 /********************************************************************************/
208 /* Nonsymmetric representation test */
209 /********************************************************************************/
210
211 int gmres_iter = 0;
212 int gmres_flag = 0;
213
214 // Form the residual's Jacobian operator
215 ROL::Ptr<CON> res = ROL::makePtr<RESIDUAL>(obj,con,bnd,*sol,maskL,maskU,scratch,mu,false);
216 ROL::Ptr<LOP> lop = ROL::makePtr<LOPEC>( sol, res );
217
218 // Evaluate the right-hand-side
219 res->value(*rhs,*sol,tol);
220
221 // Create a GMRES solver
222 krylist.set("Type","GMRES");
223 ROL::Ptr<KRYLOV> gmres = ROL::KrylovFactory<RealT>(parlist);
224
225 for( int k=0; k<sol->dimension(); ++k ) {
226 res->applyJacobian(*(J[k]),*(I[k]),*sol,tol);
227 }
228
229 *outStream << "Nonsymmetric Jacobian" << std::endl;
230 printMatrix(J,I,*outStream);
231
232 // Solve the system
233 gmres->run( *gmres_sol, *lop, *rhs, identity, gmres_iter, gmres_flag );
234
235 errorFlag += gmres_flag;
236
237 *outStream << "GMRES terminated after " << gmres_iter << " iterations "
238 << "with exit flag " << gmres_flag << std::endl;
239
240
241 /********************************************************************************/
242 /* Symmetric representation test */
243 /********************************************************************************/
244
245 int cg_iter = 0;
246 int cg_flag = 0;
247
248 ROL::Ptr<V> jv = v->clone();
249 ROL::Ptr<V> ju = u->clone();
250
251 iplist.set("Symmetrize Primal Dual System",true);
252 ROL::Ptr<CON> symres = ROL::makePtr<RESIDUAL>(obj,con,bnd,*sol,maskL,maskU,scratch,mu,true);
253 ROL::Ptr<LOP> symlop = ROL::makePtr<LOPEC>( sol, res );
254 symres->value(*symrhs,*sol,tol);
255
256 symres->applyJacobian(*jv,*v,*sol,tol);
257 symres->applyJacobian(*ju,*u,*sol,tol);
258 *outStream << "Symmetry check |u.dot(jv)-v.dot(ju)| = "
259 << std::abs(u->dot(*jv)-v->dot(*ju)) << std::endl;
260
261 cg->run( *cg_sol, *symlop, *symrhs, identity, cg_iter, cg_flag );
262
263 *outStream << "CG terminated after " << cg_iter << " iterations "
264 << "with exit flag " << cg_flag << std::endl;
265
266 *outStream << "Check that GMRES solution also is a solution to the symmetrized system"
267 << std::endl;
268
269 symres->applyJacobian(*ju,*gmres_sol,*sol,tol);
270 ju->axpy(-1.0,*symrhs);
271 RealT mismatch = ju->norm();
272 if(mismatch>tol) {
273 errorFlag++;
274 }
275 *outStream << "||J_sym*sol_nonsym-rhs_sym|| = " << mismatch << std::endl;
276
277 }
278 catch (std::logic_error& err) {
279 *outStream << err.what() << std::endl;
280 errorFlag = -1000;
281 }
282
283 if (errorFlag != 0)
284 std::cout << "End Result: TEST FAILED" << std::endl;
285 else
286 std::cout << "End Result: TEST PASSED" << std::endl;
287
288 return 0;
289}
290
Vector< Real > V
PartitionedVector< Real > PV
typename PV< Real >::size_type size_type
void apply(ROL::Vector< Real > &Hv, const ROL::Vector< Real > &v, Real &tol) const
Apply linear operator.
Provides the interface to apply upper and lower bound constraints.
Defines the general constraint operator interface.
Provides the interface to evaluate the Interior Pointy log barrier penalty function with upper and lo...
Provides definitions for Krylov solvers.
A simple wrapper which allows application of constraint Jacobians through the LinearOperator interfac...
Provides the interface to apply a linear operator.
Provides the interface to evaluate objective functions.
Defines the linear algebra of vector space on a generic partitioned vector.
Symmetrized form of the KKT operator for the Type-EB problem with equality and bound multipliers.
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 void set(const Vector &x)
Set where .
int main(int argc, char *argv[])
void printVector(const ROL::Vector< Real > &x, std::ostream &outStream)
void printMatrix(const std::vector< ROL::Ptr< ROL::Vector< Real > > > &A, const std::vector< ROL::Ptr< ROL::Vector< Real > > > &I, std::ostream &outStream)
constexpr auto dim