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
13namespace ROL {
14
15template<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();
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
58template<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
77template<typename Real>
79 if (con_ == nullPtr) {
80 bnd_->project(x);
81 }
82 else {
83 project_DouglasRachford(x, stream);
84 }
85}
86
87template<typename Real>
89 return xprim_->dot(x) + b_;
90}
91
92template<typename Real>
94 Real tol(std::sqrt(ROL_EPSILON<Real>()));
95 con_->update(y,UpdateType::Temp);
96 con_->value(r,y,tol);
97}
98
99template<typename Real>
101 x.set(y);
102 bnd_->project(x);
103}
104
105template<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
122template<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
Provides the interface to apply upper and lower bound constraints.
Defines the general constraint operator interface.
void project(Vector< Real > &x, std::ostream &stream=std::cout) override
Real residual_1d(const Vector< Real > &x) const
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)
void project_DouglasRachford(Vector< Real > &x, std::ostream &stream=std::cout) const
void project_bnd(Vector< Real > &x, const Vector< Real > &y) const
void project_con(Vector< Real > &x, const Vector< Real > &y) const
void residual_nd(Vector< Real > &r, const Vector< Real > &y) const
const Ptr< Constraint< Real > > con_
Defines the linear algebra or vector space interface.
virtual Real norm() const =0
Returns where .
virtual void set(const Vector &x)
Set where .
virtual void scale(const Real alpha)=0
Compute where .
virtual void plus(const Vector &x)=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.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Definition ROL_Types.hpp:57