ROL
example_01d.hpp
Go to the documentation of this file.
1 
2 #include "Sacado.hpp"
3 #include "ROL_StdVector.hpp"
4 #include "ROL_Objective.hpp"
5 
6 using namespace ROL;
7 
8 // This is a tweak of example_01c which uses a couple of C++11 features
9 // To build this example, you must add the cmake flag -D ENABLE_CPP11:BOOL=ON
10 
11 
12 template<class Real>
13 Teuchos::RCP<const std::vector<Real>>
15  return (Teuchos::dyn_cast<StdVector<Real>>
16  (const_cast<Vector<Real>&>(x))).getVector();
17 }
18 
19 
20 template<class Real>
21 Teuchos::RCP<std::vector<Real>>
23  return Teuchos::rcp_const_cast<std::vector<Real>>
24  ((Teuchos::dyn_cast<StdVector<Real>> (x)).getVector());
25 }
26 
27 
28 
29 template<class Real>
30 class Zakharov {
31 
32  public:
33  Real value(const Vector<Real> &x, Real &tol) {
34 
35  auto xp = access_elements(x);
36 
37  int n = xp->size();
38 
39  Real xdotx = 0;
40 
41  Real kdotx = 0;
42  Real J = 0;
43 
44  // Compute dot products
45  for(int i=0; i<n; ++i) {
46  xdotx += pow((*xp)[i],2); // (k,x)
47  kdotx += double(i+1)*(*xp)[i]; // (x,x)
48  }
49 
50  // Sum terms in objective function
51  J = xdotx + pow(kdotx,2)/4.0 + pow(kdotx,4)/16.0;
52 
53  return J;
54  }
55 };
56 
57 
58 
59 template<class Real>
60 class ObjectiveEnabler : public Objective<Real> {
62  public:
63  ObjectiveEnabler(const Zakharov<Real>& zak) : zakharov(zak) {}
64  Real value(const Vector<Real> &x, Real &tol) { return zakharov.value(x,tol); }
65 };
66 
67 
68 template<class Real>
69 class GradientEnabler : public Objective<Real> {
70 
71  typedef Sacado::Fad::DFad<Real> FadType;
73 
74  Teuchos::RCP<Objective<FadType>> obj_;
75 
76  public:
77  GradientEnabler(Teuchos::RCP<Objective<FadType>> obj) : obj_(obj) {}
78 
79  Real value(const Vector<Real> &x, Real &tol) {
80 
81  auto xp = access_elements(x);
82 
83  int n = xp->size();
84 
85  auto x_fad_rcp = Teuchos::rcp(new std::vector<FadType>);
86 
87  x_fad_rcp->reserve(n);
88 
89  for(int i=0; i<n; ++i) {
90  x_fad_rcp->push_back((*xp)[i]);
91  }
92 
93  FadVector x_fad(x_fad_rcp);
94 
95  FadType tol_fad = tol;
96  FadType J_fad = obj_->value(x_fad,tol_fad);
97 
98  return J_fad.val();
99  }
100 
101  void gradient(Vector<Real> &g, const Vector<Real> &x, Real &tol) {
102 
103  auto xp = access_elements(x);
104  auto gp = access_elements(g);
105  int n = xp->size();
106 
107  auto x_fad_rcp = Teuchos::rcp( new std::vector<FadType> );
108 
109  x_fad_rcp->reserve(n);
110 
111  for(int i=0; i<n; ++i) {
112  x_fad_rcp->push_back(FadType(n,i,(*xp)[i]));
113  }
114 
115  FadVector x_fad(x_fad_rcp);
116 
117  FadType tol_fad = tol;
118  FadType J_fad = obj_->value(x_fad,tol_fad);
119 
120  for(int i=0; i<n; ++i) {
121  (*gp)[i] = J_fad.dx(i);
122  }
123  }
124 };
125 
126 
127 
128 
129 template<class Real>
130 class HessianEnabler : public Objective<Real> {
131 
132  typedef Sacado::Fad::SFad<Real,1> FadType;
134 
135  Teuchos::RCP<Objective<FadType>> obj_;
136 
137  public:
138  HessianEnabler(Teuchos::RCP<Objective<FadType>> obj) : obj_(obj) {}
139 
140  Real value(const Vector<Real> &x, Real &tol) {
141 
142  auto xp = access_elements(x);
143 
144  int n = xp->size();
145 
146  auto x_fad_rcp = Teuchos::rcp(new std::vector<FadType>);
147 
148  x_fad_rcp->reserve(n);
149  for(int i=0; i<n; ++i) {
150  x_fad_rcp->push_back((*xp)[i]);
151  }
152 
153  FadVector x_fad(x_fad_rcp);
154 
155  FadType tol_fad = tol;
156  FadType J_fad = obj_->value(x_fad,tol_fad);
157 
158  return J_fad.val();
159  }
160 
161  void gradient(Vector<Real> &g, const Vector<Real> &x, Real &tol) {
162 
163  auto xp = access_elements(x);
164  auto gp = access_elements(g);
165 
166  int n = xp->size();
167 
168  auto x_fad_rcp = Teuchos::rcp(new std::vector<FadType>);
169  auto g_fad_rcp = Teuchos::rcp(new std::vector<FadType>);
170 
171  x_fad_rcp->reserve(n);
172  g_fad_rcp->reserve(n);
173 
174  for(int i=0; i<n; ++i) {
175  x_fad_rcp->push_back((*xp)[i]);
176  g_fad_rcp->push_back((*xp)[i]);
177  }
178 
179  FadVector x_fad(x_fad_rcp);
180  FadVector g_fad(g_fad_rcp);
181  FadType tol_fad = tol;
182 
183  obj_->gradient(g_fad,x_fad,tol_fad);
184 
185  for(int i=0; i<n; ++i) {
186  (*gp)[i] = (*g_fad_rcp)[i].val();
187  }
188  }
189 
190  void hessVec(Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol) {
191  auto xp = access_elements(x);
192  auto vp = access_elements(v);
193  auto hvp = access_elements(hv);
194  int n = xp->size();
195 
196  // Create a vector of independent variables
197  auto x_fad_rcp = Teuchos::rcp( new std::vector<FadType> );
198  x_fad_rcp->reserve(n);
199 
200  // Allocate for gradient
201  auto g_fad_rcp = Teuchos::rcp( new std::vector<FadType> );
202 
203  g_fad_rcp->reserve(n);
204 
205  for(int i=0; i<n; ++i) {
206  x_fad_rcp->push_back(FadType(1,(*xp)[i]));
207  g_fad_rcp->push_back(0);
208  (*x_fad_rcp)[i].fastAccessDx(0) = (*vp)[i];
209  }
210 
211  FadVector x_fad(x_fad_rcp);
212  FadVector g_fad(g_fad_rcp);
213 
214  FadType tol_fad = tol;
215  obj_->gradient(g_fad,x_fad,tol_fad);
216 
217  for(int i=0; i<n; ++i) {
218  (*hvp)[i] = (*g_fad_rcp)[i].dx(0);
219  }
220  }
221 };
222 
223 
224 template<class Real>
225 class ObjectiveAD : public Objective<Real> {
226 
227  typedef Sacado::Fad::SFad<Real,1> FadType;
228  typedef Sacado::Fad::DFad<FadType> FadFadType;
229 
230  private:
231 
232  Teuchos::RCP<Objective<FadFadType>> obj_;
233  Teuchos::RCP<Objective<FadType>> grad_;
234  Teuchos::RCP<Objective<Real>> hess_;
235 
236  public:
237  ObjectiveAD( const Zakharov<FadFadType> &zakharov ) :
238  obj_(Teuchos::rcp(new ObjectiveEnabler<FadFadType>(zakharov))),
239  grad_(Teuchos::rcp(new GradientEnabler<FadType>(obj_))),
240  hess_(Teuchos::rcp(new HessianEnabler<Real>(grad_))) {}
241 
242 
243  Real value(const Vector<Real> &x, Real &tol) { return hess_->value(x,tol); }
244 
245  void gradient(Vector<Real> &g, const Vector<Real> &x, Real &tol) {
246  hess_->gradient(g,x,tol);
247  }
248 
249  void hessVec(Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol) {
250  hess_->hessVec(hv,v,x,tol);
251  }
252 };
253 
254 
255 
Provides the interface to evaluate objective functions.
StdVector< FadType > FadVector
Definition: example_01d.hpp:72
Sacado::Fad::DFad< Real > FadType
Definition: example_01d.hpp:71
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
Teuchos::RCP< Objective< Real > > hess_
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
Definition: example_01d.hpp:64
HessianEnabler(Teuchos::RCP< Objective< FadType >> obj)
Sacado::Fad::DFad< FadType > FadFadType
ObjectiveEnabler(const Zakharov< Real > &zak)
Definition: example_01d.hpp:63
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:72
Sacado::Fad::SFad< Real, 1 > FadType
StdVector< FadType > FadVector
Provides the std::vector implementation of the ROL::Vector interface.
Sacado::Fad::SFad< Real, 1 > FadType
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
Definition: example_01d.hpp:33
ObjectiveAD(const Zakharov< FadFadType > &zakharov)
Teuchos::RCP< Objective< FadType > > grad_
Real value(const Vector< Real > &x, Real &tol)
Compute value.
Definition: example_01d.hpp:79
Zakharov< Real > zakharov
Definition: example_01d.hpp:61
Teuchos::RCP< Objective< FadFadType > > obj_
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Teuchos::RCP< const std::vector< Real > > access_elements(const Vector< Real > &x)
Definition: example_01d.hpp:14
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
GradientEnabler(Teuchos::RCP< Objective< FadType >> obj)
Definition: example_01d.hpp:77