ROL
ROL_BoundConstraint.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_BOUND_CONSTRAINT_H
45 #define ROL_BOUND_CONSTRAINT_H
46 
47 #include "ROL_Vector.hpp"
48 #include "ROL_Types.hpp"
49 #include <iostream>
50 
69 namespace ROL {
70 
71 template <class Real>
73 private:
74  int dim_;
75 
76  const Teuchos::RCP<Vector<Real> > x_lo_;
77  const Teuchos::RCP<Vector<Real> > x_up_;
78  const Real scale_;
79 
80  Teuchos::RCP<Vector<Real> > mask_;
81 
82  bool activated_;
83  Real min_diff_;
84 
85  Elementwise::ReductionMin<Real> minimum_;
86 
87  class Active : public Elementwise::BinaryFunction<Real> {
88  public:
89  Active(Real offset) : offset_(offset) {}
90  Real apply( const Real &x, const Real &y ) const {
91  return ((y <= offset_) ? 0 : x);
92  }
93  private:
94  Real offset_;
95  };
96 
97  class UpperBinding : public Elementwise::BinaryFunction<Real> {
98  public:
99  UpperBinding(Real offset) : offset_(offset) {}
100  Real apply( const Real &x, const Real &y ) const {
101  return ((y < 0 && x <= offset_) ? 0 : 1);
102  }
103  private:
104  Real offset_;
105  };
106 
107  class LowerBinding : public Elementwise::BinaryFunction<Real> {
108  public:
109  LowerBinding(Real offset) : offset_(offset) {}
110  Real apply( const Real &x, const Real &y ) const {
111  return ((y > 0 && x <= offset_) ? 0 : 1);
112  }
113  private:
114  Real offset_;
115  };
116 
117  class PruneBinding : public Elementwise::BinaryFunction<Real> {
118  public:
119  Real apply( const Real &x, const Real &y ) const {
120  return ((y == 1) ? x : 0);
121  }
122  } prune_;
123 
124 public:
125 
126  virtual ~BoundConstraint() {}
127 
129  : x_lo_(Teuchos::null), x_up_(Teuchos::null), scale_(1.0),
130  mask_(Teuchos::null), activated_(true), min_diff_(0.0) {}
131 
136  BoundConstraint(const Teuchos::RCP<Vector<Real> > &x_lo,
137  const Teuchos::RCP<Vector<Real> > &x_up,
138  const Real scale = 1.0)
139  : x_lo_(x_lo), x_up_(x_up), scale_(scale), activated_(true) {
140  mask_ = x_lo_->clone();
141 
142  // Compute difference between upper and lower bounds
143  mask_->set(*x_up_);
144  mask_->axpy(-1.0,*x_lo_);
145 
146  // Compute minimum difference
147  min_diff_ = mask_->reduce(minimum_);
148  min_diff_ *= 0.5;
149 
150  }
151 
159  virtual void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {}
160 
169  virtual void project( Vector<Real> &x ) {
170 
171  struct Lesser : public Elementwise::BinaryFunction<Real> {
172  Real apply(const Real &xc, const Real &yc) const { return xc<yc ? xc : yc; }
173  } lesser;
174 
175  struct Greater : public Elementwise::BinaryFunction<Real> {
176  Real apply(const Real &xc, const Real &yc) const { return xc>yc ? xc : yc; }
177  } greater;
178 
179  x.applyBinary(lesser, *x_up_); // Set x to the elementwise minimum of x and x_up_
180  x.applyBinary(greater,*x_lo_); // Set x to the elementwise maximum of x and x_lo_
181 
182  }
183 
195  virtual void pruneUpperActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
196 
197  Real epsn = std::min(scale_*eps,min_diff_);
198 
199  mask_->set(*x_up_);
200  mask_->axpy(-1.0,x);
201 
202  Active op(epsn);
203  v.applyBinary(op,*mask_);
204 
205  }
206 
220  virtual void pruneUpperActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
221 
222  Real epsn = std::min(scale_*eps,min_diff_);
223 
224  mask_->set(*x_up_);
225  mask_->axpy(-1.0,x);
226 
227  UpperBinding op(epsn);
228  mask_->applyBinary(op,g);
229 
230  v.applyBinary(prune_,*mask_);
231 
232  }
233 
245  virtual void pruneLowerActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
246 
247  Real epsn = std::min(scale_*eps,min_diff_);
248 
249  mask_->set(x);
250  mask_->axpy(-1.0,*x_lo_);
251 
252  Active op(epsn);
253  v.applyBinary(op,*mask_);
254 
255  }
256 
270  virtual void pruneLowerActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
271 
272  Real epsn = std::min(scale_*eps,min_diff_);
273 
274  mask_->set(x);
275  mask_->axpy(-1.0,*x_lo_);
276 
277  LowerBinding op(epsn);
278  mask_->applyBinary(op,g);
279 
280  v.applyBinary(prune_,*mask_);
281 
282  }
283 
285  const Teuchos::RCP<Vector<Real> > getLowerVectorRCP( void ) const {
286  return x_lo_;
287  }
288 
290  const Teuchos::RCP<Vector<Real> > getUpperVectorRCP( void ) const {
291  return x_up_;
292  }
293 
294 
295 
296 
302  virtual void setVectorToUpperBound( Vector<Real> &u ) {
303  u.set(*x_up_);
304  }
305 
311  virtual void setVectorToLowerBound( Vector<Real> &l ) {
312  l.set(*x_lo_);
313  }
314 
326  virtual void pruneActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
327  pruneUpperActive(v,x,eps);
328  pruneLowerActive(v,x,eps);
329  }
330 
343  virtual void pruneActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
344  pruneUpperActive(v,g,x,eps);
345  pruneLowerActive(v,g,x,eps);
346  }
347 
353  virtual bool isFeasible( const Vector<Real> &v ) {
354  bool flag = true;
355  if ( activated_ ) {
356  mask_->set(*x_up_);
357  mask_->axpy(-1.0,v);
358  Real uminusv = mask_->reduce(minimum_);
359 
360  mask_->set(v);
361  mask_->axpy(-1.0,*x_lo_);
362  Real vminusl = mask_->reduce(minimum_);
363 
364  flag = (((uminusv < 0) || (vminusl<0)) ? false : true);
365  }
366  return flag;
367  }
368 
373  void activate(void) { activated_ = true; }
374 
379  void deactivate(void) { activated_ = false; }
380 
385  bool isActivated(void) { return activated_; }
386 
394  void pruneInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
395  Teuchos::RCP<Vector<Real> > tmp = v.clone();
396  tmp->set(v);
397  pruneActive(*tmp,x,eps);
398  v.axpy(-1.0,*tmp);
399  }
400  void pruneLowerInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
401  Teuchos::RCP<Vector<Real> > tmp = v.clone();
402  tmp->set(v);
403  pruneLowerActive(*tmp,x,eps);
404  v.axpy(-1.0,*tmp);
405  }
406  void pruneUpperInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
407  Teuchos::RCP<Vector<Real> > tmp = v.clone();
408  tmp->set(v);
409  pruneUpperActive(*tmp,x,eps);
410  v.axpy(-1.0,*tmp);
411  }
412 
413 
422  void pruneInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
423  Teuchos::RCP<Vector<Real> > tmp = v.clone();
424  tmp->set(v);
425  pruneActive(*tmp,g,x,eps);
426  v.axpy(-1.0,*tmp);
427  }
428  void pruneLowerInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
429  Teuchos::RCP<Vector<Real> > tmp = v.clone();
430  tmp->set(v);
431  pruneLowerActive(*tmp,g,x,eps);
432  v.axpy(-1.0,*tmp);
433  }
434  void pruneUpperInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
435  Teuchos::RCP<Vector<Real> > tmp = v.clone();
436  tmp->set(v);
437  pruneUpperActive(*tmp,g,x,eps);
438  v.axpy(-1.0,*tmp);
439  }
440 
448  Teuchos::RCP<Vector<Real> > tmp = g.clone();
449  tmp->set(g);
450  pruneActive(g,*tmp,x);
451  }
452 
460  v.plus(x);
461  project(v);
462  v.axpy(-1.0,x);
463  }
464 
465 }; // class BoundConstraint
466 
467 } // namespace ROL
468 
469 #endif
bool activated_
Flag that determines whether or not the constraints are being used.
Elementwise::ReductionMin< Real > minimum_
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:143
void activate(void)
Turn on bounds.
void pruneLowerInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
Definition: ROL_Vector.hpp:222
Contains definitions of custom data types in ROL.
const Teuchos::RCP< Vector< Real > > x_lo_
ROL::BoundConstraint::PruneBinding prune_
Teuchos::RCP< Vector< Real > > mask_
virtual void pruneLowerActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the lower -active set.
void pruneLowerInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
const Teuchos::RCP< Vector< Real > > getLowerVectorRCP(void) const
Return the ref count pointer to the lower bound vector.
virtual void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update bounds.
virtual Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void setVectorToUpperBound(Vector< Real > &u)
Set the input vector to the upper bound.
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:74
virtual void pruneActive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the -binding set.
const Teuchos::RCP< Vector< Real > > x_up_
const Teuchos::RCP< Vector< Real > > getUpperVectorRCP(void) const
Return the ref count pointer to the upper bound vector.
bool isActivated(void)
Check if bounds are on.
void pruneUpperInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
virtual void pruneUpperActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the upper -active set.
void computeProjectedStep(Vector< Real > &v, const Vector< Real > &x)
Compute projected step.
void pruneInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the -inactive set.
virtual void setVectorToLowerBound(Vector< Real > &l)
Set the input vector to the lower bound.
Real apply(const Real &x, const Real &y) const
Provides the interface to apply upper and lower bound constraints.
Real apply(const Real &x, const Real &y) const
void computeProjectedGradient(Vector< Real > &g, const Vector< Real > &x)
Compute projected gradient.
Real apply(const Real &x, const Real &y) const
virtual void pruneUpperActive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the upper -binding set.
virtual void pruneLowerActive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the lower -binding set.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:196
virtual void pruneActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the -active set.
void pruneUpperInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
BoundConstraint(const Teuchos::RCP< Vector< Real > > &x_lo, const Teuchos::RCP< Vector< Real > > &x_up, const Real scale=1.0)
Default constructor.
void deactivate(void)
Turn off bounds.
void pruneInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
Set variables to zero if they correspond to the -nonbinding set.
virtual bool isFeasible(const Vector< Real > &v)
Check if the vector, v, is feasible.
Real apply(const Real &x, const Real &y) const
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.