ROL
ROL_Bounds.hpp
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 #ifndef ROL_BOUNDS_H
45 #define ROL_BOUNDS_H
46 
47 #include "ROL_BoundConstraint.hpp"
48 
56 namespace ROL {
57 
58 template <class Real>
59 class Bounds : public BoundConstraint<Real> {
60 private:
61  const ROL::Ptr<Vector<Real> > x_lo_;
62  const ROL::Ptr<Vector<Real> > x_up_;
63  const Real scale_;
64 
65  ROL::Ptr<Vector<Real> > mask_;
66 
67  Real min_diff_;
68 
69  Elementwise::ReductionMin<Real> minimum_;
70 
71  class Active : public Elementwise::BinaryFunction<Real> {
72  public:
73  Active(Real offset) : offset_(offset) {}
74  Real apply( const Real &x, const Real &y ) const {
75  return ((y <= offset_) ? 0 : x);
76  }
77  private:
78  Real offset_;
79  };
80 
81  class UpperBinding : public Elementwise::BinaryFunction<Real> {
82  public:
83  UpperBinding(Real offset) : offset_(offset) {}
84  Real apply( const Real &x, const Real &y ) const {
85  return ((y < 0 && x <= offset_) ? 0 : 1);
86  }
87  private:
88  Real offset_;
89  };
90 
91  class LowerBinding : public Elementwise::BinaryFunction<Real> {
92  public:
93  LowerBinding(Real offset) : offset_(offset) {}
94  Real apply( const Real &x, const Real &y ) const {
95  return ((y > 0 && x <= offset_) ? 0 : 1);
96  }
97  private:
98  Real offset_;
99  };
100 
101  class PruneBinding : public Elementwise::BinaryFunction<Real> {
102  public:
103  Real apply( const Real &x, const Real &y ) const {
104  return ((y == 1) ? x : 0);
105  }
106  } prune_;
107 
108 public:
109 
111  bool isLower = true,
112  Real scale = 1)
113  : x_lo_(x.clone()), x_up_(x.clone()),
114  scale_(scale), mask_(x.clone()),
115  min_diff_(ROL_INF<Real>()) {
116  if (isLower) {
117  x_lo_->set(x);
118  x_up_->applyUnary(Elementwise::Fill<Real>(ROL_INF<Real>()));
120  }
121  else {
122  x_lo_->applyUnary(Elementwise::Fill<Real>(ROL_NINF<Real>()));
123  x_up_->set(x);
125  }
126  }
127 
128  Bounds(const ROL::Ptr<Vector<Real> > &x_lo,
129  const ROL::Ptr<Vector<Real> > &x_up,
130  const Real scale = 1)
131  : x_lo_(x_lo), x_up_(x_up), scale_(scale), mask_(x_lo->clone()) {
132  const Real half(0.5), one(1);
133  // Compute difference between upper and lower bounds
134  mask_->set(*x_up_);
135  mask_->axpy(-one,*x_lo_);
136  // Compute minimum difference
137  min_diff_ = mask_->reduce(minimum_);
138  min_diff_ *= half;
139  }
140 
141  virtual void project( Vector<Real> &x ) {
142  struct Lesser : public Elementwise::BinaryFunction<Real> {
143  Real apply(const Real &xc, const Real &yc) const { return xc<yc ? xc : yc; }
144  } lesser;
145 
146  struct Greater : public Elementwise::BinaryFunction<Real> {
147  Real apply(const Real &xc, const Real &yc) const { return xc>yc ? xc : yc; }
148  } greater;
149 
151  x.applyBinary(lesser, *x_up_); // Set x to the elementwise minimum of x and x_up_
152  }
154  x.applyBinary(greater,*x_lo_); // Set x to the elementwise maximum of x and x_lo_
155  }
156  }
157 
158  virtual void projectInterior( Vector<Real> &x ) {
159  // Make vector strictly feasible
160  const Real eps(1e-1);
161  // Lower feasibility
163  class LowerFeasible : public Elementwise::BinaryFunction<Real> {
164  private:
165  const Real eps_;
166  const Real diff_;
167  public:
168  LowerFeasible(const Real eps, const Real diff)
169  : eps_(eps), diff_(diff) {}
170  Real apply( const Real &x, const Real &y ) const {
171  const Real tol = static_cast<Real>(100)*ROL_EPSILON<Real>();
172  const Real one(1);
173  Real val = ((y <-tol) ? y*(one-eps_)
174  : ((y > tol) ? y*(one+eps_)
175  : y+eps_));
176  val = std::min(y+eps_*diff_, val);
177  return (x < y+tol) ? val : x;
178  }
179  };
180  x.applyBinary(LowerFeasible(eps,min_diff_), *x_lo_);
181  }
182  // Upper feasibility
184  class UpperFeasible : public Elementwise::BinaryFunction<Real> {
185  private:
186  const Real eps_;
187  const Real diff_;
188  public:
189  UpperFeasible(const Real eps, const Real diff)
190  : eps_(eps), diff_(diff) {}
191  Real apply( const Real &x, const Real &y ) const {
192  const Real tol = static_cast<Real>(100)*ROL_EPSILON<Real>();
193  const Real one(1);
194  Real val = ((y <-tol) ? y*(one+eps_)
195  : ((y > tol) ? y*(one-eps_)
196  : y-eps_));
197  val = std::max(y-eps_*diff_, val);
198  return (x > y-tol) ? val : x;
199  }
200  };
201  x.applyBinary(UpperFeasible(eps,min_diff_), *x_up_);
202  }
203  }
204 
205  void pruneUpperActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
207  Real one(1), epsn(std::min(scale_*eps,min_diff_));
208 
209  mask_->set(*x_up_);
210  mask_->axpy(-one,x);
211 
212  Active op(epsn);
213  v.applyBinary(op,*mask_);
214  }
215  }
216 
217  void pruneUpperActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
219  Real one(1), epsn(std::min(scale_*eps,min_diff_));
220 
221  mask_->set(*x_up_);
222  mask_->axpy(-one,x);
223 
224  UpperBinding op(epsn);
225  mask_->applyBinary(op,g);
226 
228  }
229  }
230 
231  void pruneLowerActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
233  Real one(1), epsn(std::min(scale_*eps,min_diff_));
234 
235  mask_->set(x);
236  mask_->axpy(-one,*x_lo_);
237 
238  Active op(epsn);
239  v.applyBinary(op,*mask_);
240  }
241  }
242 
243  void pruneLowerActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
245  Real one(1), epsn(std::min(scale_*eps,min_diff_));
246 
247  mask_->set(x);
248  mask_->axpy(-one,*x_lo_);
249 
250  LowerBinding op(epsn);
251  mask_->applyBinary(op,g);
252 
254  }
255  }
256 
257  const ROL::Ptr<const Vector<Real> > getLowerBound( void ) const {
258  return x_lo_;
259  }
260 
261  const ROL::Ptr<const Vector<Real> > getUpperBound( void ) const {
262  return x_up_;
263  }
264 
265  virtual bool isFeasible( const Vector<Real> &v ) {
266  const Real one(1);
267  bool flagU = false, flagL = false;
269  mask_->set(*x_up_);
270  mask_->axpy(-one,v);
271  Real uminusv = mask_->reduce(minimum_);
272  flagU = ((uminusv<0) ? true : false);
273  }
275  mask_->set(v);
276  mask_->axpy(-one,*x_lo_);
277  Real vminusl = mask_->reduce(minimum_);
278 
279  flagL = ((vminusl<0) ? true : false);
280  }
281  return ((flagU || flagL) ? false : true);
282  }
283 
284 }; // class Bounds
285 
286 } // namespace ROL
287 
288 #endif
void activateLower(void)
Turn on lower bound.
Real apply(const Real &x, const Real &y) const
Definition: ROL_Bounds.hpp:94
virtual void projectInterior(Vector< Real > &x)
Project optimization variables into the interior of the feasible set.
Definition: ROL_Bounds.hpp:158
void pruneUpperActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the upper -active set.
Definition: ROL_Bounds.hpp:205
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
Definition: ROL_Vector.hpp:236
Real ROL_INF(void)
Definition: ROL_Types.hpp:105
Real apply(const Real &x, const Real &y) const
Definition: ROL_Bounds.hpp:84
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
void pruneLowerActive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the -binding set.
Definition: ROL_Bounds.hpp:243
virtual bool isFeasible(const Vector< Real > &v)
Check if the vector, v, is feasible.
Definition: ROL_Bounds.hpp:265
void pruneUpperActive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the upper -binding set.
Definition: ROL_Bounds.hpp:217
Elementwise::ReductionMin< Real > minimum_
Definition: ROL_Bounds.hpp:69
void activateUpper(void)
Turn on upper bound.
const ROL::Ptr< Vector< Real > > x_lo_
Definition: ROL_Bounds.hpp:61
Bounds(const Vector< Real > &x, bool isLower=true, Real scale=1)
Definition: ROL_Bounds.hpp:110
const ROL::Ptr< const Vector< Real > > getLowerBound(void) const
Return the ref count pointer to the lower bound vector.
Definition: ROL_Bounds.hpp:257
Provides the elementwise interface to apply upper and lower bound constraints.
Definition: ROL_Bounds.hpp:59
ROL::Bounds::PruneBinding prune_
Bounds(const ROL::Ptr< Vector< Real > > &x_lo, const ROL::Ptr< Vector< Real > > &x_up, const Real scale=1)
Definition: ROL_Bounds.hpp:128
const Real scale_
Definition: ROL_Bounds.hpp:63
Provides the interface to apply upper and lower bound constraints.
ROL::Ptr< Vector< Real > > mask_
Definition: ROL_Bounds.hpp:65
const ROL::Ptr< const Vector< Real > > getUpperBound(void) const
Return the ref count pointer to the upper bound vector.
Definition: ROL_Bounds.hpp:261
Real apply(const Real &x, const Real &y) const
Definition: ROL_Bounds.hpp:103
Real apply(const Real &x, const Real &y) const
Definition: ROL_Bounds.hpp:74
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.
Definition: ROL_Bounds.hpp:141
void pruneLowerActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the lower -active set.
Definition: ROL_Bounds.hpp:231
ROL::DiagonalOperator apply
Real min_diff_
Definition: ROL_Bounds.hpp:67
const ROL::Ptr< Vector< Real > > x_up_
Definition: ROL_Bounds.hpp:62
Active(Real offset)
Definition: ROL_Bounds.hpp:73