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