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 
37 template<class Real>
38 void 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 
65 template<class Real>
66 void 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 uint;
70  uint dim = A.size();
71 
72  for( uint i=0; i<dim; ++i ) {
73  for( uint j=0; j<dim; ++j ) {
74  outStream << std::setw(6) << A[j]->dot(*(I[i]));
75  }
76  outStream << std::endl;
77  }
78 }
79 
80 
81 template<class Real>
82 class IdentityOperator : public ROL::LinearOperator<Real> {
83 public:
84  void apply( ROL::Vector<Real> &Hv, const ROL::Vector<Real> &v, Real &tol ) const {
85  Hv.set(v);
86  }
87 }; // IdentityOperator
88 
89 
90 typedef double RealT;
91 
92 int 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 
190  IdentityOperator<RealT> identity;
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 
Provides the interface to evaluate objective functions.
PartitionedVector< Real > PV
typename PV< Real >::size_type size_type
Defines the linear algebra of vector space on a generic partitioned vector.
ROL::Ptr< Vector< Real > > CreatePartitionedVector(const ROL::Ptr< Vector< Real >> &a)
void RandomizeVector(Vector< Real > &x, const Real &lower=0.0, const Real &upper=1.0)
Fill a ROL::Vector with uniformly-distributed random numbers in the interval [lower,upper].
Symmetrized form of the KKT operator for the Type-EB problem with equality and bound multipliers...
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Vector< Real > V
void printVector(const ROL::Vector< Real > &x, std::ostream &outStream)
A simple wrapper which allows application of constraint Jacobians through the LinearOperator interfac...
Provides the interface to evaluate the Interior Pointy log barrier penalty function with upper and lo...
void printMatrix(const std::vector< ROL::Ptr< ROL::Vector< Real > > > &A, const std::vector< ROL::Ptr< ROL::Vector< Real > > > &I, std::ostream &outStream)
void apply(ROL::Vector< Real > &Hv, const ROL::Vector< Real > &v, Real &tol) const
Apply linear operator.
Provides definitions for Krylov solvers.
Definition: ROL_Krylov.hpp:24
Provides the interface to apply a linear operator.
Provides the interface to apply upper and lower bound constraints.
basic_nullstream< char, char_traits< char >> nullstream
Definition: ROL_Stream.hpp:38
int main(int argc, char *argv[])
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
constexpr auto dim