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  Teuchos::RCP<Vector<Real> > x_lo_;
76  Teuchos::RCP<Vector<Real> > x_up_;
77  Real scale_;
78  bool activated_;
79  Real min_diff_;
80 
81  Elementwise::ReductionMin<Real> minimum_;
82 
83  // Add a constant to every element in a vector
84  class Shift : public Elementwise::UnaryFunction<Real> {
85  public:
86  Shift(Real offset) : offset_(offset) {}
87  Real apply( const Real &x ) const { return offset_ + x; }
88  private:
89  Real offset_;
90  };
91 
92  class LogicalOr : public Elementwise::BinaryFunction<Real> {
93  public:
94  Real apply( const Real &x, const Real &y ) const {
95  return (x==0.0 && y==0.0) ? 0.0 : 1.0;
96  }
97  };
98 
99  class Product : public Elementwise::BinaryFunction<Real> {
100  public:
101  Real apply( const Real &x, const Real &y ) const { return x*y; }
102  } product;
103 
104 
105 public:
106 
107  virtual ~BoundConstraint() {}
108 
109  BoundConstraint(void) : activated_(true) {}
110 
115  BoundConstraint(const Teuchos::RCP<Vector<Real> > &x_lo,
116  const Teuchos::RCP<Vector<Real> > &x_up,
117  Real scale = 1.0) :
118  x_lo_(x_lo), x_up_(x_up),scale_(scale),activated_(true) {
119 
120  // Compute difference between upper and lower bounds
121  Teuchos::RCP<Vector<Real> > diff = x_up_->clone();
122  diff->set(*x_up_);
123  diff->axpy(-1.0,*x_lo_);
124 
125  // Compute minimum difference
126  min_diff_ = diff->reduce(minimum_);
127  min_diff_ *= 0.5;
128 
129  }
130 
138  virtual void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {}
139 
148  virtual void project( Vector<Real> &x ) {
149 
150  struct Lesser : public Elementwise::BinaryFunction<Real> {
151  Real apply(const Real &x, const Real &y) const { return x<y ? x : y; }
152  } lesser;
153 
154  struct Greater : public Elementwise::BinaryFunction<Real> {
155  Real apply(const Real &x, const Real &y) const { return x>y ? x : y; }
156  } greater;
157 
158  x.applyBinary(lesser, *x_up_); // Set x to the elementwise minimum of x and x_up_
159  x.applyBinary(greater,*x_lo_); // Set x to the elementwise minimum of x and x_lo_
160 
161  }
162 
174  virtual void pruneUpperActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
175 
176  Real epsn = std::min(scale_*eps,this->min_diff_);
177 
178  // Find the indices where x - u + epsn >= 0
179 
180  Shift shift(epsn);
181 
182  Teuchos::RCP<Vector<Real> > mask = x.clone();
183  mask->set(x);
184  mask->axpy(-1.0,*x_up_);
185  mask->applyUnary(shift);
186 
187  struct Condition : public Elementwise::UnaryFunction<Real> {
188  Real apply(const Real &x) const {
189  return x>=0 ? 0.0 : 1.0;
190  }
191  } condition;
192 
193  mask->applyUnary(condition); // mask = 0 anywhere x - u + epsn >= 0
194 
195  v.applyBinary(product, *mask); // zeros elements of v where mask=0
196  }
197 
211  virtual void pruneUpperActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
212 
213  Real epsn = std::min(scale_*eps,this->min_diff_);
214 
215  // Find the indices where x - u + epsn >= 0
216 
217  Shift shift(epsn);
218 
219  Teuchos::RCP<Vector<Real> > mask1 = x.clone();
220  mask1->set(x);
221  mask1->axpy(-1.0,*x_up_);
222  mask1->applyUnary(shift);
223 
224  struct Condition1 : public Elementwise::UnaryFunction<Real> {
225  Real apply(const Real &x) const {
226  return x>=0 ? 0.0 : 1.0;
227  }
228  } condition1;
229 
230  mask1->applyUnary(condition1);
231 
232  struct Condition2 : public Elementwise::UnaryFunction<Real> {
233  Real apply(const Real &x) const {
234  return x < 0.0 ? 0.0 : 1.0;
235  }
236  } condition2;
237 
238  Teuchos::RCP<Vector<Real> > mask2 = g.clone();
239  mask2->set(g);
240 
241  mask2->applyUnary(condition2);
242 
243  LogicalOr logicalOr;
244 
245  mask1->applyBinary(logicalOr,*mask2);
246 
247  v.applyBinary(product,*mask1);
248 
249  }
250 
262  virtual void pruneLowerActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
263 
264  Real epsn = std::min(scale_*eps,this->min_diff_);
265 
266  // Find the indices where -x + l + epsn >= 0
267 
268  Shift shift(epsn);
269 
270  Teuchos::RCP<Vector<Real> > mask = x_lo_->clone();
271  mask->set(*x_lo_);
272  mask->axpy(-1.0,x);
273  mask->applyUnary(shift);
274 
275  struct Condition: public Elementwise::UnaryFunction<Real> {
276  Real apply(const Real &x) const {
277  return x>=0 ? 0.0 : 1.0;
278  }
279  } condition;
280 
281  mask->applyUnary(condition); // mask = 0 anywhere -x + l + epsn >= 0
282 
283  v.applyBinary(product, *mask); // zeros elements of v where mask=0
284 
285  }
286 
300  virtual void pruneLowerActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
301 
302  Real epsn = std::min(scale_*eps,this->min_diff_);
303 
304  // Find the indices where -x + l + epsn >= 0
305 
306  Shift shift(epsn);
307 
308  Teuchos::RCP<Vector<Real> > mask1 = x_lo_->clone();
309  mask1->set(*x_lo_);
310  mask1->axpy(-1.0,x);
311  mask1->applyUnary(shift);
312 
313  struct Condition1: public Elementwise::UnaryFunction<Real> {
314  Real apply(const Real &x) const {
315  return x>=0 ? 0.0 : 1.0;
316  }
317  } condition1;
318 
319  mask1->applyUnary(condition1); // mask = 0 anywhere -x + l + epsn >= 0
320 
321  struct Condition2 : public Elementwise::UnaryFunction<Real> {
322  Real apply(const Real &x) const {
323  return x > 0.0 ? 0.0 : 1.0;
324  }
325  } condition2;
326 
327  Teuchos::RCP<Vector<Real> > mask2 = g.clone();
328  mask2->set(g);
329 
330  mask2->applyUnary(condition2);
331 
332  LogicalOr logicalOr;
333 
334  mask1->applyBinary(logicalOr,*mask2);
335 
336  v.applyBinary(product,*mask1);
337 
338  }
339 
345  virtual void setVectorToUpperBound( Vector<Real> &u ) {
346  u.set(*x_up_);
347  }
348 
354  virtual void setVectorToLowerBound( Vector<Real> &l ) {
355  l.set(*x_lo_);
356  }
357 
369  virtual void pruneActive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
370  this->pruneUpperActive(v,x,eps);
371  this->pruneLowerActive(v,x,eps);
372  }
373 
386  virtual void pruneActive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
387  this->pruneUpperActive(v,g,x,eps);
388  this->pruneLowerActive(v,g,x,eps);
389  }
390 
396  virtual bool isFeasible( const Vector<Real> &v ) {
397  if ( this->activated_ ) {
398  Teuchos::RCP<Vector<Real> > s = v.clone();
399  s->set(*x_up_);
400 
401  s->axpy(-1.0,v); // u-v
402 
403  Real uminusv = s->reduce(minimum_);
404 
405  s->set(v);
406  s->axpy(-1.0,*x_lo_);
407 
408  Real vminusl = s->reduce(minimum_);
409 
410  if( (uminusv<0) || (vminusl<0) ) {
411  return false;
412  }
413  else {
414  return true;
415  }
416 
417  }
418  else {
419  return true;
420  }
421  }
422 
427  void activate(void) { this->activated_ = true; }
428 
433  void deactivate(void) { this->activated_ = false; }
434 
439  bool isActivated(void) { return this->activated_; }
440 
448  void pruneInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
449  Teuchos::RCP<Vector<Real> > tmp = v.clone();
450  tmp->set(v);
451  this->pruneActive(*tmp,x,eps);
452  v.axpy(-1.0,*tmp);
453  }
454  void pruneLowerInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
455  Teuchos::RCP<Vector<Real> > tmp = v.clone();
456  tmp->set(v);
457  this->pruneLowerActive(*tmp,x,eps);
458  v.axpy(-1.0,*tmp);
459  }
460  void pruneUpperInactive( Vector<Real> &v, const Vector<Real> &x, Real eps = 0.0 ) {
461  Teuchos::RCP<Vector<Real> > tmp = v.clone();
462  tmp->set(v);
463  this->pruneUpperActive(*tmp,x,eps);
464  v.axpy(-1.0,*tmp);
465  }
466 
467 
476  void pruneInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
477  Teuchos::RCP<Vector<Real> > tmp = v.clone();
478  tmp->set(v);
479  this->pruneActive(*tmp,g,x,eps);
480  v.axpy(-1.0,*tmp);
481  }
482  void pruneLowerInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
483  Teuchos::RCP<Vector<Real> > tmp = v.clone();
484  tmp->set(v);
485  this->pruneLowerActive(*tmp,g,x,eps);
486  v.axpy(-1.0,*tmp);
487  }
488  void pruneUpperInactive( Vector<Real> &v, const Vector<Real> &g, const Vector<Real> &x, Real eps = 0.0 ) {
489  Teuchos::RCP<Vector<Real> > tmp = v.clone();
490  tmp->set(v);
491  this->pruneUpperActive(*tmp,g,x,eps);
492  v.axpy(-1.0,*tmp);
493  }
494 
502  Teuchos::RCP<Vector<Real> > tmp = g.clone();
503  tmp->set(g);
504  this->pruneActive(g,*tmp,x);
505  }
506 
514  v.plus(x);
515  this->project(v);
516  v.axpy(-1.0,x);
517  }
518 
519 }; // class BoundConstraint
520 
521 } // namespace ROL
522 
523 #endif
bool activated_
Flag that determines whether or not the constraints are being used.
Elementwise::ReductionMin< Real > minimum_
Real apply(const Real &x) 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.
void pruneLowerInactive(Vector< Real > &v, const Vector< Real > &g, const Vector< Real > &x, Real eps=0.0)
Real apply(const Real &x, const Real &y) const
virtual void applyBinary(const Elementwise::BinaryFunction< Real > &f, const Vector &x)
Definition: ROL_Vector.hpp:222
Contains definitions of custom data types in ROL.
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)
virtual void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update bounds.
Teuchos::RCP< Vector< Real > > x_lo_
virtual Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
Real apply(const Real &x, const Real &y) const
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.
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.
Provides the interface to apply upper and lower bound constraints.
void computeProjectedGradient(Vector< Real > &g, const Vector< Real > &x)
Compute projected gradient.
BoundConstraint(const Teuchos::RCP< Vector< Real > > &x_lo, const Teuchos::RCP< Vector< Real > > &x_up, Real scale=1.0)
Default constructor.
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)
void deactivate(void)
Turn off bounds.
Teuchos::RCP< Vector< Real > > x_up_
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.
virtual void project(Vector< Real > &x)
Project optimization variables onto the bounds.
ROL::BoundConstraint::Product product