45 #ifndef ROL_EQUALITYCONSTRAINT_DEF_H
46 #define ROL_EQUALITYCONSTRAINT_DEF_H
60 Real ctol = std::sqrt(ROL_EPSILON<Real>());
63 Real h = std::max(one,x.
norm()/v.
norm())*tol;
67 Teuchos::RCP<Vector<Real> > c = jv.
clone();
68 this->
value(*c,x,ctol);
71 Teuchos::RCP<Vector<Real> > xnew = x.
clone();
78 this->
value(jv,*xnew,ctol);
91 applyAdjointJacobian(ajv,v,x,v.
dual(),tol);
112 Real ctol = std::sqrt(ROL_EPSILON<Real>());
114 Teuchos::RCP<Vector<Real> > xnew = x.
clone();
115 Teuchos::RCP<Vector<Real> > ex = x.
clone();
116 Teuchos::RCP<Vector<Real> > eajv = ajv.
clone();
117 Teuchos::RCP<Vector<Real> > cnew = dualv.
clone();
118 Teuchos::RCP<Vector<Real> > c0 = dualv.
clone();
119 this->
value(*c0,x,ctol);
122 for (
int i = 0; i < ajv.
dimension(); i++ ) {
125 h = std::max(one,x.
norm()/ex->norm())*tol;
129 this->
value(*cnew,*xnew,ctol);
130 cnew->axpy(-one,*c0);
132 ajv.
axpy(cnew->dot(v.
dual()),*eajv);
169 template <
class Real>
177 Real h = std::max(static_cast<Real>(1),x.
norm()/v.
norm())*tol;
180 Teuchos::RCP<Vector<Real> > aju = huv.
clone();
181 applyAdjointJacobian(*aju,u,x,tol);
184 Teuchos::RCP<Vector<Real> > xnew = x.
clone();
191 applyAdjointJacobian(huv,u,*xnew,tol);
194 huv.
axpy(static_cast<Real>(-1),*aju);
195 huv.
scale(static_cast<Real>(1)/h);
199 template <
class Real>
218 tol = std::sqrt(b1.
dot(b1)+b2.
dot(b2))*tol;
224 Teuchos::RCP<Vector<Real> > r1 = b1.
clone();
225 Teuchos::RCP<Vector<Real> > r2 = b2.
clone();
226 Teuchos::RCP<Vector<Real> > z1 = v1.
clone();
227 Teuchos::RCP<Vector<Real> > z2 = v2.
clone();
228 Teuchos::RCP<Vector<Real> > w1 = b1.
clone();
229 Teuchos::RCP<Vector<Real> > w2 = b2.
clone();
230 std::vector<Teuchos::RCP<Vector<Real> > > V1;
231 std::vector<Teuchos::RCP<Vector<Real> > > V2;
232 Teuchos::RCP<Vector<Real> > V2temp = b2.
clone();
233 std::vector<Teuchos::RCP<Vector<Real> > > Z1;
234 std::vector<Teuchos::RCP<Vector<Real> > > Z2;
235 Teuchos::RCP<Vector<Real> > w1temp = b1.
clone();
236 Teuchos::RCP<Vector<Real> > Z2temp = v2.
clone();
238 std::vector<Real> res(m+1, zero);
239 Teuchos::SerialDenseMatrix<int, Real> H(m+1,m);
240 Teuchos::SerialDenseVector<int, Real> cs(m);
241 Teuchos::SerialDenseVector<int, Real> sn(m);
242 Teuchos::SerialDenseVector<int, Real> s(m+1);
243 Teuchos::SerialDenseVector<int, Real> y(m+1);
244 Teuchos::SerialDenseVector<int, Real> cnorm(m);
245 Teuchos::LAPACK<int, Real> lapack;
248 applyAdjointJacobian(*r1, v2, x, zerotol);
249 r1->scale(-one); r1->axpy(-one, v1.
dual()); r1->plus(b1);
251 r2->scale(-one); r2->plus(b2);
252 res[0] = std::sqrt(r1->dot(*r1) + r2->dot(*r2));
255 if (res[0] == zero) {
260 V1.push_back(b1.
clone()); (V1[0])->set(*r1); (V1[0])->scale(one/res[0]);
261 V2.push_back(b2.
clone()); (V2[0])->set(*r2); (V2[0])->scale(one/res[0]);
265 for (i=0; i<m; i++) {
268 V2temp->set(*(V2[i]));
269 applyPreconditioner(*Z2temp, *V2temp, x, b1, zerotol);
270 Z2.push_back(v2.
clone()); (Z2[i])->set(*Z2temp);
271 Z1.push_back(v1.
clone()); (Z1[i])->set((V1[i])->dual());
275 applyAdjointJacobian(*w1temp, *Z2temp, x, zerotol);
276 w1->set(*(V1[i])); w1->plus(*w1temp);
279 for (k=0; k<=i; k++) {
280 H(k,i) = w1->dot(*(V1[k])) + w2->dot(*(V2[k]));
281 w1->axpy(-H(k,i), *(V1[k]));
282 w2->axpy(-H(k,i), *(V2[k]));
284 H(i+1,i) = std::sqrt(w1->dot(*w1) + w2->dot(*w2));
286 V1.push_back(b1.
clone()); (V1[i+1])->set(*w1); (V1[i+1])->scale(one/H(i+1,i));
287 V2.push_back(b2.
clone()); (V2[i+1])->set(*w2); (V2[i+1])->scale(one/H(i+1,i));
290 for (k=0; k<=i-1; k++) {
291 temp = cs(k)*H(k,i) + sn(k)*H(k+1,i);
292 H(k+1,i) = -sn(k)*H(k,i) + cs(k)*H(k+1,i);
297 if ( H(i+1,i) == zero ) {
301 else if ( std::abs(H(i+1,i)) > std::abs(H(i,i)) ) {
302 temp = H(i,i) / H(i+1,i);
303 sn(i) = one / std::sqrt( one + temp*temp );
304 cs(i) = temp * sn(i);
307 temp = H(i+1,i) / H(i,i);
308 cs(i) = one / std::sqrt( one + temp*temp );
309 sn(i) = temp * cs(i);
314 s(i+1) = -sn(i)*s(i);
316 H(i,i) = cs(i)*H(i,i) + sn(i)*H(i+1,i);
318 resnrm = std::abs(s(i+1));
322 const char uplo =
'U';
323 const char trans =
'N';
324 const char diag =
'N';
325 const char normin =
'N';
329 lapack.LATRS(uplo, trans, diag, normin, i+1, H.values(), m+1, y.values(), &scaling, cnorm.values(), &info);
332 for (k=0; k<=i; k++) {
333 z1->axpy(y(k), *(Z1[k]));
334 z2->axpy(y(k), *(Z2[k]));
340 if (res[i+1] <= tol) {
368 template <
class Real>
372 const bool printToStream,
373 std::ostream & outStream,
376 std::vector<Real> steps(numSteps);
377 for(
int i=0;i<numSteps;++i) {
378 steps[i] = pow(10,-i);
381 return checkApplyJacobian(x,v,jv,steps,printToStream,outStream,order);
387 template <
class Real>
391 const std::vector<Real> &steps,
392 const bool printToStream,
393 std::ostream & outStream,
396 TEUCHOS_TEST_FOR_EXCEPTION( order<1 || order>4, std::invalid_argument,
397 "Error: finite difference order must be 1,2,3, or 4" );
404 Real tol = std::sqrt(ROL_EPSILON<Real>());
406 int numSteps = steps.size();
408 std::vector<Real> tmp(numVals);
409 std::vector<std::vector<Real> > jvCheck(numSteps, tmp);
412 Teuchos::oblackholestream oldFormatState;
413 oldFormatState.copyfmt(outStream);
416 Teuchos::RCP<Vector<Real> > c = jv.
clone();
418 this->
value(*c, x, tol);
421 Teuchos::RCP<Vector<Real> > Jv = jv.
clone();
423 Real normJv = Jv->norm();
426 Teuchos::RCP<Vector<Real> > cdif = jv.
clone();
427 Teuchos::RCP<Vector<Real> > cnew = jv.
clone();
428 Teuchos::RCP<Vector<Real> > xnew = x.
clone();
430 for (
int i=0; i<numSteps; i++) {
437 cdif->scale(
weights[order-1][0]);
439 for(
int j=0; j<order; ++j) {
441 xnew->axpy(eta*
shifts[order-1][j], v);
443 if(
weights[order-1][j+1] != 0 ) {
445 this->
value(*cnew,*xnew,tol);
446 cdif->axpy(
weights[order-1][j+1],*cnew);
451 cdif->scale(one/eta);
455 jvCheck[i][1] = normJv;
456 jvCheck[i][2] = cdif->norm();
457 cdif->axpy(-one, *Jv);
458 jvCheck[i][3] = cdif->norm();
461 std::stringstream hist;
464 << std::setw(20) <<
"Step size"
465 << std::setw(20) <<
"norm(Jac*vec)"
466 << std::setw(20) <<
"norm(FD approx)"
467 << std::setw(20) <<
"norm(abs error)"
469 << std::setw(20) <<
"---------"
470 << std::setw(20) <<
"-------------"
471 << std::setw(20) <<
"---------------"
472 << std::setw(20) <<
"---------------"
475 hist << std::scientific << std::setprecision(11) << std::right
476 << std::setw(20) << jvCheck[i][0]
477 << std::setw(20) << jvCheck[i][1]
478 << std::setw(20) << jvCheck[i][2]
479 << std::setw(20) << jvCheck[i][3]
481 outStream << hist.str();
487 outStream.copyfmt(oldFormatState);
493 template <
class Real>
498 const bool printToStream,
499 std::ostream & outStream,
500 const int numSteps) {
501 Real tol = std::sqrt(ROL_EPSILON<Real>());
506 std::vector<Real> tmp(numVals);
507 std::vector<std::vector<Real> > ajvCheck(numSteps, tmp);
508 Real eta_factor = 1e-1;
512 Teuchos::RCP<Vector<Real> > c0 = c.
clone();
513 Teuchos::RCP<Vector<Real> > cnew = c.
clone();
514 Teuchos::RCP<Vector<Real> > xnew = x.
clone();
515 Teuchos::RCP<Vector<Real> > ajv0 = ajv.
clone();
516 Teuchos::RCP<Vector<Real> > ajv1 = ajv.
clone();
517 Teuchos::RCP<Vector<Real> > ex = x.
clone();
518 Teuchos::RCP<Vector<Real> > eajv = ajv.
clone();
521 Teuchos::oblackholestream oldFormatState;
522 oldFormatState.copyfmt(outStream);
526 this->
value(*c0, x, tol);
529 this->applyAdjointJacobian(*ajv0, v, x, tol);
530 Real normAJv = ajv0->norm();
532 for (
int i=0; i<numSteps; i++) {
536 for (
int j = 0; j < ajv.
dimension(); j++ ) {
542 this->
value(*cnew,*xnew,tol);
543 cnew->axpy(-one,*c0);
544 cnew->scale(one/eta);
545 ajv1->axpy(cnew->dot(v.
dual()),*eajv);
549 ajvCheck[i][0] = eta;
550 ajvCheck[i][1] = normAJv;
551 ajvCheck[i][2] = ajv1->norm();
552 ajv1->axpy(-one, *ajv0);
553 ajvCheck[i][3] = ajv1->norm();
556 std::stringstream hist;
559 << std::setw(20) <<
"Step size"
560 << std::setw(20) <<
"norm(adj(Jac)*vec)"
561 << std::setw(20) <<
"norm(FD approx)"
562 << std::setw(20) <<
"norm(abs error)"
564 << std::setw(20) <<
"---------"
565 << std::setw(20) <<
"------------------"
566 << std::setw(20) <<
"---------------"
567 << std::setw(20) <<
"---------------"
570 hist << std::scientific << std::setprecision(11) << std::right
571 << std::setw(20) << ajvCheck[i][0]
572 << std::setw(20) << ajvCheck[i][1]
573 << std::setw(20) << ajvCheck[i][2]
574 << std::setw(20) << ajvCheck[i][3]
576 outStream << hist.str();
580 eta = eta*eta_factor;
584 outStream.copyfmt(oldFormatState);
589 template <
class Real>
595 const bool printToStream,
596 std::ostream & outStream) {
597 Real tol = ROL_EPSILON<Real>();
599 Teuchos::RCP<Vector<Real> > Jv = dualw.
clone();
600 Teuchos::RCP<Vector<Real> > Jw = dualv.
clone();
603 applyAdjointJacobian(*Jw,w,x,tol);
605 Real vJw = v.
dot(Jw->dual());
606 Real wJv = w.
dot(Jv->dual());
608 Real diff = std::abs(wJv-vJw);
610 if ( printToStream ) {
611 std::stringstream hist;
612 hist << std::scientific << std::setprecision(8);
613 hist <<
"\nTest Consistency of Jacobian and its adjoint: \n |<w,Jv> - <adj(J)w,v>| = "
615 hist <<
" |<w,Jv>| = " << std::abs(wJv) <<
"\n";
616 hist <<
" Relative Error = " << diff / (std::abs(wJv)+ROL_UNDERFLOW<Real>()) <<
"\n";
617 outStream << hist.str();
622 template <
class Real>
627 const bool printToStream,
628 std::ostream & outStream,
631 std::vector<Real> steps(numSteps);
632 for(
int i=0;i<numSteps;++i) {
633 steps[i] = pow(10,-i);
636 return checkApplyAdjointHessian(x,u,v,hv,steps,printToStream,outStream,order);
641 template <
class Real>
646 const std::vector<Real> &steps,
647 const bool printToStream,
648 std::ostream & outStream,
655 Real tol = std::sqrt(ROL_EPSILON<Real>());
657 int numSteps = steps.size();
659 std::vector<Real> tmp(numVals);
660 std::vector<std::vector<Real> > ahuvCheck(numSteps, tmp);
663 Teuchos::RCP<Vector<Real> > AJdif = hv.
clone();
664 Teuchos::RCP<Vector<Real> > AJu = hv.
clone();
665 Teuchos::RCP<Vector<Real> > AHuv = hv.
clone();
666 Teuchos::RCP<Vector<Real> > AJnew = hv.
clone();
667 Teuchos::RCP<Vector<Real> > xnew = x.
clone();
670 Teuchos::oblackholestream oldFormatState;
671 oldFormatState.copyfmt(outStream);
675 this->applyAdjointJacobian(*AJu, u, x, tol);
678 this->applyAdjointHessian(*AHuv, u, v, x, tol);
679 Real normAHuv = AHuv->norm();
681 for (
int i=0; i<numSteps; i++) {
689 AJdif->scale(
weights[order-1][0]);
691 for(
int j=0; j<order; ++j) {
693 xnew->axpy(eta*
shifts[order-1][j],v);
695 if(
weights[order-1][j+1] != 0 ) {
697 this->applyAdjointJacobian(*AJnew, u, *xnew, tol);
698 AJdif->axpy(
weights[order-1][j+1],*AJnew);
702 AJdif->scale(one/eta);
705 ahuvCheck[i][0] = eta;
706 ahuvCheck[i][1] = normAHuv;
707 ahuvCheck[i][2] = AJdif->norm();
708 AJdif->axpy(-one, *AHuv);
709 ahuvCheck[i][3] = AJdif->norm();
712 std::stringstream hist;
715 << std::setw(20) <<
"Step size"
716 << std::setw(20) <<
"norm(adj(H)(u,v))"
717 << std::setw(20) <<
"norm(FD approx)"
718 << std::setw(20) <<
"norm(abs error)"
720 << std::setw(20) <<
"---------"
721 << std::setw(20) <<
"-----------------"
722 << std::setw(20) <<
"---------------"
723 << std::setw(20) <<
"---------------"
726 hist << std::scientific << std::setprecision(11) << std::right
727 << std::setw(20) << ahuvCheck[i][0]
728 << std::setw(20) << ahuvCheck[i][1]
729 << std::setw(20) << ahuvCheck[i][2]
730 << std::setw(20) << ahuvCheck[i][3]
732 outStream << hist.str();
738 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 int dimension() const
Return dimension of the vector space.
virtual void plus(const Vector &x)=0
Compute , where .
const double weights[4][5]
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
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 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 > > 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 Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
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 .
void applyJacobian(ROL::Vector< Real > &jv, const ROL::Vector< Real > &v, const ROL::Vector< Real > &sol)
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< 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 where , , , , is an identity or Riesz operator...
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 applyJacobian(Vector< Real > &jv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply the constraint Jacobian at , , to vector .
void value(ROL::Vector< Real > &c, const ROL::Vector< Real > &sol, const Real &mu)
virtual Teuchos::RCP< Vector > basis(const int i) const
Return i-th basis vector.
virtual Real norm() const =0
Returns where .
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. ...