ROL
function/constraint/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 
14 #include <cmath>
15 
16 #include "ROL_RandomVector.hpp"
17 #include "ROL_StdVector.hpp"
19 #include "ROL_StdConstraint.hpp"
20 
21 #include "ROL_Stream.hpp"
22 #include "Teuchos_GlobalMPISession.hpp"
23 
24 using RealT = double;
25 using VectorT = std::vector<RealT>;
26 
27 
28 /* constraint function with (range) = 1 + dim(domain)
29  */
30 class InnerConstraint : public ROL::StdConstraint<RealT> {
31 public:
32  InnerConstraint( int n ) : y_(n+1), sin_(n+1), cos_(n+1), n_(n), m_(n+1) {}
33 
34  void update( const VectorT& x,
35  ROL::UpdateType type,
36  int iter ) override {
37  for( int k=0; k<m_; ++k ) {
38  y_[k] = 0;
39  if( k<n_ ) y_[k] += x[k]*x[k];
40  if( k>0 ) y_[k] -= 2*x[k-1];
41  sin_[k] = std::sin(y_[k]);
42  cos_[k] = std::cos(y_[k]);
43  }
44  }
45 
46  void value( VectorT& c,
47  const VectorT& x,
48  RealT& tol ) override {
49  for( int k=0; k<m_; ++k ) c[k] = std::cos(y_[k]);
50  }
51 
52  void applyJacobian( VectorT& jv,
53  const VectorT& v,
54  const VectorT& x,
55  RealT& tol ) override {
56  for( int k=0; k<m_; ++k ) {
57  jv[k] = 0;
58  if( k<n_ ) jv[k] -= 2*v[k]*x[k]*sin_[k];
59  if( k>0 ) jv[k] += 2*v[k-1]*sin_[k];
60  }
61  }
62 
64  const VectorT& l,
65  const VectorT& x,
66  RealT& tol ) override {
67  for( int i=0; i<n_; ++i ) {
68  ajl[i] = 2*(l[i+1]*sin_[i+1] - l[i]*x[i]*sin_[i]);
69  }
70  }
71 
73  const VectorT& l,
74  const VectorT& v,
75  const VectorT& x,
76  RealT& tol ) override {
77  ahlv[0] = -4*cos_[0]*l[0]*v[0]*x[0]*x[0] - 4*cos_[1]*l[1]*v[0] + 4*cos_[1]*l[1]*v[1]*x[1] - 2*l[0]*sin_[0]*v[0];
78  for(int i=0; i<n_-1; ++i) {
79  ahlv[i] = 4*cos_[i]*l[i]*v[i-1]*x[i] - 4*cos_[i]*l[i]*v[i]*x[i]*x[i] - 4*cos_[i+1]*l[i+1]*v[i] + 4*cos_[i+1]*l[i+1]*v[i+1]*x[i+1] - 2*l[i]*sin_[i]*v[i];
80  }
81  ahlv[n_-1] = 4*cos_[n_-1]*l[n_-1]*v[n_-2]*x[n_-1] - 4*cos_[n_-1]*l[n_-1]*v[n_-1]*x[n_-1]*x[n_-1] - 4*cos_[n_]*l[n_]*v[n_-1] - 2*l[n_-1]*sin_[n_-1]*v[n_-1];
82  }
83 private:
85  int n_, m_;
86 
87 };
88 
89 /* constraint function with dim(range) = dim(domain) - 2
90  */
91 class OuterConstraint : public ROL::StdConstraint<RealT> {
92 public:
93  OuterConstraint( int n ): d_(n-2), dv_(n-2), n_(n), m_(n-2) {}
94 
95  void update( const VectorT& x,
96  ROL::UpdateType type,
97  int iter ) override {
98  for(int i=0; i<m_; ++i)
99  d_[i] = -x[i] + 2*x[i+1] - x[i+2];
100  }
101 
102  void value( VectorT& c,
103  const VectorT& x,
104  RealT& tol ) override {
105  for(int i=0; i<m_; ++i)
106  c[i] = d_[i]*d_[i];
107  }
108 
109  void applyJacobian( VectorT& jv,
110  const VectorT& v,
111  const VectorT& x,
112  RealT& tol ) override {
113  for(int i=0; i<m_; ++i)
114  jv[i] = 2*d_[i]*(-v[i]+2*v[i+1]-v[i+2]);
115  }
116 
118  const VectorT& l,
119  const VectorT& x,
120  RealT& tol ) override {
121  for(int i=0; i<n_; ++i) {
122  ajl[i] = 0;
123  for( int j=0; j<m_; ++j ) {
124  if( j == i-1 ) ajl[i] += 4*d_[j]*l[j];
125  else if( std::abs(i-j-1) == 1) ajl[i] -= 2*d_[j]*l[j];
126  }
127  }
128  }
129 
131  const VectorT& l,
132  const VectorT& v,
133  const VectorT& x,
134  RealT& tol ) override {
135  for(int i=0; i<m_; ++i)
136  dv_[i] = -v[i] + 2*v[i+1] - v[i+2];
137  for(int i=0; i<n_; ++i) {
138  ahlv[i] = 0;
139  for( int j=0; j<m_; ++j ) {
140  if( j == i-1 ) ahlv[i] += 4*dv_[j]*l[j];
141  else if( std::abs(i-j-1) == 1) ahlv[i] -= 2*dv_[j]*l[j];
142  }
143  }
144  }
145 
146 private:
148  int n_, m_;
149 
150 };
151 
152 
153 
154 
155 int main(int argc, char *argv[]) {
156 
157  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
158 
159  // This little trick lets us print to std::cout only if a (dummy) command-line argument is provided.
160  int iprint = argc - 1;
161  ROL::Ptr<std::ostream> outStream;
162  ROL::nullstream bhs; // outputs nothing
163  if (iprint > 0)
164  outStream = ROL::makePtrFromRef(std::cout);
165  else
166  outStream = ROL::makePtrFromRef(bhs);
167 
168  // Save the format state of the original std::cout.
169  ROL::nullstream oldFormatState;
170  oldFormatState.copyfmt(std::cout);
171 
172 // RealT errtol = std::sqrt(ROL::ROL_THRESHOLD<RealT>());
173 
174  int errorFlag = 0;
175 
176  // *** Test body.
177 
178  try {
179 
180  int x_dim = 7; // Inner constraint domain space dimension
181  int ci_dim = x_dim + 1; // Inner constraint range space dimension (Outer constraint domain space dimension)
182  int co_dim = x_dim - 1; // Outer constraint range space dimension
183 
184  auto inner_con = ROL::makePtr<InnerConstraint>(x_dim);
185  auto outer_con = ROL::makePtr<OuterConstraint>(ci_dim);
186 
187  auto x = ROL::makePtr<ROL::StdVector<RealT>>(x_dim);
188  auto v = ROL::makePtr<ROL::StdVector<RealT>>(x_dim);
189  auto y = ROL::makePtr<ROL::StdVector<RealT>>(ci_dim);
190  auto w = ROL::makePtr<ROL::StdVector<RealT>>(ci_dim);
191  auto ci = ROL::makePtr<ROL::StdVector<RealT>>(ci_dim);
192  auto co = ROL::makePtr<ROL::StdVector<RealT>>(co_dim);
193 
194  auto cr_con = ROL::makePtr<ROL::ChainRuleConstraint<RealT>>(outer_con,inner_con,*x,*ci);
195 
202 
203  *outStream << "\n\nInner Constraint Check:\n\n";
204 
205  inner_con->checkApplyJacobian(*x,*v,*ci,true,*outStream,7,4);
206  inner_con->checkAdjointConsistencyJacobian(*ci,*v,*x,true,*outStream);
207  inner_con->checkApplyAdjointHessian(*x,*ci,*v,*x,true,*outStream,7,4);
208 
209  *outStream << "\n\nOuter Constraint Check:\n\n";
210  outer_con->checkApplyJacobian(*y,*w,*co,true,*outStream,7,4);
211  outer_con->checkAdjointConsistencyJacobian(*co,*w,*y,true,*outStream);
212  outer_con->checkApplyAdjointHessian(*y,*co,*w,*y,true,*outStream,7,4);
213 
214  *outStream << "\n\nChain Rule Constraint Check:\n\n";
215  cr_con->checkApplyJacobian(*x,*v,*co,true,*outStream,7,4);
216  cr_con->checkAdjointConsistencyJacobian(*co,*v,*x,true,*outStream);
217  cr_con->checkApplyAdjointHessian(*x,*co,*v,*x,true,*outStream,7,4);
218 
219  }
220  catch (std::logic_error& err) {
221  *outStream << err.what() << "\n";
222  errorFlag = -1000;
223  }; // end try
224 
225  if (errorFlag != 0)
226  std::cout << "End Result: TEST FAILED\n";
227  else
228  std::cout << "End Result: TEST PASSED\n";
229 
230  return 0;
231 
232 
233 }
234 
void applyAdjointJacobian(VectorT &ajl, const VectorT &l, const VectorT &x, RealT &tol) override
void applyJacobian(VectorT &jv, const VectorT &v, const VectorT &x, RealT &tol) override
void applyAdjointHessian(VectorT &ahlv, const VectorT &l, const VectorT &v, const VectorT &x, RealT &tol) override
void update(const VectorT &x, ROL::UpdateType type, int iter) override
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].
Defines the equality constraint operator interface for StdVectors.
Defines a no-output stream class ROL::NullStream and a function makeStreamPtr which either wraps a re...
void value(VectorT &c, const VectorT &x, RealT &tol) override
basic_nullstream< char, std::char_traits< char >> nullstream
Definition: ROL_Stream.hpp:36
std::vector< RealT > VectorT
void value(VectorT &c, const VectorT &x, RealT &tol) override
void update(const VectorT &x, ROL::UpdateType type, int iter) override
void applyJacobian(VectorT &jv, const VectorT &v, const VectorT &x, RealT &tol) override
void applyAdjointHessian(VectorT &ahlv, const VectorT &l, const VectorT &v, const VectorT &x, RealT &tol) override
void applyAdjointJacobian(VectorT &ajl, const VectorT &l, const VectorT &x, RealT &tol) override
int main(int argc, char *argv[])