ROL
ROL_DouglasRachfordProjection_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_DOUGLASRACHFORDPROJECTION_DEF_H
11 #define ROL_DOUGLASRACHFORDPROJECTION_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_ (1e-2*std::sqrt(ROL_EPSILON<Real>()*std::sqrt(ROL_EPSILON<Real>()))),
24  DEFAULT_rtol_ (1e-2*std::sqrt(ROL_EPSILON<Real>())),
25  DEFAULT_maxit_ (10000),
26  DEFAULT_verbosity_ (0),
27  DEFAULT_alpha1_ (0.5),
28  DEFAULT_gamma_ (10.0),
29  DEFAULT_t0_ (1.9),
30  atol_ (DEFAULT_atol_),
31  rtol_ (DEFAULT_rtol_),
32  maxit_ (DEFAULT_maxit_),
33  verbosity_ (DEFAULT_verbosity_),
34  alpha1_ (DEFAULT_alpha1_),
35  alpha2_ (1.0-alpha1_),
36  gamma_ (DEFAULT_gamma_),
37  t0_ (DEFAULT_t0_) {
38  dim_ = mul.dimension();
39  tmp_ = xprim.clone();
40  y_ = xprim.clone();
41  q_ = xprim.clone();
42  p_ = xprim.clone();
43  z_ = xdual.clone();
44  if (dim_ == 1) {
45  Real tol(std::sqrt(ROL_EPSILON<Real>()));
46  xprim_->zero();
47  con_->update(*xprim_,UpdateType::Temp);
48  con_->value(*res_,*xprim_,tol);
49  b_ = res_->dot(*res_->basis(0));
50  mul_->setScalar(static_cast<Real>(1));
51  con_->applyAdjointJacobian(*z_,*mul_,xprim,tol);
52  xprim_->set(z_->dual());
53  cdot_ = xprim_->dot(*xprim_);
54  }
55  z_->zero();
56 }
57 
58 template<typename Real>
60  const Vector<Real> &xdual,
61  const Ptr<BoundConstraint<Real>> &bnd,
62  const Ptr<Constraint<Real>> &con,
63  const Vector<Real> &mul,
64  const Vector<Real> &res,
65  ParameterList &list)
66  : DouglasRachfordProjection<Real>(xprim,xdual,bnd,con,mul,res) {
67  atol_ = list.sublist("General").sublist("Polyhedral Projection").get("Absolute Tolerance", DEFAULT_atol_);
68  rtol_ = list.sublist("General").sublist("Polyhedral Projection").get("Relative Tolerance", DEFAULT_rtol_);
69  maxit_ = list.sublist("General").sublist("Polyhedral Projection").get("Iteration Limit", DEFAULT_maxit_);
70  verbosity_ = list.sublist("General").get("Output Level", DEFAULT_verbosity_);
71  alpha1_ = list.sublist("General").sublist("Polyhedral Projection").sublist("Douglas-Rachford").get("Constraint Weight", DEFAULT_alpha1_);
72  alpha2_ = static_cast<Real>(1)-alpha1_;
73  gamma_ = list.sublist("General").sublist("Polyhedral Projection").sublist("Douglas-Rachford").get("Penalty Parameter", DEFAULT_gamma_);
74  t0_ = list.sublist("General").sublist("Polyhedral Projection").sublist("Douglas-Rachford").get("Relaxation Parameter", DEFAULT_t0_);
75 }
76 
77 template<typename Real>
79  if (con_ == nullPtr) {
80  bnd_->project(x);
81  }
82  else {
83  project_DouglasRachford(x, stream);
84  }
85 }
86 
87 template<typename Real>
89  return xprim_->dot(x) + b_;
90 }
91 
92 template<typename Real>
94  Real tol(std::sqrt(ROL_EPSILON<Real>()));
95  con_->update(y,UpdateType::Temp);
96  con_->value(r,y,tol);
97 }
98 
99 template<typename Real>
101  x.set(y);
102  bnd_->project(x);
103 }
104 
105 template<typename Real>
107  if (dim_ == 1) {
108  Real rhs = residual_1d(y);
109  Real lam = -rhs/cdot_;
110  x.set(y);
111  x.axpy(lam,*xprim_);
112  }
113  else {
114  Real tol = std::sqrt(ROL_EPSILON<Real>());
115  residual_nd(*res_,y);
116  con_->solveAugmentedSystem(x,*mul_,*z_,*res_,y,tol);
117  x.scale(static_cast<Real>(-1));
118  x.plus(y);
119  }
120 }
121 
122 template<typename Real>
124  const Real one(1), two(2), xnorm(x.norm()), ctol(std::min(atol_,rtol_*xnorm));
125  Real rnorm(0);
126  p_->zero(); q_->zero(); y_->set(x);
127  std::ios_base::fmtflags streamFlags(stream.flags());
128  if (verbosity_ > 2) {
129  stream << std::scientific << std::setprecision(6);
130  stream << std::endl;
131  stream << " Polyhedral Projection using Douglas Rachford Splitting" << std::endl;
132  stream << " ";
133  stream << std::setw(6) << std::left << "iter";
134  stream << std::setw(15) << std::left << "error";
135  stream << std::setw(15) << std::left << "tol";
136  stream << std::endl;
137  }
138  for (int cnt=0; cnt < maxit_; ++cnt) {
139  // Constraint projection
140  tmp_->set(*y_);
141  tmp_->axpy(alpha1_*gamma_,x);
142  tmp_->scale(one/(alpha1_*gamma_+one));
143  project_con(*p_,*tmp_);
144  // Bounds projection
145  tmp_->zero();
146  tmp_->axpy(two,*p_);
147  tmp_->axpy(-one,*y_);
148  tmp_->axpy(alpha2_*gamma_,x);
149  tmp_->scale(one/(alpha2_*gamma_+one));
150  project_bnd(*q_,*tmp_);
151  // Dual update
152  tmp_->set(*q_);
153  tmp_->axpy(-one,*p_);
154  rnorm = tmp_->norm();
155  if (verbosity_ > 2) {
156  stream << " ";
157  stream << std::setw(6) << std::left << cnt;
158  stream << std::setw(15) << std::left << rnorm;
159  stream << std::setw(15) << std::left << ctol;
160  stream << std::endl;
161  }
162  if (rnorm <= ctol) break;
163  y_->axpy(t0_,*tmp_);
164  }
165  if (verbosity_ > 2) stream << std::endl;
166  x.set(*q_);
167  if (rnorm > ctol) {
168  //throw Exception::NotImplemented(">>> ROL::PolyhedralProjection::project : Projection failed!");
169  stream << ">>> ROL::PolyhedralProjection::project : Projection may be inaccurate! rnorm = ";
170  stream << rnorm << " rtol = " << ctol << std::endl;
171  }
172  stream.flags(streamFlags);
173 }
174 
175 } // namespace ROL
176 
177 #endif
void project_DouglasRachford(Vector< Real > &x, std::ostream &stream=std::cout) const
void project_bnd(Vector< Real > &x, const Vector< Real > &y) const
virtual void scale(const Real alpha)=0
Compute where .
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
void project(Vector< Real > &x, std::ostream &stream=std::cout) override
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
DouglasRachfordProjection(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)
Real residual_1d(const Vector< Real > &x) const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
const Ptr< Constraint< Real > > con_
void residual_nd(Vector< Real > &r, const Vector< Real > &y) const
void project_con(Vector< Real > &x, const Vector< Real > &y) const
Provides the interface to apply upper and lower bound constraints.
virtual void set(const Vector &x)
Set where .
Definition: ROL_Vector.hpp:175
virtual Real norm() const =0
Returns where .
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition: ROL_Types.hpp:57
Defines the general constraint operator interface.