10 #ifndef ROL_OBJECTIVE_DEF_H
11 #define ROL_OBJECTIVE_DEF_H
19 template<
typename Real>
21 if (dual_ == nullPtr) dual_ = x.
dual().
clone();
22 gradient(*dual_,x,tol);
24 return d.
apply(*dual_);
39 template<
typename Real>
41 if (prim_ == nullPtr) prim_ = x.
clone();
42 if (basis_ == nullPtr) basis_ = x.
clone();
44 const Real cbrteps = std::cbrt(ROL_EPSILON<Real>()),
zero(0), one(1);
45 Real f0 =
value(x,tol), h(0), xi(0), gi(0);
48 basis_->set(*x.
basis(i));
50 h = cbrteps * std::max(std::abs(xi),one) * (xi <
zero ? -one : one);
51 prim_->set(x); prim_->axpy(h,*basis_);
52 h = prim_->dot(*basis_) - xi;
54 gi = (
value(*prim_,tol) - f0) / h;
60 template<
typename Real>
62 const Real
zero(0), vnorm = v.
norm();
64 if ( vnorm ==
zero ) {
68 if (prim_ == nullPtr) prim_ = x.
clone();
69 if (dual_ == nullPtr) dual_ = hv.
clone();
72 const Real one(1), h(std::max(one,x.
norm()/vnorm)*tol);
74 gradient(*dual_,x,tol);
75 prim_->set(x); prim_->axpy(h,v);
77 gradient(hv,*prim_,tol);
84 template<
typename Real>
86 const Real
zero(0), vnorm = v.
norm();
88 if ( vnorm ==
zero ) {
92 if (prim_ == nullPtr) prim_ = x.
clone();
95 const Real one(1), h(std::max(one,x.
norm()/vnorm)*tol);
97 prim_->set(x); prim_->axpy(h,v);
98 prox(Jv,*prim_,t,tol);
100 prox(*prim_,x,t,tol);
101 Jv.
axpy(-one,*prim_);
106 template<
typename Real>
110 const bool printToStream,
111 std::ostream & outStream,
116 std::vector<Real> steps(numSteps);
117 for(
int i=0;i<numSteps;++i) {
118 steps[i] = pow(ten,static_cast<Real>(-i));
121 return checkGradient(x,g,d,steps,printToStream,outStream,order);
125 template<
typename Real>
129 const std::vector<Real> &steps,
130 const bool printToStream,
131 std::ostream & outStream,
134 ROL_TEST_FOR_EXCEPTION( order<1 || order>4, std::invalid_argument,
135 "Error: finite difference order must be 1,2,3, or 4" );
140 Real tol = std::sqrt(ROL_EPSILON<Real>());
142 int numSteps = steps.size();
144 std::vector<Real> tmp(numVals);
145 std::vector<std::vector<Real>> gCheck(numSteps, tmp);
149 oldFormatState.copyfmt(outStream);
153 Real val =
value(x,tol);
156 Ptr<Vector<Real>> gtmp = g.
clone();
157 gradient(*gtmp, x, tol);
159 Real dtg = d.
apply(*gtmp);
162 Ptr<Vector<Real>> xnew = x.
clone();
164 for (
int i=0; i<numSteps; i++) {
174 gCheck[i][2] =
weights[order-1][0] * val;
176 for(
int j=0; j<order; ++j) {
178 xnew->axpy(eta*
shifts[order-1][j], d);
181 if(
weights[order-1][j+1] != 0 ) {
183 gCheck[i][2] +=
weights[order-1][j+1] * this->
value(*xnew,tol);
189 gCheck[i][3] = std::abs(gCheck[i][2] - gCheck[i][1]);
193 outStream << std::right
194 << std::setw(20) <<
"Step size"
195 << std::setw(20) <<
"grad'*dir"
196 << std::setw(20) <<
"FD approx"
197 << std::setw(20) <<
"abs error"
199 << std::setw(20) <<
"---------"
200 << std::setw(20) <<
"---------"
201 << std::setw(20) <<
"---------"
202 << std::setw(20) <<
"---------"
205 outStream << std::scientific << std::setprecision(11) << std::right
206 << std::setw(20) << gCheck[i][0]
207 << std::setw(20) << gCheck[i][1]
208 << std::setw(20) << gCheck[i][2]
209 << std::setw(20) << gCheck[i][3]
216 outStream.copyfmt(oldFormatState);
221 template<
typename Real>
225 const bool printToStream,
226 std::ostream & outStream,
230 std::vector<Real> steps(numSteps);
231 for(
int i=0;i<numSteps;++i) {
232 steps[i] = pow(ten,static_cast<Real>(-i));
235 return checkHessVec(x,hv,v,steps,printToStream,outStream,order);
240 template<
typename Real>
244 const std::vector<Real> &steps,
245 const bool printToStream,
246 std::ostream & outStream,
249 ROL_TEST_FOR_EXCEPTION( order<1 || order>4, std::invalid_argument,
250 "Error: finite difference order must be 1,2,3, or 4" );
256 Real tol = std::sqrt(ROL_EPSILON<Real>());
258 int numSteps = steps.size();
260 std::vector<Real> tmp(numVals);
261 std::vector<std::vector<Real>> hvCheck(numSteps, tmp);
265 oldFormatState.copyfmt(outStream);
268 Ptr<Vector<Real>> g = hv.
clone();
270 gradient(*g, x, tol);
273 Ptr<Vector<Real>> Hv = hv.
clone();
274 hessVec(*Hv, v, x, tol);
275 Real normHv = Hv->norm();
278 Ptr<Vector<Real>> gdif = hv.
clone();
279 Ptr<Vector<Real>> gnew = hv.
clone();
280 Ptr<Vector<Real>> xnew = x.
clone();
282 for (
int i=0; i<numSteps; i++) {
287 gdif->scale(
weights[order-1][0]);
288 for (
int j=0; j<order; ++j) {
290 xnew->axpy(eta*
shifts[order-1][j], v);
292 if (
weights[order-1][j+1] != 0 ) {
294 gradient(*gnew, *xnew, tol);
295 gdif->axpy(
weights[order-1][j+1],*gnew);
298 gdif->scale(one/eta);
302 hvCheck[i][1] = normHv;
303 hvCheck[i][2] = gdif->norm();
304 gdif->axpy(-one, *Hv);
305 hvCheck[i][3] = gdif->norm();
309 outStream << std::right
310 << std::setw(20) <<
"Step size"
311 << std::setw(20) <<
"norm(Hess*vec)"
312 << std::setw(20) <<
"norm(FD approx)"
313 << std::setw(20) <<
"norm(abs error)"
315 << std::setw(20) <<
"---------"
316 << std::setw(20) <<
"--------------"
317 << std::setw(20) <<
"---------------"
318 << std::setw(20) <<
"---------------"
321 outStream << std::scientific << std::setprecision(11) << std::right
322 << std::setw(20) << hvCheck[i][0]
323 << std::setw(20) << hvCheck[i][1]
324 << std::setw(20) << hvCheck[i][2]
325 << std::setw(20) << hvCheck[i][3]
332 outStream.copyfmt(oldFormatState);
337 template<
typename Real>
342 const bool printToStream,
343 std::ostream & outStream ) {
345 Real tol = std::sqrt(ROL_EPSILON<Real>());
348 Ptr<Vector<Real>> h = hv.
clone();
350 hessVec(*h, v, x, tol);
352 Real wHv = w.
apply(*h);
354 hessVec(*h, w, x, tol);
356 Real vHw = v.
apply(*h);
358 std::vector<Real> hsymCheck(3, 0);
362 hsymCheck[2] = std::abs(vHw-wHv);
366 oldFormatState.copyfmt(outStream);
369 outStream << std::right
370 << std::setw(20) <<
"<w, H(x)v>"
371 << std::setw(20) <<
"<v, H(x)w>"
372 << std::setw(20) <<
"abs error"
374 outStream << std::scientific << std::setprecision(11) << std::right
375 << std::setw(20) << hsymCheck[0]
376 << std::setw(20) << hsymCheck[1]
377 << std::setw(20) << hsymCheck[2]
382 outStream.copyfmt(oldFormatState);
388 template<
typename Real>
393 std::ostream & outStream,
396 const Real one(1), scale(0.1);
397 Real tol = std::sqrt(ROL_EPSILON<Real>());
400 std::vector<Real> tmp(numVals);
401 std::vector<std::vector<Real>> hvCheck(numSteps, tmp);
405 oldFormatState.copyfmt(outStream);
408 Ptr<Vector<Real>> p = x.
clone();
412 Ptr<Vector<Real>> pdif = x.
clone();
413 Ptr<Vector<Real>> Jnew = x.
clone();
414 Ptr<Vector<Real>> xnew = x.
clone();
417 for (
int i=0; i<numSteps; i++) {
423 prox(*pdif,*xnew,t,tol);
425 pdif->scale(one/eta);
426 proxJacVec(*Jnew,v,*xnew,t,tol);
430 hvCheck[i][1] = Jnew->norm();
431 hvCheck[i][2] = pdif->norm();
432 pdif->axpy(-one, *Jnew);
433 hvCheck[i][3] = pdif->norm();
437 outStream << std::right
438 << std::setw(20) <<
"Step size"
439 << std::setw(20) <<
"norm(Jac*vec)"
440 << std::setw(20) <<
"norm(FD approx)"
441 << std::setw(20) <<
"norm(abs error)"
443 << std::setw(20) <<
"---------"
444 << std::setw(20) <<
"--------------"
445 << std::setw(20) <<
"---------------"
446 << std::setw(20) <<
"---------------"
449 outStream << std::scientific << std::setprecision(11) << std::right
450 << std::setw(20) << hvCheck[i][0]
451 << std::setw(20) << hvCheck[i][1]
452 << std::setw(20) << hvCheck[i][2]
453 << std::setw(20) << hvCheck[i][3]
459 outStream.copyfmt(oldFormatState);
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis...
virtual void scale(const Real alpha)=0
Compute where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual std::vector< std::vector< Real > > checkProxJacVec(const Vector< Real > &x, const Vector< Real > &v, Real t=Real(1), bool printToStream=true, std::ostream &outStream=std::cout, int numSteps=ROL_NUM_CHECKDERIV_STEPS)
Finite-difference proximity operator Jacobian-applied-to-vector check.
virtual int dimension() const
Return dimension of the vector space.
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
const double weights[4][5]
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
virtual void update(const Vector< Real > &u, const Vector< Real > &z, bool flag=true, int iter=-1) override
virtual Real dirDeriv(const Vector< Real > &x, const Vector< Real > &d, Real &tol)
Compute directional derivative.
virtual void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
ROL::Objective_SimOpt value
virtual void zero()
Set to zero vector.
Defines the linear algebra or vector space interface.
virtual Real dot(const Vector &x) const =0
Compute where .
virtual std::vector< std::vector< Real > > checkGradient(const Vector< Real > &x, const Vector< Real > &d, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference gradient check.
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
basic_nullstream< char, std::char_traits< char >> nullstream
virtual void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
virtual void proxJacVec(Vector< Real > &Jv, const Vector< Real > &v, const Vector< Real > &x, Real t, Real &tol)
Apply the Jacobian of the proximity operator.
virtual std::vector< std::vector< Real > > checkHessVec(const Vector< Real > &x, const Vector< Real > &v, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS, const int order=1)
Finite-difference Hessian-applied-to-vector check.
virtual Real norm() const =0
Returns where .
virtual std::vector< Real > checkHessSym(const Vector< Real > &x, const Vector< Real > &v, const Vector< Real > &w, const bool printToStream=true, std::ostream &outStream=std::cout)
Hessian symmetry check.