ROL
ROL_PrimalDualInteriorPointReducedResidual.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_PRIMALDUALINTERIORPOINTREDUCEDRESIDUAL_H
11#define ROL_PRIMALDUALINTERIORPOINTREDUCEDRESIDUAL_H
12
14#include "ROL_Constraint.hpp"
15
16#include <iostream>
17
74namespace ROL {
75
76template<class Real>
78
79 typedef ROL::ParameterList PL;
80
81 typedef Vector<Real> V;
88
89 typedef Elementwise::ValueSet<Real> ValueSet;
90
91 typedef typename PV::size_type size_type;
92
93private:
94
95 static const size_type OPT = 0;
96 static const size_type EQUAL = 1;
97 static const size_type LOWER = 2;
98 static const size_type UPPER = 3;
99
100 ROL::Ptr<const V> x_; // Optimization vector
101 ROL::Ptr<const V> l_; // constraint multiplier
102 ROL::Ptr<const V> zl_; // Lower bound multiplier
103 ROL::Ptr<const V> zu_; // Upper bound multiplier
104
105 ROL::Ptr<const V> xl_; // Lower bound
106 ROL::Ptr<const V> xu_; // Upper bound
107
108 const ROL::Ptr<const V> maskL_;
109 const ROL::Ptr<const V> maskU_;
110
111 ROL::Ptr<V> scratch_;
112
113 const ROL::Ptr<PENALTY> penalty_;
114 const ROL::Ptr<OBJ> obj_;
115 const ROL::Ptr<CON> con_;
116
117
118public:
119
120 PrimalDualInteriorPointResidual( const ROL::Ptr<PENALTY> &penalty,
121 const ROL::Ptr<CON> &con,
122 const V &x,
123 ROL::Ptr<V> &scratch ) :
124 penalty_(penalty), con_(con), scratch_(scratch) {
125
126 obj_ = penalty_->getObjective();
127 maskL_ = penalty_->getLowerMask();
128 maskU_ = penalty_->getUpperMask();
129
130 ROL::Ptr<BND> bnd = penalty_->getBoundConstraint();
131 xl_ = bnd->getLowerBound();
132 xu_ = bnd->getUpperBound();
133
134
135 // Get access to the four components
136 const PV &x_pv = dynamic_cast<const PV&>(x);
137
138 x_ = x_pv.get(OPT);
139 l_ = x_pv.get(EQUAL);
140 zl_ = x_pv.get(LOWER);
141 zu_ = x_pv.get(UPPER);
142
143 }
144
145
146 void update( const Vector<Real> &x, bool flag = true, int iter = -1 ) {
147
148 // Get access to the four components
149 const PV &x_pv = dynamic_cast<const PV&>(x);
150
151 x_ = x_pv.get(OPT);
152 l_ = x_pv.get(EQUAL);
153 zl_ = x_pv.get(LOWER);
154 zu_ = x_pv.get(UPPER);
155
156 obj_->update(*x_,flag,iter);
157 con_->update(*x_,flag,iter);
158 }
159
160
161 // Evaluate the gradient of the Lagrangian
162 void value( V &c, const V &x, Real &tol ) {
163
164
165 PV &c_pv = dynamic_cast<PV&>(c);
166 const PV &x_pv = dynamic_cast<const PV&>(x);
167
168 x_ = x_pv.get(OPT);
169 l_ = x_pv.get(EQUAL);
170 zl_ = x_pv.get(LOWER);
171 zu_ = x_pv.get(UPPER);
172
173 ROL::Ptr<V> cx = c_pv.get(OPT);
174 ROL::Ptr<V> cl = c_pv.get(EQUAL);
175
176 // TODO: Add check as to whether we really need to recompute these
177 penalty_->gradient(*cx,*x_,tol);
178 con_->applyAdjointJacobian(*scratch_,*l_,*x_,tol);
179
180 // \f$ c_x = \nabla \phi_mu(x) + J^\ast \lambda \f$
181 cx_->plus(*scratch_);
182
183 con_->value(*cl_,*x_,tol);
184
185 }
186
187 void applyJacobian( V &jv, const V &v, const V &x, Real &tol ) {
188
189
190
191 PV &jv_pv = dynamic_cast<PV&>(jv);
192 const PV &v_pv = dynamic_cast<const PV&>(v);
193 const PV &x_pv = dynamic_cast<const PV&>(x);
194
195 // output vector components
196 ROL::Ptr<V> jvx = jv_pv.get(OPT);
197 ROL::Ptr<V> jvl = jv_pv.get(EQUAL);
198
199 // input vector components
200 ROL::Ptr<const V> vx = v_pv.get(OPT);
201 ROL::Ptr<const V> vl = v_pv.get(EQUAL);
202
203 x_ = x_pv.get(OPT);
204 l_ = x_pv.get(EQUAL);
205
206 // \f$
207 obj_->hessVec(*jvx,*vx,*x_,tol);
208 con_->applyAdjointHessian(*scratch_,*l_,*vx,*x_,tol);
209 jvx->plus(*scratch_);
210
211 // \f$J^\ast d_\lambda \f$
212 con_->applyAdjointJacobian(*scratch_,*vl,*x_,tol);
213 jvx->plus(*scratch_);
214
215
216 Elementwise::DivideAndInvert<Real> divinv;
217 Elementwise::Multiply<Real> mult;
218
219 // Note that indices corresponding to infinite bounds should automatically lead to
220 // zero diagonal contributions to the Sigma operators
221 scratch_->set(*x_);
222 scratch_->axpy(-1.0,*xl_); // x-l
223 scratch_->applyBinary(divinv,*zl_); // zl/(x-l)
224 scratch_->applyBinary(mult,*vx); // zl*vx/(x-l) = Sigma_l*vx
225
226 jvx->plu(*scratch_);
227
228 scratch_->set(*xu_);
229 scratch_->axpy(-1.0,*x_); // u-x
230 scratch_->applyBinary(divinv,*zu_); // zu/(u-x)
231 scratch_->applyBinary(mult,*vx); // zu*vx/(u-x) = Sigma_u*vx
232
233 jvx->plus(*scratch_);
234
235
236
237
238
239
240
241// \f[ [W+(X-L)^{-1}+(U-X)^{-1}]d_x + J^\ast d_\lambda =
242// -g_x + (U-X)^{-1}g_{z_u} - (L-X)^{-1}g_{z_l} \f]
243
244
245
246 }
247
249 return nfval_;
250 }
251
253 return ngrad_;
254 }
255
257 return ncval_;
258 }
259
260
261}; // class PrimalDualInteriorPointResidual
262
263} // namespace ROL
264
265#endif // ROL_PRIMALDUALKKTOPERATOR_H
Provides the interface to apply upper and lower bound constraints.
Defines the general constraint operator interface.
Provides the interface to evaluate the Interior Pointy log barrier penalty function with upper and lo...
Provides the interface to apply a linear operator.
Provides the interface to evaluate objective functions.
Defines the linear algebra of vector space on a generic partitioned vector.
std::vector< PV >::size_type size_type
ROL::Ptr< const Vector< Real > > get(size_type i) const
Symmetrized form of the KKT operator for the Type-EB problem with equality and bound multipliers.
void applyJacobian(V &jv, const V &v, const V &x, Real &tol)
Apply the constraint Jacobian at , , to vector .
void update(const Vector< Real > &x, bool flag=true, int iter=-1)
Update constraint functions. x is the optimization variable, flag = true if optimization variable i...
void value(V &c, const V &x, Real &tol)
Evaluate the constraint operator at .
PrimalDualInteriorPointResidual(const ROL::Ptr< PENALTY > &penalty, const ROL::Ptr< CON > &con, const V &x, ROL::Ptr< V > &scratch)
Defines the linear algebra or vector space interface.