ROL
ROL_SerialObjective.hpp
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 #pragma once
11 #ifndef ROL_SERIALOBJECTIVE_HPP
12 #define ROL_SERIALOBJECTIVE_HPP
13 
14 #include <type_traits>
15 
16 #include "ROL_Objective_SimOpt.hpp"
17 #include "ROL_DynamicObjective.hpp"
18 #include "ROL_SerialFunction.hpp"
19 
34 namespace ROL {
35 
36 template<typename Real>
37 class SerialObjective : public Objective_SimOpt<Real>,
38  public SerialFunction<Real> {
39 private:
43 
44  Ptr<DynamicObjective<Real>> obj_; // Objective over a single time step
45 
46 public:
47 
53 
55  const Vector<Real>& u_initial,
56  const TimeStampsPtr<Real> timeStampsPtr ) :
57  SerialFunction<Real>::SerialFunction( u_initial, timeStampsPtr ),
58  obj_(obj) {}
59 
61  virtual Real value( const Vector<Real>& u,
62  const Vector<Real>& z,
63  Real& tol ) override {
64 
65  auto& up = partition(u);
66  auto& zp = partition(z);
67  Real result = 0;
68 
69  if( !getSkipInitialCondition() )
70  result += obj_->value( getInitialCondition(), up[0], zp[0], ts(0) );
71 
72  for( size_type k=1; k<numTimeSteps(); ++k )
73  result += obj_->value( up[k-1], up[k], zp[k], ts(k) );
74 
75  return result;
76  } // value
77 
78  virtual void gradient_1( Vector<Real>& g,
79  const Vector<Real>& u,
80  const Vector<Real>& z,
81  Real& tol ) override {
82 
83  auto& gp = partition(g);
84  auto& up = partition(u);
85  auto& zp = partition(z);
86 
87  auto tmp = clone(gp[0]);
88  auto& x = *tmp;
89 
90  // TODO: Implement skip initial condition
91 
92  obj_->gradient_un( gp[0], getInitialCondition(), up[0], zp[0], ts(0) );
93  obj_->gradient_uo( x, up[0], up[1], zp[1], ts(1) );
94  gp[0].plus(x);
95 
96  for( size_type k=1; k<numTimeSteps()-1; ++k ) {
97  obj_->gradient_un( gp[k], up[k-1], up[k], zp[k], ts(k) );
98  obj_->gradient_uo( x, up[k], up[k+1], zp[k+1], ts(k+1) );
99  gp[k].plus(x);
100  }
101 
102  size_t N = numTimeSteps()-1;
103 
104  obj_->gradient_un( gp[N], up[N-1], up[N], zp[N], ts(N) );
105 
106  } // gradient_1
107 
108  virtual void gradient_2( Vector<Real>& g,
109  const Vector<Real>& u,
110  const Vector<Real>& z,
111  Real& tol ) override {
112 
113  auto& gp = partition(g);
114  auto& up = partition(u);
115  auto& zp = partition(z);
116 
117  if( !getSkipInitialCondition() )
118  obj_->gradient_z( gp[0], getInitialCondition(), up[0], zp[0], ts(0) );
119 
120  for( size_type k=1; k<numTimeSteps(); ++k )
121  obj_->gradient_z( gp[k], up[k-1], up[k], zp[k], ts(k) ); // df[k]/dz[k]
122 
123  } // gradient_2
124 
125  virtual void hessVec_11( Vector<Real>& hv,
126  const Vector<Real>& v,
127  const Vector<Real>& u,
128  const Vector<Real>& z,
129  Real& tol ) override {
130 
131  auto& hvp = partition(hv); auto& vp = partition(v);
132  auto& up = partition(u); auto& zp = partition(z);
133 
134  auto tmp = clone(hvp[0]);
135  auto& x = *tmp;
136 
137  // TODO: Implement skip initial condition
138 
139  obj_->hessVec_un_un( hvp[0], vp[0], getInitialCondition(), up[0], zp[0], ts(0) );
140  obj_->hessVec_uo_uo( x, vp[0], up[0], up[1], zp[1], ts(1) );
141  hvp[0].plus(x);
142 
143  for( size_type k=1; k<numTimeSteps()-1; ++k ) {
144  obj_->hessVec_un_un( hvp[k], vp[k], up[k-1], up[k], zp[k], ts(k) );
145  obj_->hessVec_uo_uo( x, vp[k], up[k], up[k+1], zp[k+1], ts(k+1) );
146  hvp[k].plus(x);
147  }
148 
149  size_t N = numTimeSteps()-1;
150 
151  obj_->hessVec_un_un( hvp[N], vp[N], up[N-1], up[N], zp[N], ts(N) );
152 
153  } // hessVec_11
154 
155  virtual void hessVec_12( Vector<Real>& hv,
156  const Vector<Real>& v,
157  const Vector<Real>& u,
158  const Vector<Real>& z,
159  Real& tol ) override {
160 
161  auto& hvp = partition(hv); auto& vp = partition(v);
162  auto& up = partition(u); auto& zp = partition(z);
163 
164  auto tmp = clone(hvp[0]);
165  auto& x = *tmp;
166 
167  // TODO: Implement skip initial condition
168 
169  obj_->hessVec_un_z( hvp[0], vp[0], getInitialCondition(), up[0], zp[0], ts(0) );
170  obj_->hessVec_uo_z( x, vp[0], up[0], up[1], zp[1], ts(1) );
171  hvp[0].plus(x);
172 
173  for( size_type k=1; k<numTimeSteps()-1; ++k ) {
174  obj_->hessVec_un_z( hvp[k], vp[k], up[k-1], up[k], zp[k], ts(k) );
175  obj_->hessVec_uo_z( x, vp[k], up[k], up[k+1], zp[k+1], ts(k+1) );
176  hvp[k].plus(x);
177  }
178 
179  size_t N = numTimeSteps()-1;
180 
181  obj_->hessVec_un_z( hvp[N], vp[N], up[N-1], up[N], zp[N], ts(N) );
182 
183 
184  } // hessVec_22
185 
186  virtual void hessVec_21( Vector<Real>& hv,
187  const Vector<Real>& v,
188  const Vector<Real>& u,
189  const Vector<Real>& z,
190  Real& tol ) override {
191 
192  auto& hvp = partition(hv); auto& vp = partition(v);
193  auto& up = partition(u); auto& zp = partition(z);
194 
195  auto tmp = clone(hvp[0]);
196  auto& x = *tmp;
197 
198  // TODO: Implement skip initial condition
199 
200  obj_->hessVec_z_un( hvp[0], vp[0], getInitialCondition(), up[0], zp[0], ts(0) );
201 
202  for( size_type k=1; k<numTimeSteps(); ++k ) {
203  obj_->hessVec_z_un( hvp[k], vp[k], up[k-1], up[k], zp[k], ts(k) );
204  obj_->hessVec_z_uo( x, vp[k-1], up[k-1], up[k], zp[k], ts(k) );
205  hvp[k].plus(x);
206  }
207 
208  } // hessVec_21
209 
210  virtual void hessVec_22( Vector<Real>& hv,
211  const Vector<Real>& v,
212  const Vector<Real>& u,
213  const Vector<Real>& z,
214  Real& tol ) override {
215 
216  auto& hvp = partition(hv); auto& vp = partition(v);
217  auto& up = partition(u); auto& zp = partition(z);
218 
219  if( !getSkipInitialCondition() )
220  obj_->hessVec_z_z( hvp[0], vp[0], getInitialCondition(), up[0], zp[0], ts(0) );
221 
222  for( size_type k=1; k<numTimeSteps(); ++k )
223  obj_->hessVec_z_z( hvp[k], vp[k], up[k-1], up[k], zp[k], ts(k) );
224 
225 
226  } // hessVec_22
227 
228 }; // SerialObjective
229 
230 
231 // Helper function to create a new SerialObjective
232 
233 template<typename DynObj, typename Real, typename P = Ptr<SerialObjective<Real>> >
234 inline typename std::enable_if<std::is_base_of<DynamicObjective<Real>,DynObj>::value,P>::type
235 make_SerialObjective( const Ptr<DynObj>& obj,
236  const Vector<Real>& u_initial,
237  const TimeStampsPtr<Real> timeStampsPtr ) {
238  return makePtr<SerialObjective<Real>>(obj,u_initial,timeStampsPtr);
239 }
240 
241 } // namespace ROL
242 
243 
244 #endif // ROL_SERIALOBJECTIVE_HPP
PartitionedVector< Real > & partition(Vector< Real > &x)
const Vector< Real > & getInitialCondition() const
Provides the interface to evaluate simulation-based objective functions.
typename PV< Real >::size_type size_type
virtual void gradient_2(Vector< Real > &g, const Vector< Real > &u, const Vector< Real > &z, Real &tol) override
Compute gradient with respect to second component.
virtual void hessVec_11(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol) override
Apply Hessian approximation to vector.
Defines the linear algebra of vector space on a generic partitioned vector.
ROL::Objective_SimOpt value
size_type numTimeSteps() const
virtual Real value(const Vector< Real > &u, const Vector< Real > &z, Real &tol) override
Compute value.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Defines the time-dependent objective function interface for simulation-based optimization. Computes time-local contributions of value, gradient, Hessian-vector product etc to a larger composite objective defined over the simulation time. In contrast to other objective classes Objective_TimeSimOpt has a default implementation of value which returns zero, as time-dependent simulation based optimization problems may have an objective value which depends only on the final state of the system.
virtual void hessVec_22(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol) override
SerialObjective(const Ptr< DynamicObjective< Real >> &obj, const Vector< Real > &u_initial, const TimeStampsPtr< Real > timeStampsPtr)
typename std::vector< Real >::size_type size_type
Ptr< Vector< Real > > clone(const Vector< Real > &x)
Ptr< DynamicObjective< Real > > obj_
Evaluates ROL::DynamicObjective over a sequential set of time intervals.
std::enable_if< std::is_base_of< DynamicObjective< Real >, DynObj >::value, P >::type make_SerialObjective(const Ptr< DynObj > &obj, const Vector< Real > &u_initial, const TimeStampsPtr< Real > timeStampsPtr)
bool getSkipInitialCondition() const
Provides behavior common to SerialObjective as SerialConstaint.
Ptr< std::vector< TimeStamp< Real >>> TimeStampsPtr
virtual void hessVec_12(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol) override
const TimeStamp< Real > & ts(size_type i) const
virtual void gradient_1(Vector< Real > &g, const Vector< Real > &u, const Vector< Real > &z, Real &tol) override
Compute gradient with respect to first component.
virtual void hessVec_21(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &u, const Vector< Real > &z, Real &tol) override