ROL
ROL_ConstraintManager.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_CONSTRAINT_MANAGER_H
45 #define ROL_CONSTRAINT_MANAGER_H
46 
47 #include "ROL_Constraint.hpp"
50 
58 namespace ROL {
59 
60 template <class Real>
62 private:
63  ROL::Ptr<Constraint<Real> > con_;
64  ROL::Ptr<Vector<Real> > l_;
65  ROL::Ptr<Vector<Real> > x_;
66  ROL::Ptr<BoundConstraint<Real> > bnd_;
67 
68  std::vector<ROL::Ptr<Constraint<Real> > > cvec_;
69  std::vector<ROL::Ptr<Vector<Real> > > lvec_;
70  std::vector<ROL::Ptr<Vector<Real> > > svec_;
71  std::vector<ROL::Ptr<BoundConstraint<Real> > > sbnd_;
72 
73  std::vector<bool> isInequality_;
74 
75  bool isNull_;
77 
78  void initializeSlackVariable(const ROL::Ptr<Constraint<Real> > &con,
79  const ROL::Ptr<BoundConstraint<Real> > &cbnd,
80  const ROL::Ptr<Vector<Real> > &s,
81  const ROL::Ptr<Vector<Real> > &x) const {
82  // Set slack variable to s = proj(c(x))
83  Real tol = std::sqrt(ROL_EPSILON<Real>());
84  con->value(*s,*x,tol);
85  cbnd->project(*s);
86  }
87 
88  void initialize(const std::vector<ROL::Ptr<Constraint<Real> > > &cvec,
89  const std::vector<ROL::Ptr<Vector<Real> > > &lvec,
90  const std::vector<ROL::Ptr<BoundConstraint<Real> > > &bvec,
91  const ROL::Ptr<Vector<Real> > &x,
92  const ROL::Ptr<BoundConstraint<Real> > &bnd) {
93  // Check size of multiplier vector and constraint vector
94  int size = static_cast<int>(cvec.size());
95  if ( size != static_cast<int>(lvec.size()) ) {
96  throw Exception::NotImplemented(">>> ROL::ConstraintManager: Constraint and multiplier vectors are different sizes!");
97  }
98  if ( size != static_cast<int>(bvec.size()) ) {
99  throw Exception::NotImplemented(">>> ROL::ConstraintManager: Constraint and BoundConstraint vectors are different sizes!");
100  }
101  // If bnd is null, then make a null BoundConstraint
102  ROL::Ptr<BoundConstraint<Real> > bnd0;
103  if ( bnd == ROL::nullPtr ) {
104  bnd0 = ROL::makePtr<BoundConstraint<Real>>(*x);
105  bnd0->deactivate();
106  }
107  else {
108  bnd0 = bnd;
109  }
110  // Build slack variables
111  svec_.clear(); svec_.push_back(x);
112  sbnd_.clear(); sbnd_.push_back(bnd0);
113  cvec_.clear(); lvec_.clear(); isInequality_.clear();
114  int cnt = 1, cnt_con = 0;
115  isNull_ = true;
116  hasInequality_ = false;
117  for (int i = 0; i < size; ++i) {
118  ROL::Ptr<Constraint<Real> > con = cvec[i];
119  ROL::Ptr<Vector<Real> > l = lvec[i];
120  ROL::Ptr<BoundConstraint<Real> > cbnd = bvec[i];
121  if (con != ROL::nullPtr) {
122  if ( con->isActivated() ) {
123  // Set default type to equality
124  isInequality_.push_back(false);
125  // Fill constraint and multiplier vectors
126  cvec_.push_back(con);
127  lvec_.push_back(l);
128  if (cbnd != ROL::nullPtr) {
129  if ( cbnd->isActivated() ) {
130  // Set type to inequality
131  isInequality_.back() = true;
132  // Create slack variables
133  svec_.push_back(l->dual().clone());
134  initializeSlackVariable(con,cbnd,svec_[cnt],x);
135  // Create slack bound
136  sbnd_.push_back(cbnd);
137  // Update inequality constraint counter
138  cnt++;
139  hasInequality_ = true;
140  }
141  }
142  cnt_con++;
143  isNull_ = false;
144  }
145  }
146  }
147  // Create partitioned constraint and multiplier vector
148  if ( !isNull_ ) {
149  if ( cnt_con > 1 || hasInequality_ ) {
150  con_ = ROL::makePtr<Constraint_Partitioned<Real>>(cvec_,isInequality_);
151  l_ = ROL::makePtr<PartitionedVector<Real>>(lvec_);
152  }
153  else {
154  con_ = cvec_[0];
155  l_ = lvec_[0];
156  }
157  }
158  else {
159  con_ = ROL::nullPtr;
160  l_ = ROL::nullPtr;
161  }
162  // Create partitioned optimization vector and bound constraint
163  if ( hasInequality_ ) {
164  x_ = ROL::makePtr<PartitionedVector<Real>>(svec_);
165  bnd_ = ROL::makePtr<BoundConstraint_Partitioned<Real>>(sbnd_,svec_);
166  }
167  else {
168  x_ = x;
169  bnd_ = bnd0;
170  }
171  }
172 
173 public:
174  virtual ~ConstraintManager(void) {}
175 
176  ConstraintManager(const std::vector<ROL::Ptr<Constraint<Real> > > &cvec,
177  const std::vector<ROL::Ptr<Vector<Real> > > &lvec,
178  const std::vector<ROL::Ptr<BoundConstraint<Real> > > &bvec,
179  const ROL::Ptr<Vector<Real> > &x,
180  const ROL::Ptr<BoundConstraint<Real> > &bnd = ROL::nullPtr)
181  : isNull_(true), hasInequality_(false) {
182  initialize(cvec,lvec,bvec,x,bnd);
183  }
184 
185  ConstraintManager(const std::vector<ROL::Ptr<Constraint<Real> > > &cvec,
186  const std::vector<ROL::Ptr<Vector<Real> > > &lvec,
187  const ROL::Ptr<Vector<Real> > &x,
188  const ROL::Ptr<BoundConstraint<Real> > &bnd = ROL::nullPtr)
189  : isNull_(true), hasInequality_(false) {
190  std::vector<ROL::Ptr<BoundConstraint<Real> > > bvec(cvec.size(),ROL::nullPtr);
191  initialize(cvec,lvec,bvec,x,bnd);
192  }
193 
194  ConstraintManager(const ROL::Ptr<Constraint<Real> > &con,
195  const ROL::Ptr<Vector<Real> > &l,
196  const ROL::Ptr<BoundConstraint<Real> > &cbnd,
197  const ROL::Ptr<Vector<Real> > &x,
198  const ROL::Ptr<BoundConstraint<Real> > &bnd = ROL::nullPtr)
199  : isNull_(true), hasInequality_(false) {
200  std::vector<ROL::Ptr<Constraint<Real> > > cvec(1,con);
201  std::vector<ROL::Ptr<Vector<Real> > > lvec(1,l);
202  std::vector<ROL::Ptr<BoundConstraint<Real> > > bvec(1,cbnd);
203  initialize(cvec,lvec,bvec,x,bnd);
204  }
205 
206  ConstraintManager(const ROL::Ptr<Constraint<Real> > &con,
207  const ROL::Ptr<Vector<Real> > &l,
208  const ROL::Ptr<Vector<Real> > &x,
209  const ROL::Ptr<BoundConstraint<Real> > &bnd = ROL::nullPtr)
210  : isNull_(true), hasInequality_(false) {
211  std::vector<ROL::Ptr<Constraint<Real> > > cvec(1,con);
212  std::vector<ROL::Ptr<Vector<Real> > > lvec(1,l);
213  std::vector<ROL::Ptr<BoundConstraint<Real> > > bvec(1,ROL::nullPtr);
214  initialize(cvec,lvec,bvec,x,bnd);
215  }
216 
217  const ROL::Ptr<Constraint<Real> > getConstraint(void) const {
218  return con_;
219  }
220 
221  const ROL::Ptr<Vector<Real> > getMultiplier(void) const {
222  return l_;
223  }
224 
225  const ROL::Ptr<Vector<Real> > getOptVector(void) const {
226  return x_;
227  }
228 
229  const ROL::Ptr<BoundConstraint<Real> > getBoundConstraint(void) const {
230  return bnd_;
231  }
232 
233  bool isNull(void) const {
234  return isNull_;
235  }
236 
237  bool hasInequality(void) const {
238  return hasInequality_;
239  }
240 
241  void resetSlackVariables(void) {
242  if (hasInequality_) {
243  int size = static_cast<int>(cvec_.size());
244  int cnt = 1;
245  for (int i = 0; i < size; ++i) {
246  if (isInequality_[i]) {
247  // Reset slack variables
248  initializeSlackVariable(cvec_[i],sbnd_[cnt],svec_[cnt],svec_[0]);
249  cnt++;
250  }
251  }
252  }
253  }
254 
255 }; // class ConstraintManager
256 
257 } // namespace ROL
258 
259 #endif
ConstraintManager(const std::vector< ROL::Ptr< Constraint< Real > > > &cvec, const std::vector< ROL::Ptr< Vector< Real > > > &lvec, const ROL::Ptr< Vector< Real > > &x, const ROL::Ptr< BoundConstraint< Real > > &bnd=ROL::nullPtr)
std::vector< ROL::Ptr< Vector< Real > > > lvec_
ROL::Ptr< Vector< Real > > l_
std::vector< ROL::Ptr< Vector< Real > > > svec_
void initializeSlackVariable(const ROL::Ptr< Constraint< Real > > &con, const ROL::Ptr< BoundConstraint< Real > > &cbnd, const ROL::Ptr< Vector< Real > > &s, const ROL::Ptr< Vector< Real > > &x) const
const ROL::Ptr< Vector< Real > > getMultiplier(void) const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
const ROL::Ptr< Vector< Real > > getOptVector(void) const
const ROL::Ptr< Constraint< Real > > getConstraint(void) const
ROL::Ptr< BoundConstraint< Real > > bnd_
ROL::Ptr< Constraint< Real > > con_
ConstraintManager(const ROL::Ptr< Constraint< Real > > &con, const ROL::Ptr< Vector< Real > > &l, const ROL::Ptr< Vector< Real > > &x, const ROL::Ptr< BoundConstraint< Real > > &bnd=ROL::nullPtr)
Provides a wrapper for multiple constraints.
void initialize(const std::vector< ROL::Ptr< Constraint< Real > > > &cvec, const std::vector< ROL::Ptr< Vector< Real > > > &lvec, const std::vector< ROL::Ptr< BoundConstraint< Real > > > &bvec, const ROL::Ptr< Vector< Real > > &x, const ROL::Ptr< BoundConstraint< Real > > &bnd)
const ROL::Ptr< BoundConstraint< Real > > getBoundConstraint(void) const
Provides the interface to apply upper and lower bound constraints.
std::vector< ROL::Ptr< Constraint< Real > > > cvec_
std::vector< ROL::Ptr< BoundConstraint< Real > > > sbnd_
ConstraintManager(const ROL::Ptr< Constraint< Real > > &con, const ROL::Ptr< Vector< Real > > &l, const ROL::Ptr< BoundConstraint< Real > > &cbnd, const ROL::Ptr< Vector< Real > > &x, const ROL::Ptr< BoundConstraint< Real > > &bnd=ROL::nullPtr)
ConstraintManager(const std::vector< ROL::Ptr< Constraint< Real > > > &cvec, const std::vector< ROL::Ptr< Vector< Real > > > &lvec, const std::vector< ROL::Ptr< BoundConstraint< Real > > > &bvec, const ROL::Ptr< Vector< Real > > &x, const ROL::Ptr< BoundConstraint< Real > > &bnd=ROL::nullPtr)
Defines the general constraint operator interface.
std::vector< bool > isInequality_
ROL::Ptr< Vector< Real > > x_