ROL
ROL_DykstraProjection_Def.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_DYKSTRAPROJECTION_DEF_H
11 #define ROL_DYKSTRAPROJECTION_DEF_H
12 
13 namespace ROL {
14 
15 template<typename Real>
17  const Vector<Real> &xdual,
18  const Ptr<BoundConstraint<Real>> &bnd,
19  const Ptr<Constraint<Real>> &con,
20  const Vector<Real> &mul,
21  const Vector<Real> &res)
22  : PolyhedralProjection<Real>(xprim,xdual,bnd,con,mul,res),
23  DEFAULT_atol_ (std::sqrt(ROL_EPSILON<Real>()*std::sqrt(ROL_EPSILON<Real>()))),
24  DEFAULT_rtol_ (std::sqrt(ROL_EPSILON<Real>())),
25  DEFAULT_maxit_ (10000),
26  DEFAULT_verbosity_ (0),
27  atol_ (DEFAULT_atol_),
28  rtol_ (DEFAULT_rtol_),
29  maxit_ (DEFAULT_maxit_),
30  verbosity_ (DEFAULT_verbosity_) {
31  dim_ = mul.dimension();
32  tmp_ = xprim.clone();
33  y_ = xprim.clone();
34  q_ = xprim.clone();
35  p_ = xprim.clone();
36  z_ = xdual.clone();
37  if (dim_ == 1) {
38  Real tol(std::sqrt(ROL_EPSILON<Real>()));
39  xprim_->zero();
40  con_->update(*xprim_,UpdateType::Temp);
41  con_->value(*res_,*xprim_,tol);
42  b_ = res_->dot(*res_->basis(0));
43  mul_->setScalar(static_cast<Real>(1));
44  con_->applyAdjointJacobian(*z_,*mul_,xprim,tol);
45  xprim_->set(z_->dual());
46  cdot_ = xprim_->dot(*xprim_);
47  }
48  z_->zero();
49 }
50 
51 template<typename Real>
53  const Vector<Real> &xdual,
54  const Ptr<BoundConstraint<Real>> &bnd,
55  const Ptr<Constraint<Real>> &con,
56  const Vector<Real> &mul,
57  const Vector<Real> &res,
58  ParameterList &list)
59  : DykstraProjection<Real>(xprim,xdual,bnd,con,mul,res) {
60  atol_ = list.sublist("General").sublist("Polyhedral Projection").get("Absolute Tolerance", DEFAULT_atol_);
61  rtol_ = list.sublist("General").sublist("Polyhedral Projection").get("Relative Tolerance", DEFAULT_rtol_);
62  maxit_ = list.sublist("General").sublist("Polyhedral Projection").get("Iteration Limit", DEFAULT_maxit_);
63  verbosity_ = list.sublist("General").get("Output Level", DEFAULT_verbosity_);
64 }
65 
66 template<typename Real>
67 void DykstraProjection<Real>::project(Vector<Real> &x, std::ostream &stream) {
68  if (con_ == nullPtr) {
69  bnd_->project(x);
70  }
71  else {
72  project_Dykstra(x, stream);
73  }
74 }
75 
76 template<typename Real>
78  return xprim_->dot(x) + b_;
79 }
80 
81 template<typename Real>
83  Real tol(std::sqrt(ROL_EPSILON<Real>()));
84  con_->update(y,UpdateType::Temp);
85  con_->value(r,y,tol);
86 }
87 
88 template<typename Real>
90  x.set(y);
91  bnd_->project(x);
92 }
93 
94 template<typename Real>
96  if (dim_ == 1) {
97  Real rhs = residual_1d(y);
98  Real lam = -rhs/cdot_;
99  x.set(y);
100  x.axpy(lam,*xprim_);
101  }
102  else {
103  Real tol = std::sqrt(ROL_EPSILON<Real>());
104  residual_nd(*res_,y);
105  con_->solveAugmentedSystem(x,*mul_,*z_,*res_,y,tol);
106  x.scale(static_cast<Real>(-1));
107  x.plus(y);
108  }
109 }
110 
111 template<typename Real>
112 void DykstraProjection<Real>::project_Dykstra(Vector<Real> &x, std::ostream &stream) const {
113  const Real one(1), xnorm(x.norm()), ctol(std::min(atol_,rtol_*xnorm));
114  Real norm1(0), norm2(0), rnorm(0);
115  p_->zero(); q_->zero();
116  std::ios_base::fmtflags streamFlags(stream.flags());
117  if (verbosity_ > 2) {
118  stream << std::scientific << std::setprecision(6);
119  stream << std::endl;
120  stream << " Polyhedral Projection using Dykstra's Algorithm" << std::endl;
121  stream << " ";
122  stream << std::setw(6) << std::left << "iter";
123  stream << std::setw(15) << std::left << "con norm";
124  stream << std::setw(15) << std::left << "bnd norm";
125  stream << std::setw(15) << std::left << "error";
126  stream << std::setw(15) << std::left << "tol";
127  stream << std::endl;
128  }
129  for (int cnt=0; cnt < maxit_; ++cnt) {
130  // Constraint projection
131  tmp_->set(x); tmp_->plus(*p_);
132  project_con(*y_,*tmp_);
133  p_->set(*tmp_); p_->axpy(-one,*y_);
134  // compute error between pnew and pold
135  tmp_->set(x); tmp_->axpy(-one,*y_);
136  norm1 = tmp_->norm();
137  // Bounds projection
138  tmp_->set(*y_); tmp_->plus(*q_);
139  project_bnd(x,*tmp_);
140  q_->set(*tmp_); q_->axpy(-one,x);
141  // compute error between qnew and qold
142  tmp_->set(x); tmp_->axpy(-one,*y_);
143  norm2 = tmp_->norm();
144  // stopping condition based on Birgin/Raydan paper
145  // Robust Stopping Criteria for Dykstra's Algorithm
146  // SISC Vol. 26, No. 4, 2005
147  rnorm = std::sqrt(norm1*norm1 + norm2*norm2);
148  if (verbosity_ > 2) {
149  stream << " ";
150  stream << std::setw(6) << std::left << cnt;
151  stream << std::setw(15) << std::left << norm1;
152  stream << std::setw(15) << std::left << norm2;
153  stream << std::setw(15) << std::left << rnorm;
154  stream << std::setw(15) << std::left << ctol;
155  stream << std::endl;
156  }
157  if (rnorm <= ctol) break;
158  }
159  if (verbosity_ > 2) {
160  stream << std::endl;
161  }
162  if (rnorm > ctol) {
163  //throw Exception::NotImplemented(">>> ROL::PolyhedralProjection::project : Projection failed!");
164  stream << ">>> ROL::PolyhedralProjection::project : Projection may be inaccurate! rnorm = ";
165  stream << rnorm << " rtol = " << ctol << std::endl;
166  }
167  stream.flags(streamFlags);
168 }
169 
170 } // namespace ROL
171 
172 #endif
virtual void scale(const Real alpha)=0
Compute where .
Real residual_1d(const Vector< Real > &x) const
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual int dimension() const
Return dimension of the vector space.
Definition: ROL_Vector.hpp:162
Ptr< Vector< Real > > q_
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:119
void project(Vector< Real > &x, std::ostream &stream=std::cout) override
Ptr< Vector< Real > > p_
void residual_nd(Vector< Real > &r, const Vector< Real > &y) const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
Ptr< Vector< Real > > tmp_
void project_con(Vector< Real > &x, const Vector< Real > &y) const
const Ptr< Constraint< Real > > con_
Ptr< Vector< Real > > y_
void project_bnd(Vector< Real > &x, const Vector< Real > &y) const
Ptr< Vector< Real > > z_
Provides the interface to apply upper and lower bound constraints.
DykstraProjection(const Vector< Real > &xprim, const Vector< Real > &xdual, const Ptr< BoundConstraint< Real >> &bnd, const Ptr< Constraint< Real >> &con, const Vector< Real > &mul, const Vector< Real > &res)
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
virtual Real norm() const =0
Returns where .
void project_Dykstra(Vector< Real > &x, std::ostream &stream=std::cout) const
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition: ROL_Types.hpp:57
Defines the general constraint operator interface.