ROL
step/interiorpoint/test_03.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #define OPTIMIZATION_PROBLEM_REFACTOR
45 
46 #include "ROL_RandomVector.hpp"
47 #include "ROL_StdVector.hpp"
48 #include "ROL_NonlinearProgram.hpp"
53 #include "ROL_KrylovFactory.hpp"
54 
55 #include "HS_ProblemFactory.hpp"
56 
57 #include <iomanip>
58 
69 template<class Real>
70 void printVector( const ROL::Vector<Real> &x, std::ostream &outStream ) {
71 
72  try {
73  Teuchos::RCP<const std::vector<Real> > xp =
74  Teuchos::dyn_cast<const ROL::StdVector<Real> >(x).getVector();
75 
76  outStream << "Standard Vector" << std::endl;
77  for( size_t i=0; i<xp->size(); ++i ) {
78  outStream << (*xp)[i] << std::endl;
79  }
80  }
81  catch( const std::bad_cast& e ) {
82  outStream << "Partitioned Vector" << std::endl;
83 
85  typedef typename PV::size_type size_type;
86 
87  const PV &xpv = Teuchos::dyn_cast<const PV>(x);
88 
89  for( size_type i=0; i<xpv.numVectors(); ++i ) {
90  outStream << "--------------------" << std::endl;
91  printVector( *(xpv.get(i)), outStream );
92  }
93  outStream << "--------------------" << std::endl;
94  }
95 }
96 
97 template<class Real>
98 void printMatrix( const std::vector<Teuchos::RCP<ROL::Vector<Real> > > &A,
99  const std::vector<Teuchos::RCP<ROL::Vector<Real> > > &I,
100  std::ostream &outStream ) {
101  typedef typename std::vector<Real>::size_type uint;
102  uint dim = A.size();
103 
104  for( uint i=0; i<dim; ++i ) {
105  for( uint j=0; j<dim; ++j ) {
106  outStream << std::setw(6) << A[j]->dot(*(I[i]));
107  }
108  outStream << std::endl;
109  }
110 }
111 
112 
113 template<class Real>
114 class IdentityOperator : public ROL::LinearOperator<Real> {
115 public:
116  void apply( ROL::Vector<Real> &Hv, const ROL::Vector<Real> &v, Real &tol ) const {
117  Hv.set(v);
118  }
119 }; // IdentityOperator
120 
121 
122 typedef double RealT;
123 
124 int main(int argc, char *argv[]) {
125 
126 // typedef std::vector<RealT> vector;
127 
128  typedef Teuchos::ParameterList PL;
129 
130  typedef ROL::Vector<RealT> V;
132  typedef ROL::Objective<RealT> OBJ;
133  typedef ROL::EqualityConstraint<RealT> CON;
134  typedef ROL::BoundConstraint<RealT> BND;
136  typedef ROL::NonlinearProgram<RealT> NLP;
137  typedef ROL::LinearOperator<RealT> LOP;
139  typedef ROL::Krylov<RealT> KRYLOV;
140 
141 
142  typedef ROL::InteriorPointPenalty<RealT> PENALTY;
144 
145  using Teuchos::RCP; using Teuchos::rcp;
146 
147  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
148 
149  int iprint = argc - 1;
150  RCP<std::ostream> outStream;
151  Teuchos::oblackholestream bhs;
152  if( iprint > 0 )
153  outStream = rcp(&std::cout,false);
154  else
155  outStream = rcp(&bhs,false);
156 
157  int errorFlag = 0;
158 
159  try {
160 
161  RealT mu = 0.1;
162 
163  RealT tol = std::sqrt(ROL::ROL_EPSILON<RealT>());
164 
165  PL parlist;
166 
167  PL &iplist = parlist.sublist("Step").sublist("Primal Dual Interior Point");
168  PL &lblist = iplist.sublist("Barrier Objective");
169 
170  lblist.set("Use Linear Damping", true); // Not used in this test
171  lblist.set("Linear Damping Coefficient",1.e-4); // Not used in this test
172  lblist.set("Initial Barrier Parameter", mu);
173 
174  PL &krylist = parlist.sublist("General").sublist("Krylov");
175 
176  krylist.set("Absolute Tolerance", 1.e-6);
177  krylist.set("Relative Tolerance", 1.e-6);
178  krylist.set("Iteration Limit", 50);
179 
180  // Create a Conjugate Gradients solver
181  krylist.set("Type","Conjugate Gradients");
182  RCP<KRYLOV> cg = ROL::KrylovFactory<RealT>(parlist);
183  HS::ProblemFactory<RealT> problemFactory;
184 
185  // Choose an example problem with inequality constraints and
186  // a mixture of finite and infinite bounds
187  RCP<NLP> nlp = problemFactory.getProblem(16);
188  RCP<OPT> opt = nlp->getOptimizationProblem();
189 
190  RCP<V> x = opt->getSolutionVector();
191  RCP<V> l = opt->getMultiplierVector();
192  RCP<V> zl = x->clone();
193  RCP<V> zu = x->clone();
194 
195  RCP<V> scratch = x->clone();
196 
197  RCP<PV> x_pv = Teuchos::rcp_dynamic_cast<PV>(x);
198 
199  RCP<V> sol = CreatePartitionedVector(x,l,zl,zu);
200 
201  std::vector<RCP<V> > I;
202  std::vector<RCP<V> > J;
203 
204  for( int k=0; k<sol->dimension(); ++k ) {
205  I.push_back(sol->basis(k));
206  J.push_back(sol->clone());
207  }
208 
209  RCP<V> u = sol->clone();
210  RCP<V> v = sol->clone();
211 
212  RCP<V> rhs = sol->clone();
213  RCP<V> symrhs = sol->clone();
214 
215  RCP<V> gmres_sol = sol->clone(); gmres_sol->set(*sol);
216  RCP<V> cg_sol = sol->clone(); cg_sol->set(*sol);
217 
218  IdentityOperator<RealT> identity;
219 
220  RandomizeVector(*u,-1.0,1.0);
221  RandomizeVector(*v,-1.0,1.0);
222 
223  RCP<OBJ> obj = opt->getObjective();
224  RCP<CON> con = opt->getEqualityConstraint();
225  RCP<BND> bnd = opt->getBoundConstraint();
226 
227  PENALTY penalty(obj,bnd,parlist);
228 
229  RCP<const V> maskL = penalty.getLowerMask();
230  RCP<const V> maskU = penalty.getUpperMask();
231 
232  zl->set(*maskL);
233  zu->set(*maskU);
234 
235 
236  /********************************************************************************/
237  /* Nonsymmetric representation test */
238  /********************************************************************************/
239 
240 
241  int gmres_iter = 0;
242  int gmres_flag = 0;
243 
244  // Form the residual's Jacobian operator
245  RCP<CON> res = rcp( new RESIDUAL(obj,con,bnd,*sol,maskL,maskU,scratch,mu,false) );
246  RCP<LOP> lop = rcp( new LOPEC( sol, res ) );
247 
248  // Evaluate the right-hand-side
249  res->value(*rhs,*sol,tol);
250 
251  // Create a GMRES solver
252  krylist.set("Type","GMRES");
253  RCP<KRYLOV> gmres = ROL::KrylovFactory<RealT>(parlist);
254 
255 
256  for( int k=0; k<sol->dimension(); ++k ) {
257  res->applyJacobian(*(J[k]),*(I[k]),*sol,tol);
258  }
259 
260  *outStream << "Nonsymmetric Jacobian" << std::endl;
261  printMatrix(J,I,*outStream);
262 
263  // Solve the system
264  gmres->run( *gmres_sol, *lop, *rhs, identity, gmres_iter, gmres_flag );
265 
266  errorFlag += gmres_flag;
267 
268 
269  *outStream << "GMRES terminated after " << gmres_iter << " iterations "
270  << "with exit flag " << gmres_flag << std::endl;
271 
272 
273 
274  /********************************************************************************/
275  /* Symmetric representation test */
276  /********************************************************************************/
277 
278  int cg_iter = 0;
279  int cg_flag = 0;
280 
281  RCP<V> jv = v->clone();
282  RCP<V> ju = u->clone();
283 
284  iplist.set("Symmetrize Primal Dual System",true);
285  RCP<CON> symres = rcp( new RESIDUAL(obj,con,bnd,*sol,maskL,maskU,scratch,mu,true) );
286  RCP<LOP> symlop = rcp( new LOPEC( sol, res ) );
287  symres->value(*symrhs,*sol,tol);
288 
289  symres->applyJacobian(*jv,*v,*sol,tol);
290  symres->applyJacobian(*ju,*u,*sol,tol);
291  *outStream << "Symmetry check |u.dot(jv)-v.dot(ju)| = "
292  << std::abs(u->dot(*jv)-v->dot(*ju)) << std::endl;
293 
294  cg->run( *cg_sol, *symlop, *symrhs, identity, cg_iter, cg_flag );
295 
296  *outStream << "CG terminated after " << cg_iter << " iterations "
297  << "with exit flag " << cg_flag << std::endl;
298 
299  *outStream << "Check that GMRES solution also is a solution to the symmetrized system"
300  << std::endl;
301 
302  symres->applyJacobian(*ju,*gmres_sol,*sol,tol);
303  ju->axpy(-1.0,*symrhs);
304  RealT mismatch = ju->norm();
305  if(mismatch>tol) {
306  errorFlag++;
307  }
308  *outStream << "||J_sym*sol_nonsym-rhs_sym|| = " << mismatch << std::endl;
309 
310  }
311  catch (std::logic_error err) {
312  *outStream << err.what() << std::endl;
313  errorFlag = -1000;
314  }
315 
316  if (errorFlag != 0)
317  std::cout << "End Result: TEST FAILED" << std::endl;
318  else
319  std::cout << "End Result: TEST PASSED" << std::endl;
320 
321  return 0;
322 }
323 
Provides the interface to evaluate objective functions.
PartitionedVector< Real > PV
void printMatrix(const std::vector< Teuchos::RCP< ROL::Vector< Real > > > &A, const std::vector< Teuchos::RCP< ROL::Vector< Real > > > &I, std::ostream &outStream)
Defines the linear algebra of vector space on a generic partitioned vector.
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...
Teuchos::RCP< Vector< Real > > CreatePartitionedVector(const Teuchos::RCP< Vector< Real > > &a)
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:76
void apply(ROL::Vector< Real > &Hv, const ROL::Vector< Real > &v, Real &tol) const
Apply linear operator.
Vector< Real > V
Provides the interface to evaluate the Interior Pointy log barrier penalty function with upper and lo...
Defines the equality constraint operator interface.
void printVector(const ROL::Vector< Real > &x, std::ostream &outStream)
Provides definitions for Krylov solvers.
Definition: ROL_Krylov.hpp:57
Provides the interface to apply a linear operator.
Provides the interface to apply upper and lower bound constraints.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:198
int main(int argc, char *argv[])
A simple wrapper which allows application of constraint Jacobians through the LinearOperator interfac...