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
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_ (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();
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
51template<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
66template<typename Real>
67void 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
76template<typename Real>
78 return xprim_->dot(x) + b_;
79}
80
81template<typename Real>
83 Real tol(std::sqrt(ROL_EPSILON<Real>()));
84 con_->update(y,UpdateType::Temp);
85 con_->value(r,y,tol);
86}
87
88template<typename Real>
90 x.set(y);
91 bnd_->project(x);
92}
93
94template<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
111template<typename Real>
112void 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
Provides the interface to apply upper and lower bound constraints.
Defines the general constraint operator interface.
Real residual_1d(const Vector< Real > &x) const
void residual_nd(Vector< Real > &r, const Vector< Real > &y) const
void project(Vector< Real > &x, std::ostream &stream=std::cout) override
void project_Dykstra(Vector< Real > &x, std::ostream &stream=std::cout) const
void project_con(Vector< Real > &x, const Vector< Real > &y) const
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)
void project_bnd(Vector< Real > &x, 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