10#ifndef ROL_CONSTRAINT_DEF_H
11#define ROL_CONSTRAINT_DEF_H
13#include "ROL_LinearAlgebra.hpp"
14#include "ROL_LAPACK.hpp"
28 Real h = std::max(one,x.
norm()/v.
norm())*tol;
32 ROL::Ptr<Vector<Real> > c = jv.
clone();
33 this->
value(*c,x,ctol);
36 ROL::Ptr<Vector<Real> > xnew = x.
clone();
43 this->
value(jv,*xnew,ctol);
75 ROL::Ptr<Vector<Real> > xnew = x.
clone();
76 ROL::Ptr<Vector<Real> > ex = x.
clone();
77 ROL::Ptr<Vector<Real> > eajv = ajv.
clone();
78 ROL::Ptr<Vector<Real> > cnew = dualv.
clone();
79 ROL::Ptr<Vector<Real> > c0 = dualv.
clone();
80 this->
value(*c0,x,ctol);
83 for (
int i = 0; i < ajv.
dimension(); i++ ) {
86 h = std::max(one,x.
norm()/ex->norm())*tol;
90 this->
value(*cnew,*xnew,ctol);
94 ajv.
axpy(cnew->apply(v),*eajv);
138 Real h = std::max(
static_cast<Real
>(1),x.
norm()/v.
norm())*tol;
141 ROL::Ptr<Vector<Real> > aju = huv.
clone();
145 ROL::Ptr<Vector<Real> > xnew = x.
clone();
155 huv.
axpy(
static_cast<Real
>(-1),*aju);
156 huv.
scale(
static_cast<Real
>(1)/h);
169 const Real
zero(0), one(1);
178 tol = std::sqrt(b1.
dot(b1)+b2.
dot(b2))*tol;
184 Ptr<Vector<Real>> r1 = b1.
clone();
185 Ptr<Vector<Real>> r2 = b2.
clone();
186 Ptr<Vector<Real>> z1 = v1.
clone();
187 Ptr<Vector<Real>> z2 = v2.
clone();
188 Ptr<Vector<Real>> w1 = b1.
clone();
189 Ptr<Vector<Real>> w2 = b2.
clone();
190 std::vector<Ptr<Vector<Real>>> V1;
191 std::vector<Ptr<Vector<Real>>> V2;
192 Ptr<Vector<Real>> V2temp = b2.
clone();
193 std::vector<Ptr<Vector<Real>>> Z1;
194 std::vector<Ptr<Vector<Real>>> Z2;
195 Ptr<Vector<Real>> w1temp = b1.
clone();
196 Ptr<Vector<Real>> Z2temp = v2.
clone();
198 std::vector<Real> res(m+1,
zero);
199 LA::Matrix<Real> H(m+1,m);
200 LA::Vector<Real> cs(m);
201 LA::Vector<Real> sn(m);
202 LA::Vector<Real> s(m+1);
203 LA::Vector<Real> y(m+1);
204 LA::Vector<Real> cnorm(m);
205 LAPACK<int, Real> lapack;
212 r1->set(b1); r2->set(b2);
213 res[0] = std::sqrt(r1->dot(*r1) + r2->dot(*r2));
216 if (res[0] ==
zero) {
221 V1.push_back(b1.
clone()); (V1[0])->set(*r1); (V1[0])->scale(one/res[0]);
222 V2.push_back(b2.
clone()); (V2[0])->set(*r2); (V2[0])->scale(one/res[0]);
226 for (i=0; i<m; i++) {
229 V2temp->set(*(V2[i]));
231 Z2.push_back(v2.
clone()); (Z2[i])->set(*Z2temp);
232 Z1.push_back(v1.
clone()); (Z1[i])->set((V1[i])->dual());
237 w1->set(*(V1[i])); w1->plus(*w1temp);
240 for (k=0; k<=i; k++) {
241 H(k,i) = w1->dot(*(V1[k])) + w2->dot(*(V2[k]));
242 w1->axpy(-H(k,i), *(V1[k]));
243 w2->axpy(-H(k,i), *(V2[k]));
245 H(i+1,i) = std::sqrt(w1->dot(*w1) + w2->dot(*w2));
247 const bool breakdown = (H(i+1,i) ==
zero);
249 V1.push_back(b1.
clone()); (V1[i+1])->set(*w1); (V1[i+1])->scale(one/H(i+1,i));
250 V2.push_back(b2.
clone()); (V2[i+1])->set(*w2); (V2[i+1])->scale(one/H(i+1,i));
254 for (k=0; k<=i-1; k++) {
255 temp = cs(k)*H(k,i) + sn(k)*H(k+1,i);
256 H(k+1,i) = -sn(k)*H(k,i) + cs(k)*H(k+1,i);
261 if ( H(i+1,i) ==
zero ) {
265 else if ( std::abs(H(i+1,i)) > std::abs(H(i,i)) ) {
266 temp = H(i,i) / H(i+1,i);
267 sn(i) = one / std::sqrt( one + temp*temp );
268 cs(i) = temp * sn(i);
271 temp = H(i+1,i) / H(i,i);
272 cs(i) = one / std::sqrt( one + temp*temp );
273 sn(i) = temp * cs(i);
278 s(i+1) = -sn(i)*s(i);
280 H(i,i) = cs(i)*H(i,i) + sn(i)*H(i+1,i);
282 resnrm = std::abs(s(i+1));
286 const char uplo =
'U';
287 const char trans =
'N';
288 const char diag =
'N';
289 const char normin =
'N';
293 lapack.LATRS(uplo, trans, diag, normin, i+1, H.values(), m+1, y.values(), &scaling, cnorm.values(), &info);
296 for (k=0; k<=i; k++) {
297 z1->axpy(y(k), *(Z1[k]));
298 z2->axpy(y(k), *(Z2[k]));
301 if (res[i+1] <= tol || breakdown) {
330 const bool printToStream,
331 std::ostream & outStream,
334 std::vector<Real> steps(numSteps);
335 for(
int i=0;i<numSteps;++i) {
336 steps[i] = pow(10,-i);
349 const std::vector<Real> &steps,
350 const bool printToStream,
351 std::ostream & outStream,
353 ROL_TEST_FOR_EXCEPTION( order<1 || order>4, std::invalid_argument,
354 "Error: finite difference order must be 1,2,3, or 4" );
363 int numSteps = steps.size();
365 std::vector<Real> tmp(numVals);
366 std::vector<std::vector<Real> > jvCheck(numSteps, tmp);
370 oldFormatState.copyfmt(outStream);
373 ROL::Ptr<Vector<Real> > c = jv.
clone();
375 this->
value(*c, x, tol);
378 ROL::Ptr<Vector<Real> > Jv = jv.
clone();
380 Real normJv = Jv->norm();
383 ROL::Ptr<Vector<Real> > cdif = jv.
clone();
384 ROL::Ptr<Vector<Real> > cnew = jv.
clone();
385 ROL::Ptr<Vector<Real> > xnew = x.
clone();
387 for (
int i=0; i<numSteps; i++) {
394 cdif->scale(weights[order-1][0]);
396 for(
int j=0; j<order; ++j) {
398 xnew->axpy(eta*shifts[order-1][j], v);
400 if( weights[order-1][j+1] != 0 ) {
402 this->
value(*cnew,*xnew,tol);
403 cdif->axpy(weights[order-1][j+1],*cnew);
408 cdif->scale(one/eta);
412 jvCheck[i][1] = normJv;
413 jvCheck[i][2] = cdif->norm();
414 cdif->axpy(-one, *Jv);
415 jvCheck[i][3] = cdif->norm();
418 std::stringstream hist;
421 << std::setw(20) <<
"Step size"
422 << std::setw(20) <<
"norm(Jac*vec)"
423 << std::setw(20) <<
"norm(FD approx)"
424 << std::setw(20) <<
"norm(abs error)"
426 << std::setw(20) <<
"---------"
427 << std::setw(20) <<
"-------------"
428 << std::setw(20) <<
"---------------"
429 << std::setw(20) <<
"---------------"
432 hist << std::scientific << std::setprecision(11) << std::right
433 << std::setw(20) << jvCheck[i][0]
434 << std::setw(20) << jvCheck[i][1]
435 << std::setw(20) << jvCheck[i][2]
436 << std::setw(20) << jvCheck[i][3]
438 outStream << hist.str();
444 outStream.copyfmt(oldFormatState);
455 const bool printToStream,
456 std::ostream & outStream,
457 const int numSteps) {
462 std::vector<Real> tmp(numVals);
463 std::vector<std::vector<Real> > ajvCheck(numSteps, tmp);
464 Real eta_factor = 1e-1;
468 ROL::Ptr<Vector<Real> > c0 = c.
clone();
469 ROL::Ptr<Vector<Real> > cnew = c.
clone();
470 ROL::Ptr<Vector<Real> > xnew = x.
clone();
471 ROL::Ptr<Vector<Real> > ajv0 = ajv.
clone();
472 ROL::Ptr<Vector<Real> > ajv1 = ajv.
clone();
473 ROL::Ptr<Vector<Real> > ex = x.
clone();
474 ROL::Ptr<Vector<Real> > eajv = ajv.
clone();
478 oldFormatState.copyfmt(outStream);
482 this->
value(*c0, x, tol);
486 Real normAJv = ajv0->norm();
488 for (
int i=0; i<numSteps; i++) {
492 for (
int j = 0; j < ajv.
dimension(); j++ ) {
498 this->
value(*cnew,*xnew,tol);
499 cnew->axpy(-one,*c0);
500 cnew->scale(one/eta);
502 ajv1->axpy(cnew->apply(v),*eajv);
506 ajvCheck[i][0] = eta;
507 ajvCheck[i][1] = normAJv;
508 ajvCheck[i][2] = ajv1->norm();
509 ajv1->axpy(-one, *ajv0);
510 ajvCheck[i][3] = ajv1->norm();
513 std::stringstream hist;
516 << std::setw(20) <<
"Step size"
517 << std::setw(20) <<
"norm(adj(Jac)*vec)"
518 << std::setw(20) <<
"norm(FD approx)"
519 << std::setw(20) <<
"norm(abs error)"
521 << std::setw(20) <<
"---------"
522 << std::setw(20) <<
"------------------"
523 << std::setw(20) <<
"---------------"
524 << std::setw(20) <<
"---------------"
527 hist << std::scientific << std::setprecision(11) << std::right
528 << std::setw(20) << ajvCheck[i][0]
529 << std::setw(20) << ajvCheck[i][1]
530 << std::setw(20) << ajvCheck[i][2]
531 << std::setw(20) << ajvCheck[i][3]
533 outStream << hist.str();
537 eta = eta*eta_factor;
541 outStream.copyfmt(oldFormatState);
552 const bool printToStream,
553 std::ostream & outStream) {
556 ROL::Ptr<Vector<Real> > Jv = dualw.
clone();
557 ROL::Ptr<Vector<Real> > Jw = dualv.
clone();
564 Real vJw = v.
apply(*Jw);
566 Real wJv = w.
apply(*Jv);
568 Real diff = std::abs(wJv-vJw);
570 if ( printToStream ) {
571 std::stringstream hist;
572 hist << std::scientific << std::setprecision(8);
573 hist <<
"\nTest Consistency of Jacobian and its adjoint: \n |<w,Jv> - <adj(J)w,v>| = "
575 hist <<
" |<w,Jv>| = " << std::abs(wJv) <<
"\n";
577 outStream << hist.str();
587 const bool printToStream,
588 std::ostream & outStream,
591 std::vector<Real> steps(numSteps);
592 for(
int i=0;i<numSteps;++i) {
593 steps[i] = pow(10,-i);
605 const std::vector<Real> &steps,
606 const bool printToStream,
607 std::ostream & outStream,
615 int numSteps = steps.size();
617 std::vector<Real> tmp(numVals);
618 std::vector<std::vector<Real> > ahuvCheck(numSteps, tmp);
621 ROL::Ptr<Vector<Real> > AJdif = hv.
clone();
622 ROL::Ptr<Vector<Real> > AJu = hv.
clone();
623 ROL::Ptr<Vector<Real> > AHuv = hv.
clone();
624 ROL::Ptr<Vector<Real> > AJnew = hv.
clone();
625 ROL::Ptr<Vector<Real> > xnew = x.
clone();
629 oldFormatState.copyfmt(outStream);
637 Real normAHuv = AHuv->norm();
639 for (
int i=0; i<numSteps; i++) {
647 AJdif->scale(weights[order-1][0]);
649 for(
int j=0; j<order; ++j) {
651 xnew->axpy(eta*shifts[order-1][j],v);
653 if( weights[order-1][j+1] != 0 ) {
656 AJdif->axpy(weights[order-1][j+1],*AJnew);
660 AJdif->scale(one/eta);
663 ahuvCheck[i][0] = eta;
664 ahuvCheck[i][1] = normAHuv;
665 ahuvCheck[i][2] = AJdif->norm();
666 AJdif->axpy(-one, *AHuv);
667 ahuvCheck[i][3] = AJdif->norm();
670 std::stringstream hist;
673 << std::setw(20) <<
"Step size"
674 << std::setw(20) <<
"norm(adj(H)(u,v))"
675 << std::setw(20) <<
"norm(FD approx)"
676 << std::setw(20) <<
"norm(abs error)"
678 << std::setw(20) <<
"---------"
679 << std::setw(20) <<
"-----------------"
680 << std::setw(20) <<
"---------------"
681 << std::setw(20) <<
"---------------"
684 hist << std::scientific << std::setprecision(11) << std::right
685 << std::setw(20) << ahuvCheck[i][0]
686 << std::setw(20) << ahuvCheck[i][1]
687 << std::setw(20) << ahuvCheck[i][2]
688 << std::setw(20) << ahuvCheck[i][3]
690 outStream << hist.str();
696 outStream.copyfmt(oldFormatState);
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0 zero)()
virtual void update(const Vector< Real > &u_old, const Vector< Real > &u_new, const Vector< Real > &z, bool flag=true, int iter=-1)
virtual std::vector< std::vector< Real > > checkApplyJacobian(const Vector< Real > &x, const Vector< Real > &v, const Vector< Real > &jv, const std::vector< Real > &steps, const bool printToStream=true, std::ostream &outStream=std::cout, const int order=1)
Finite-difference check for the constraint Jacobian application.
virtual std::vector< std::vector< Real > > checkApplyAdjointJacobian(const Vector< Real > &x, const Vector< Real > &v, const Vector< Real > &c, const Vector< Real > &ajv, const bool printToStream=true, std::ostream &outStream=std::cout, const int numSteps=ROL_NUM_CHECKDERIV_STEPS)
Finite-difference check for the application of the adjoint of constraint Jacobian.
virtual void applyAdjointHessian(Vector< Real > &ahuv, const Vector< Real > &u, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the derivative of the adjoint of the constraint Jacobian at to vector in direction ,...
virtual void applyAdjointJacobian(Vector< Real > &ajv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the adjoint of the the constraint Jacobian at , , to vector .
virtual Real checkAdjointConsistencyJacobian(const Vector< Real > &w, const Vector< Real > &v, const Vector< Real > &x, const bool printToStream=true, std::ostream &outStream=std::cout)
virtual void applyJacobian(Vector< Real > &jv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the constraint Jacobian at , , to vector .
virtual std::vector< Real > solveAugmentedSystem(Vector< Real > &v1, Vector< Real > &v2, const Vector< Real > &b1, const Vector< Real > &b2, const Vector< Real > &x, Real &tol)
Approximately solves the augmented system .
virtual std::vector< std::vector< Real > > checkApplyAdjointHessian(const Vector< Real > &x, const Vector< Real > &u, const Vector< Real > &v, const Vector< Real > &hv, const std::vector< Real > &step, const bool printToScreen=true, std::ostream &outStream=std::cout, const int order=1)
Finite-difference check for the application of the adjoint of constraint Hessian.
virtual void applyAdjointJacobian(Vector< Real > &ajv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the adjoint of the the constraint Jacobian at , , to vector .
virtual void applyAdjointHessian(Vector< Real > &ahuv, const Vector< Real > &u, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the derivative of the adjoint of the constraint Jacobian at to vector in direction ,...
virtual std::vector< std::vector< Real > > checkApplyJacobian(const Vector< Real > &x, const Vector< Real > &v, const Vector< Real > &jv, const std::vector< Real > &steps, const bool printToStream=true, std::ostream &outStream=std::cout, const int order=1)
Finite-difference check for the constraint Jacobian application.
virtual std::vector< std::vector< Real > > checkApplyAdjointHessian(const Vector< Real > &x, const Vector< Real > &u, const Vector< Real > &v, const Vector< Real > &hv, const std::vector< Real > &step, const bool printToScreen=true, std::ostream &outStream=std::cout, const int order=1)
Finite-difference check for the application of the adjoint of constraint Hessian.
virtual void applyPreconditioner(Vector< Real > &pv, const Vector< Real > &v, const Vector< Real > &x, const Vector< Real > &g, Real &tol)
Apply a constraint preconditioner at , , to vector . Ideally, this preconditioner satisfies the follo...
virtual void scale(const Real alpha)=0
Compute where .
virtual ROL::Ptr< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void set(const Vector &x)
Set where .
virtual ROL::Ptr< Vector > basis(const int i) const
Return i-th basis vector.
virtual Real dot(const Vector &x) const =0
Compute where .
virtual int dimension() const
Return dimension of the vector space.
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
virtual const Vector & dual() const
Return dual representation of , for example, the result of applying a Riesz map, or change of basis,...
virtual Real norm() const =0
Returns where .
virtual Real apply(const Vector< Real > &x) const
Apply to a dual vector. This is equivalent to the call .
virtual void zero()
Set to zero vector.
const double weights[4][5]
basic_nullstream< char, std::char_traits< char > > nullstream
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
ROL::Objective_SerialSimOpt Objective_SimOpt value(const V &u, const V &z, Real &tol) override
Real ROL_EPSILON(void)
Platform-dependent machine epsilon.
Real ROL_UNDERFLOW(void)
Platform-dependent minimum double.
void applyJacobian(ROL::Vector< Real > &jv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &sol)