ROL
ROL_ConstraintAssembler_Def.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_ASSEMBLER_DEF_H
45 #define ROL_CONSTRAINT_ASSEMBLER_DEF_H
46 
47 namespace ROL {
48 
49 template<typename Real>
51  const Ptr<BoundConstraint<Real>> &cbnd,
52  const Ptr<Vector<Real>> &s,
53  const Ptr<Vector<Real>> &x) const {
54  // Set slack variable to s = proj(c(x))
55  Real tol = std::sqrt(ROL_EPSILON<Real>());
56  con->value(*s,*x,tol);
57  cbnd->project(*s);
58 }
59 
60 template<typename Real>
61 void ConstraintAssembler<Real>::initialize( const std::unordered_map<std::string,ConstraintData<Real>> &input_con,
62  const Ptr<Vector<Real>> &xprim,
63  const Ptr<Vector<Real>> &xdual,
64  const Ptr<BoundConstraint<Real>> &bnd) {
65  // If bnd is null, then make a null BoundConstraint
66  Ptr<BoundConstraint<Real>> bnd0;
67  if ( bnd == nullPtr ) {
68  bnd0 = makePtr<BoundConstraint<Real>>(*xprim);
69  bnd0->deactivate();
70  }
71  else {
72  bnd0 = bnd;
73  }
74  // Build slack variables
75  psvec_.clear(); psvec_.push_back(xprim);
76  dsvec_.clear(); dsvec_.push_back(xdual);
77  sbnd_.clear(); sbnd_.push_back(bnd0);
78  cvec_.clear(); lvec_.clear(); rvec_.clear();
79  isInequality_.clear();
80  int cnt = 1, cnt_con = 0;
81  isNull_ = true;
82  hasInequality_ = false;
83  for (auto it = input_con.begin(); it != input_con.end(); ++it) {
84  Ptr<Constraint<Real>> con = it->second.constraint;
85  Ptr<Vector<Real>> l = it->second.multiplier;
86  Ptr<Vector<Real>> r = it->second.residual;
87  Ptr<BoundConstraint<Real>> cbnd = it->second.bounds;
88  if (con != nullPtr) {
89  if ( con->isActivated() ) {
90  // Set default type to equality
91  isInequality_.push_back(false);
92  // Fill constraint and multiplier vectors
93  cvec_.push_back(con);
94  lvec_.push_back(l);
95  rvec_.push_back(r);
96  if (cbnd != nullPtr) {
97  if ( cbnd->isActivated() ) {
98  // Set type to inequality
99  isInequality_.back() = true;
100  // Create slack variables
101  psvec_.push_back(r->clone());
102  dsvec_.push_back(l->clone());
103  initializeSlackVariable(con,cbnd,psvec_[cnt],xprim);
104  // Create slack bound
105  sbnd_.push_back(cbnd);
106  // Update inequality constraint counter
107  cnt++;
108  hasInequality_ = true;
109  }
110  }
111  cnt_con++;
112  isNull_ = false;
113  }
114  }
115  }
116  // Create partitioned constraint and multiplier vector
117  if ( !isNull_ ) {
118  if ( cnt_con > 1 || hasInequality_ ) {
119  con_ = makePtr<Constraint_Partitioned<Real>>(cvec_,isInequality_);
120  mul_ = makePtr<PartitionedVector<Real>>(lvec_);
121  res_ = makePtr<PartitionedVector<Real>>(rvec_);
122  }
123  else {
124  con_ = cvec_[0];
125  mul_ = lvec_[0];
126  res_ = rvec_[0];
127  }
128  }
129  else {
130  con_ = nullPtr;
131  mul_ = nullPtr;
132  res_ = nullPtr;
133  }
134  // Create partitioned optimization vector and bound constraint
135  if ( hasInequality_ ) {
136  xprim_ = makePtr<PartitionedVector<Real>>(psvec_);
137  xdual_ = makePtr<PartitionedVector<Real>>(dsvec_);
138  bnd_ = makePtr<BoundConstraint_Partitioned<Real>>(sbnd_,psvec_);
139  }
140  else {
141  xprim_ = xprim;
142  xdual_ = xdual;
143  bnd_ = bnd0;
144  }
145 }
146 
147 template<typename Real>
148 void ConstraintAssembler<Real>::initialize( const std::unordered_map<std::string,ConstraintData<Real>> &input_con,
149  const std::unordered_map<std::string,ConstraintData<Real>> &input_lcon,
150  const Ptr<Vector<Real>> &xprim,
151  const Ptr<Vector<Real>> &xdual,
152  const Ptr<BoundConstraint<Real>> &bnd) {
153  // If bnd is null, then make a null BoundConstraint
154  Ptr<BoundConstraint<Real>> bnd0;
155  if ( bnd == nullPtr ) {
156  bnd0 = makePtr<BoundConstraint<Real>>(*xprim);
157  bnd0->deactivate();
158  }
159  else {
160  bnd0 = bnd;
161  }
162  // Build slack variables
163  psvec_.clear(); psvec_.push_back(xprim);
164  dsvec_.clear(); dsvec_.push_back(xdual);
165  sbnd_.clear(); sbnd_.push_back(bnd0);
166  cvec_.clear(); lvec_.clear(); rvec_.clear();
167  lcvec_.clear(); llvec_.clear(); lrvec_.clear();
168  isInequality_.clear(); isLinearInequality_.clear();
169  int cnt = 1, cnt_con = 0, cnt_lcon = 0;
170  isNull_ = true;
171  hasInequality_ = false;
172  for (auto it = input_con.begin(); it != input_con.end(); ++it) {
173  Ptr<Constraint<Real>> con = it->second.constraint;
174  Ptr<Vector<Real>> l = it->second.multiplier;
175  Ptr<Vector<Real>> r = it->second.residual;
176  Ptr<BoundConstraint<Real>> cbnd = it->second.bounds;
177  if (con != nullPtr) {
178  if ( con->isActivated() ) {
179  // Set default type to equality
180  isInequality_.push_back(false);
181  // Fill constraint and multiplier vectors
182  cvec_.push_back(con);
183  lvec_.push_back(l);
184  rvec_.push_back(r);
185  if (cbnd != nullPtr) {
186  if ( cbnd->isActivated() ) {
187  // Set type to inequality
188  isInequality_.back() = true;
189  // Create slack variables
190  psvec_.push_back(r->clone());
191  dsvec_.push_back(l->clone());
192  initializeSlackVariable(con,cbnd,psvec_[cnt],xprim);
193  // Create slack bound
194  sbnd_.push_back(cbnd);
195  // Update inequality constraint counter
196  cnt++;
197  hasInequality_ = true;
198  }
199  }
200  cnt_con++;
201  isNull_ = false;
202  }
203  }
204  }
205  for (auto it = input_lcon.begin(); it != input_lcon.end(); ++it) {
206  Ptr<Constraint<Real>> con = it->second.constraint;
207  Ptr<Vector<Real>> l = it->second.multiplier;
208  Ptr<Vector<Real>> r = it->second.residual;
209  Ptr<BoundConstraint<Real>> cbnd = it->second.bounds;
210  if (con != nullPtr) {
211  if ( con->isActivated() ) {
212  // Set default type to equality
213  isLinearInequality_.push_back(false);
214  // Fill constraint and multiplier vectors
215  lcvec_.push_back(con);
216  llvec_.push_back(l);
217  lrvec_.push_back(r);
218  if (cbnd != nullPtr) {
219  if ( cbnd->isActivated() ) {
220  // Set type to inequality
221  isLinearInequality_.back() = true;
222  // Create slack variables
223  psvec_.push_back(r->clone());
224  dsvec_.push_back(l->clone());
225  initializeSlackVariable(con,cbnd,psvec_[cnt],xprim);
226  // Create slack bound
227  sbnd_.push_back(cbnd);
228  // Update inequality constraint counter
229  cnt++;
230  hasInequality_ = true;
231  }
232  }
233  cnt_lcon++;
234  isNull_ = false;
235  }
236  }
237  }
238  // Create partitioned constraint and multiplier vector
239  if ( !isNull_ ) {
240  if ( cnt_con > 1 || hasInequality_ ) {
241  con_ = makePtr<Constraint_Partitioned<Real>>(cvec_,isInequality_);
242  mul_ = makePtr<PartitionedVector<Real>>(lvec_);
243  res_ = makePtr<PartitionedVector<Real>>(rvec_);
244  }
245  else {
246  con_ = cvec_[0];
247  mul_ = lvec_[0];
248  res_ = rvec_[0];
249  }
250  if ( cnt_lcon > 1 || hasInequality_ ) {
251  linear_con_ = makePtr<Constraint_Partitioned<Real>>(lcvec_,isLinearInequality_,cnt_con);
252  linear_mul_ = makePtr<PartitionedVector<Real>>(llvec_);
253  linear_res_ = makePtr<PartitionedVector<Real>>(lrvec_);
254  }
255  else {
256  linear_con_ = lcvec_[0];
257  linear_mul_ = llvec_[0];
258  linear_res_ = lrvec_[0];
259  }
260  }
261  else {
262  con_ = nullPtr;
263  mul_ = nullPtr;
264  res_ = nullPtr;
265  linear_con_ = nullPtr;
266  linear_mul_ = nullPtr;
267  linear_res_ = nullPtr;
268  }
269  // Create partitioned optimization vector and bound constraint
270  if ( hasInequality_ ) {
271  xprim_ = makePtr<PartitionedVector<Real>>(psvec_);
272  xdual_ = makePtr<PartitionedVector<Real>>(dsvec_);
273  bnd_ = makePtr<BoundConstraint_Partitioned<Real>>(sbnd_,psvec_);
274  }
275  else {
276  xprim_ = xprim;
277  xdual_ = xdual;
278  bnd_ = bnd0;
279  }
280 }
281 
282 template<typename Real>
283 ConstraintAssembler<Real>::ConstraintAssembler( const std::unordered_map<std::string,ConstraintData<Real>> &con,
284  const Ptr<Vector<Real>> &xprim,
285  const Ptr<Vector<Real>> &xdual,
286  const Ptr<BoundConstraint<Real>> &bnd)
287  : isNull_(true), hasInequality_(false) {
288  initialize(con,xprim,xdual,bnd);
289 }
290 
291 template<typename Real>
292 ConstraintAssembler<Real>::ConstraintAssembler( const std::unordered_map<std::string,ConstraintData<Real>> &con,
293  const std::unordered_map<std::string,ConstraintData<Real>> &linear_con,
294  const Ptr<Vector<Real>> &xprim,
295  const Ptr<Vector<Real>> &xdual,
296  const Ptr<BoundConstraint<Real>> &bnd)
297  : isNull_(true), hasInequality_(false) {
298  initialize(con,linear_con,xprim,xdual,bnd);
299 }
300 
301 template<typename Real>
302 const Ptr<Constraint<Real>>& ConstraintAssembler<Real>::getConstraint() const {
303  return con_;
304 }
305 
306 template<typename Real>
307 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getMultiplier() const {
308  return mul_;
309 }
310 
311 template<typename Real>
312 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getResidual() const {
313  return res_;
314 }
315 
316 template<typename Real>
317 const Ptr<Constraint<Real>>& ConstraintAssembler<Real>::getLinearConstraint() const {
318  return linear_con_;
319 }
320 
321 template<typename Real>
322 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getLinearMultiplier() const {
323  return linear_mul_;
324 }
325 
326 template<typename Real>
327 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getLinearResidual() const {
328  return linear_res_;
329 }
330 
331 template<typename Real>
332 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getOptVector() const {
333  return xprim_;
334 }
335 
336 template<typename Real>
337 const Ptr<Vector<Real>>& ConstraintAssembler<Real>::getDualOptVector() const {
338  return xdual_;
339 }
340 
341 template<typename Real>
342 const Ptr<BoundConstraint<Real>>& ConstraintAssembler<Real>::getBoundConstraint() const {
343  return bnd_;
344 }
345 
346 template<typename Real>
348  return isNull_;
349 }
350 
351 template<typename Real>
353  return hasInequality_;
354 }
355 
356 template<typename Real>
358  if (hasInequality_) {
359  int size = static_cast<int>(cvec_.size());
360  int cnt = 1;
361  for (int i = 0; i < size; ++i) {
362  if (isInequality_[i]) {
363  // Reset slack variables
364  initializeSlackVariable(cvec_[i],sbnd_[cnt],psvec_[cnt],psvec_[0]);
365  cnt++;
366  }
367  }
368  size = static_cast<int>(lcvec_.size());
369  for (int i = 0; i < size; ++i) {
370  if (isLinearInequality_[i]) {
371  // Reset slack variables
372  initializeSlackVariable(lcvec_[i],sbnd_[cnt],psvec_[cnt],psvec_[0]);
373  cnt++;
374  }
375  }
376  }
377 }
378 
379 } // namespace ROL
380 
381 #endif
const Ptr< BoundConstraint< Real > > & getBoundConstraint() const
const Ptr< Constraint< Real > > & getConstraint() const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
const Ptr< Vector< Real > > & getLinearResidual() const
void initializeSlackVariable(const Ptr< Constraint< Real >> &con, const Ptr< BoundConstraint< Real >> &cbnd, const Ptr< Vector< Real >> &s, const Ptr< Vector< Real >> &x) const
ConstraintAssembler(const std::unordered_map< std::string, ConstraintData< Real >> &con, const Ptr< Vector< Real >> &xprim, const Ptr< Vector< Real >> &xdual, const Ptr< BoundConstraint< Real >> &bnd=nullPtr)
const Ptr< Vector< Real > > & getMultiplier() const
Provides the interface to apply upper and lower bound constraints.
const Ptr< Vector< Real > > & getDualOptVector() const
void initialize(const std::unordered_map< std::string, ConstraintData< Real >> &input_con, const Ptr< Vector< Real >> &xprim, const Ptr< Vector< Real >> &xdual, const Ptr< BoundConstraint< Real >> &bnd)
const Ptr< Vector< Real > > & getOptVector() const
const Ptr< Constraint< Real > > & getLinearConstraint() const
const Ptr< Vector< Real > > & getLinearMultiplier() const
const Ptr< Vector< Real > > & getResidual() const
Defines the general constraint operator interface.