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),
130  mask_(Teuchos::null), activated_(false), min_diff_(0) {}
131 
132  BoundConstraint( const Vector<Real> &x ) : x_lo_(x.clone()),
133  x_up_(x.clone()), scale_(1),
134  mask_(Teuchos::null), activated_(false), min_diff_(0) {
135  x_lo_->applyUnary(Elementwise::Fill<Real>(ROL_NINF<Real>()));
136  x_up_->applyUnary(Elementwise::Fill<Real>(ROL_INF<Real>()));
137 
138  }
143  BoundConstraint(const Teuchos::RCP<Vector<Real> > &x_lo,
144  const Teuchos::RCP<Vector<Real> > &x_up,
145  const Real scale = 1)
146  : x_lo_(x_lo), x_up_(x_up), scale_(scale), activated_(true) {
147  Real half(0.5), one(1);
148  mask_ = x_lo_->clone();
149 
150  // Compute difference between upper and lower bounds
151  mask_->set(*x_up_);
152  mask_->axpy(-one,*x_lo_);
153 
154  // Compute minimum difference
155  min_diff_ = mask_->reduce(minimum_);
156  min_diff_ *= half;
157 
158  }
159 
167  virtual void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {}
168 
177  virtual void project( Vector<Real> &x ) {
178 
179  struct Lesser : public Elementwise::BinaryFunction<Real> {
180  Real apply(const Real &xc, const Real &yc) const { return xc<yc ? xc : yc; }
181  } lesser;
182 
183  struct Greater : public Elementwise::BinaryFunction<Real> {
184  Real apply(const Real &xc, const Real &yc) const { return xc>yc ? xc : yc; }
185  } greater;
186 
187  x.applyBinary(lesser, *x_up_); // Set x to the elementwise minimum of x and x_up_
188  x.applyBinary(greater,*x_lo_); // Set x to the elementwise maximum of x and x_lo_
189 
190  }
191 
203  virtual void pruneUpperActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
204 
205  Real one(1), epsn(std::min(scale_*eps,min_diff_));
206 
207  mask_->set(*x_up_);
208  mask_->axpy(-one,x);
209 
210  Active op(epsn);
211  v.applyBinary(op,*mask_);
212 
213  }
214 
228  virtual void pruneUpperActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
229 
230  Real one(1), epsn(std::min(scale_*eps,min_diff_));
231 
232  mask_->set(*x_up_);
233  mask_->axpy(-one,x);
234 
235  UpperBinding op(epsn);
236  mask_->applyBinary(op,g);
237 
239 
240  }
241 
253  virtual void pruneLowerActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
254 
255  Real one(1), epsn(std::min(scale_*eps,min_diff_));
256 
257  mask_->set(x);
258  mask_->axpy(-one,*x_lo_);
259 
260  Active op(epsn);
261  v.applyBinary(op,*mask_);
262 
263  }
264 
278  virtual void pruneLowerActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
279 
280  Real one(1), epsn(std::min(scale_*eps,min_diff_));
281 
282  mask_->set(x);
283  mask_->axpy(-one,*x_lo_);
284 
285  LowerBinding op(epsn);
286  mask_->applyBinary(op,g);
287 
289 
290  }
291 
293  virtual const Teuchos::RCP<const Vector<Real> > getLowerVectorRCP( void ) const {
294  return x_lo_;
295  }
296 
298  virtual const Teuchos::RCP<const Vector<Real> > getUpperVectorRCP( void ) const {
299  return x_up_;
300  }
301 
303  virtual const Teuchos::RCP<Vector<Real> > getLowerVectorRCP( void ) {
304  return x_lo_;
305  }
306 
308  virtual const Teuchos::RCP<Vector<Real> > getUpperVectorRCP( void ) {
309  return x_up_;
310  }
311 
312 
313 
319  virtual void setVectorToUpperBound( Vector<Real> &u ) {
320  if( x_up_ == Teuchos::null ) {
321  u.applyUnary(Elementwise::Fill<Real>(ROL_INF<Real>()));
322  }
323  else {
324  u.set(*x_up_);
325  }
326  }
327 
333  virtual void setVectorToLowerBound( Vector<Real> &l ) {
334  if( x_lo_ == Teuchos::null ) {
335  l.applyUnary(Elementwise::Fill<Real>(ROL_NINF<Real>()));
336  }
337  else {
338  l.set(*x_lo_);
339  }
340  }
341 
353  virtual void pruneActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
354  pruneUpperActive(v,x,eps);
355  pruneLowerActive(v,x,eps);
356  }
357 
370  virtual void pruneActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
371  pruneUpperActive(v,g,x,eps);
372  pruneLowerActive(v,g,x,eps);
373  }
374 
380  virtual bool isFeasible( const Vector<Real> &v ) {
381  bool flag = true;
382  Real one(1);
383  if ( activated_ ) {
384  mask_->set(*x_up_);
385  mask_->axpy(-one,v);
386  Real uminusv = mask_->reduce(minimum_);
387 
388  mask_->set(v);
389  mask_->axpy(-one,*x_lo_);
390  Real vminusl = mask_->reduce(minimum_);
391 
392  flag = (((uminusv < 0) || (vminusl<0)) ? false : true);
393  }
394  return flag;
395  }
396 
401  void activate(void) { activated_ = true; }
402 
407  void deactivate(void) { activated_ = false; }
408 
413  bool isActivated(void) { return activated_; }
414 
422  void pruneInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
423  Real one(1);
424  Teuchos::RCP<Vector<Real> > tmp = v.clone();
425  tmp->set(v);
426  pruneActive(*tmp,x,eps);
427  v.axpy(-one,*tmp);
428  }
429  void pruneLowerInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
430  Real one(1);
431  Teuchos::RCP<Vector<Real> > tmp = v.clone();
432  tmp->set(v);
433  pruneLowerActive(*tmp,x,eps);
434  v.axpy(-one,*tmp);
435  }
436  void pruneUpperInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0 ) {
437  Real one(1);
438  Teuchos::RCP<Vector<Real> > tmp = v.clone();
439  tmp->set(v);
440  pruneUpperActive(*tmp,x,eps);
441  v.axpy(-one,*tmp);
442  }
443 
444 
453  void pruneInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
454  Real one(1);
455  Teuchos::RCP<Vector<Real> > tmp = v.clone();
456  tmp->set(v);
457  pruneActive(*tmp,g,x,eps);
458  v.axpy(-one,*tmp);
459  }
460  void pruneLowerInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
461  Real one(1);
462  Teuchos::RCP<Vector<Real> > tmp = v.clone();
463  tmp->set(v);
464  pruneLowerActive(*tmp,g,x,eps);
465  v.axpy(-one,*tmp);
466  }
467  void pruneUpperInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0 ) {
468  Real one(1);
469  Teuchos::RCP<Vector<Real> > tmp = v.clone();
470  tmp->set(v);
471  pruneUpperActive(*tmp,g,x,eps);
472  v.axpy(-one,*tmp);
473  }
474 
482  Teuchos::RCP<Vector<Real> > tmp = g.clone();
483  tmp->set(g);
484  pruneActive(g,*tmp,x);
485  }
486 
494  Real one(1);
495  v.plus(x);
496  project(v);
497  v.axpy(-one,x);
498  }
499 
500 }; // class BoundConstraint
501 
502 } // namespace ROL
503 
504 #endif
bool activated_
Flag that determines whether or not the constraints are being used.
Elementwise::ReductionMin< Real > minimum_
BoundConstraint(const Teuchos::RCP< Vector< Real > > &x_lo, const Teuchos::RCP< Vector< Real > > &x_up, const Real scale=1)
Default constructor.
BoundConstraint(const Vector< Real > &x)
Real apply(const Real &x, const Real &y) const
Real apply(const Real &x, const Real &y) const
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.
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
Definition: ROL_Vector.hpp:222
virtual const Teuchos::RCP< Vector< Real > > getLowerVectorRCP(void)
Return the ref count pointer to the lower bound vector.
Contains definitions of custom data types in ROL.
virtual const Teuchos::RCP< Vector< Real > > getUpperVectorRCP(void)
Return the ref count pointer to the upper bound vector.
virtual 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 lower -binding set.
const Teuchos::RCP< Vector< Real > > x_lo_
ROL::BoundConstraint::PruneBinding prune_
Teuchos::RCP< Vector< Real > > mask_
void pruneInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the -inactive set.
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.
void pruneUpperInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
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 > &x, Real eps=0)
Set variables to zero if they correspond to the -active set.
virtual 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.
virtual void pruneLowerActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the lower -active set.
const Teuchos::RCP< Vector< Real > > x_up_
bool isActivated(void)
Check if bounds are on.
virtual void pruneUpperActive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the upper -active set.
virtual const Teuchos::RCP< const Vector< Real > > getUpperVectorRCP(void) const
Return the ref count pointer to the upper bound vector.
void pruneLowerInactive(Vector< Real > &v, const Vector< Real > &x, Real eps=0)
void computeProjectedStep(Vector< Real > &v, const Vector< Real > &x)
Compute projected step.
Real apply(const Real &x, const Real &y) const
void pruneLowerInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0)
virtual void setVectorToLowerBound(Vector< Real > &l)
Set the input vector to the lower bound.
Provides the interface to apply upper and lower bound constraints.
virtual void applyUnary(const Elementwise::UnaryFunction< Real > &f)
Definition: ROL_Vector.hpp:217
void computeProjectedGradient(Vector< Real > &g, const Vector< Real > &x)
Compute projected gradient.
virtual const Teuchos::RCP< const Vector< Real > > getLowerVectorRCP(void) const
Return the ref count pointer to the lower bound vector.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:196
void pruneUpperInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0)
void pruneInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0)
Set variables to zero if they correspond to the -nonbinding set.
void deactivate(void)
Turn off bounds.
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 pruneActive(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.
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.