ROL
ROL_InteriorPointPenalty.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 #ifndef ROL_INTERIORPOINTPENALTY_H
11 #define ROL_INTERIORPOINTPENALTY_H
12 
13 #include "ROL_Objective.hpp"
14 #include "ROL_BoundConstraint.hpp"
15 #include "ROL_ParameterList.hpp"
16 
26 namespace ROL {
27 
28 template<class Real>
29 class InteriorPointPenalty : public Objective<Real> {
30 
31  typedef Vector<Real> V;
34 
35  typedef Elementwise::ValueSet<Real> ValueSet;
36 
37 private:
38 
39  const ROL::Ptr<OBJ> obj_;
40  const ROL::Ptr<BND> bnd_;
41  const ROL::Ptr<const V> lo_;
42  const ROL::Ptr<const V> up_;
43 
44  ROL::Ptr<V> g_; // Gradient of penalized objective
45 
46  ROL::Ptr<V> maskL_; // Elements are 1 when xl>-INF, zero for xl = -INF
47  ROL::Ptr<V> maskU_; // Elements are 1 when xu< INF, zero for xu = INF
48 
49  ROL::Ptr<V> a_; // Scratch vector
50  ROL::Ptr<V> b_; // Scratch vector
51  ROL::Ptr<V> c_; // Scratch vector
52 
53  bool useLinearDamping_; // Add linear damping terms to the penalized objective
54  // to prevent the problems such as when the log barrier
55  // contribution is unbounded below on the feasible set
56 
57  Real mu_; // Penalty parameter
58  Real kappaD_; // Linear damping coefficient
59  Real fval_; // Unpenalized objective value
60 
61  int nfval_;
62  int ngval_;
63 
64 
65 
66  // x <- f(x) = { log(x) if x > 0
67  // { 0 if x <= 0
68  class ModifiedLogarithm : public Elementwise::UnaryFunction<Real> {
69  public:
70  Real apply( const Real &x ) const {
71  return (x>0) ? std::log(x) : Real(0.0);
72  }
73  }; // class ModifiedLogarithm
74 
75  // x <- f(x) = { 1/x if x > 0
76  // { 0 if x <= 0
77  class ModifiedReciprocal : public Elementwise::UnaryFunction<Real> {
78  public:
79  Real apply( const Real &x ) const {
80  return (x>0) ? 1.0/x : Real(0.0);
81  }
82 
83  }; // class ModifiedReciprocal
84 
85  // x <- f(x,y) = { y/x if x > 0
86  // { 0 if x <= 0
87  class ModifiedDivide : public Elementwise::BinaryFunction<Real> {
88  public:
89  Real apply( const Real &x, const Real &y ) const {
90  return (x>0) ? y/x : Real(0.0);
91  }
92  }; // class ModifiedDivide
93 
94  // x <- f(x,y) = { x if y != 0, complement == false
95  // { 0 if y == 0, complement == false
96  // { 0 if y != 0, complement == true
97  // { x if y == 0, complement == true
98  class Mask : public Elementwise::BinaryFunction<Real> {
99  private:
101  public:
102  Mask( bool complement ) : complement_(complement) {}
103  Real apply( const Real &x, const Real &y ) const {
104  return ( complement_ ^ (y !=0) ) ? 0 : x;
105  }
106  }; // class Mask
107 
108 
109 public:
110 
112 
113  InteriorPointPenalty( const ROL::Ptr<Objective<Real> > &obj,
114  const ROL::Ptr<BoundConstraint<Real> > &con,
115  ROL::ParameterList &parlist ) :
116  obj_(obj), bnd_(con), lo_( con->getLowerBound() ), up_( con->getUpperBound() ) {
117 
118  Real one(1);
119  Real zero(0);
120 
121  // Determine the index sets where the
122  ValueSet isBoundedBelow( ROL_NINF<Real>(), ValueSet::GREATER_THAN, one, zero );
123  ValueSet isBoundedAbove( ROL_INF<Real>(), ValueSet::LESS_THAN, one, zero );
124 
125  maskL_ = lo_->clone();
126  maskU_ = up_->clone();
127 
128  maskL_->applyBinary(isBoundedBelow,*lo_);
129  maskU_->applyBinary(isBoundedAbove,*up_);
130 
131  ROL::ParameterList &iplist = parlist.sublist("Step").sublist("Primal Dual Interior Point");
132  ROL::ParameterList &lblist = iplist.sublist("Barrier Objective");
133 
134  useLinearDamping_ = lblist.get("Use Linear Damping",true);
135  kappaD_ = lblist.get("Linear Damping Coefficient",1.e-4);
136  mu_ = lblist.get("Initial Barrier Parameter",0.1);
137 
138 
139  a_ = lo_->clone();
140  b_ = up_->clone();
141  g_ = lo_->dual().clone();
142 
143  if( useLinearDamping_ ) {
144  c_ = lo_->clone();
145  }
146  }
147 
148  Real getObjectiveValue(void) const {
149  return fval_;
150  }
151 
152  ROL::Ptr<Vector<Real> > getGradient(void) const {
153  return g_;
154  }
155 
157  return nfval_;
158  }
159 
161  return ngval_;
162  }
163 
164  ROL::Ptr<const Vector<Real> > getLowerMask(void) const {
165  return maskL_;
166  }
167 
168  ROL::Ptr<const Vector<Real> > getUpperMask(void) const {
169  return maskU_;
170  }
171 
179  void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
180  obj_->update(x,flag,iter);
181  }
182 
194  Real value( const Vector<Real> &x, Real &tol ) {
195 
196  ModifiedLogarithm mlog;
197  Elementwise::ReductionSum<Real> sum;
198  Elementwise::Multiply<Real> mult;
199 
200  // Compute the unpenalized objective value
201  fval_ = obj_->value(x,tol);
202  nfval_++;
203 
204  Real fval = fval_;
205  Real linearTerm = 0.0; // Linear damping contribution
206 
207  a_->set(x); // a_i = x_i
208  a_->axpy(-1.0,*lo_); // a_i = x_i-l_i
209 
210  if( useLinearDamping_ ) {
211 
212  c_->set(*maskL_); // c_i = { 1 if l_i > NINF
213  // { 0 otherwise
214  c_->applyBinary(Mask(true),*maskU_); // c_i = { 1 if l_i > NINF and u_i = INF
215  // { 0 otherwise
216  c_->applyBinary(mult,*a_); // c_i = { x_i-l_i if l_i > NINF and u_i = INF
217 
218  // Penalizes large positive x_i when only a lower bound exists
219  linearTerm += c_->reduce(sum);
220  }
221 
222  a_->applyUnary(mlog); // a_i = mlog(x_i-l_i)
223 
224  Real aval = a_->dot(*maskL_);
225 
226  b_->set(*up_); // b_i = u_i
227  b_->axpy(-1.0,x); // b_i = u_i-x_i
228 
229  if( useLinearDamping_ ) {
230 
231  c_->set(*maskU_); // c_i = { 1 if u_i < INF
232  // { 0 otherwise
233  c_->applyBinary(Mask(true),*maskL_); // c_i = { 1 if u_i < INF and l_i = NINF
234  // { 0 otherwise
235  c_->applyBinary(mult,*b_); // c_i = { u_i-x_i if u_i < INF and l_i = NINF
236  // { 0 otherwise
237 
238  // Penalizes large negative x_i when only an upper bound exists
239  linearTerm += c_->reduce(sum);
240 
241  }
242 
243  b_->applyUnary(mlog); // b_i = mlog(u_i-x_i)
244 
245  Real bval = b_->dot(*maskU_);
246 
247 
248  fval -= mu_*(aval+bval);
249  fval += kappaD_*mu_*linearTerm;
250 
251  return fval;
252 
253  }
254 
263  void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
264  // Compute gradient of objective function
265  obj_->gradient(*g_,x,tol);
266  ngval_++;
267  g.set(*g_);
268 
269  // Add gradient of the log barrier penalty
270  ModifiedReciprocal mrec;
271 
272  a_->set(x); // a = x
273  a_->axpy(-1.0,*lo_); // a = x-l
274 
275  a_->applyUnary(mrec); // a_i = 1/(x_i-l_i) for i s.t. x_i > l_i, 0 otherwise
276  a_->applyBinary(Mask(true),*maskL_); // zero elements where l = NINF
277 
278  b_->set(*up_); // b = u
279  b_->axpy(-1.0,x); // b = u-x
280  b_->applyUnary(mrec); // b_i = 1/(u_i-x_i) for i s.t. u_i > x_i, 0 otherwise
281  b_->applyBinary(Mask(true),*maskU_); // zero elements where u = INF
282 
283  g.axpy(-mu_,*a_);
284  g.axpy(mu_,*b_);
285 
286  if( useLinearDamping_ ) {
287 
288  a_->set(*maskL_);
289  a_->applyBinary(Mask(true),*maskU_); // a_i = { 1 if l_i > NINF and u_i = INF
290  // { 0 otherwise
291  b_->set(*maskU_);
292  b_->applyBinary(Mask(true),*maskL_); // b_i = { 1 if u_i < INF and l_i = NINF
293  // { 0 otherwise
294  g.axpy(-mu_*kappaD_,*a_);
295  g.axpy( mu_*kappaD_,*b_);
296 
297  }
298  }
299 
309  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
310 
311  ModifiedReciprocal mrec;
312  Elementwise::Multiply<Real> mult;
313  Elementwise::Power<Real> square(2.0);
314 
315  obj_->hessVec(hv,v,x,tol);
316 
317  a_->set(x); // a = x
318  a_->axpy(-1.0,*lo_); // a = x-l
319  a_->applyUnary(mrec); // a_i = 1/(x_i-l_i) for i s.t. x_i > l_i, 0 otherwise
320  a_->applyBinary(Mask(true),*maskL_); // zero elements where l = NINF
321  a_->applyUnary(square); // a_i = { (x_i-l_i)^(-2) if l_i > NINF
322  // { 0 if l_i = NINF
323  a_->applyBinary(mult,v);
324 
325  b_->set(*up_); // b = u
326  b_->axpy(-1.0,x); // b = u-x
327  b_->applyUnary(mrec); // b_i = 1/(u_i-x_i) for i s.t. u_i > x_i, 0 otherwise
328  b_->applyBinary(Mask(true),*maskU_); // zero elements where u = INF
329  b_->applyUnary(square); // b_i = { (u_i-x_i)^(-2) if u_i < INF
330  // { 0 if u_i = INF
331  b_->applyBinary(mult,v);
332 
333  hv.axpy(mu_,*a_);
334  hv.axpy(mu_,*b_);
335  }
336 
337  // Return the unpenalized objective
338  const ROL::Ptr<OBJ> getObjective( void ) { return obj_; }
339 
340  // Return the bound constraint
341  const ROL::Ptr<BND> getBoundConstraint( void ) { return bnd_; }
342 
343 }; // class InteriorPointPenalty
344 
345 }
346 
347 
348 #endif // ROL_INTERIORPOINTPENALTY_H
Provides the interface to evaluate objective functions.
Real value(const Vector< Real > &x, Real &tol)
Compute value.
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update the interior point penalized objective.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:119
ROL::Ptr< const Vector< Real > > getLowerMask(void) const
ROL::Ptr< const Vector< Real > > getUpperMask(void) const
InteriorPointPenalty(const ROL::Ptr< Objective< Real > > &obj, const ROL::Ptr< BoundConstraint< Real > > &con, ROL::ParameterList &parlist)
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Real apply(const Real &x, const Real &y) const
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
const ROL::Ptr< OBJ > getObjective(void)
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Compute action of Hessian on vector.
Provides the interface to evaluate the Interior Pointy log barrier penalty function with upper and lo...
const ROL::Ptr< BND > getBoundConstraint(void)
ROL::Ptr< Vector< Real > > getGradient(void) const
Real apply(const Real &x, const Real &y) const
const ROL::Ptr< const V > lo_
const ROL::Ptr< const V > up_
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Provides the interface to apply upper and lower bound constraints.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
Elementwise::ValueSet< Real > ValueSet