44 #ifndef ROL_COLEMANLIMODEL_HPP
45 #define ROL_COLEMANLIMODEL_HPP
75 Elementwise::Multiply<Real>
mult_;
76 Elementwise::Divide<Real>
div_;
102 Cmat_->set(gc->dual());
103 Cmat_->applyUnary(Elementwise::Sign<Real>());
105 class NegGradInfU :
public Elementwise::BinaryFunction<Real> {
108 Real
apply(
const Real &x,
const Real &y)
const {
109 const Real
zero(0), one(1), INF(ROL_INF<Real>());
110 return (x <
zero && y == INF) ?
zero : one;
113 prim_->set(gc->dual());
114 prim_->applyBinary(NegGradInfU(), *u);
117 class PosGradNinfL :
public Elementwise::BinaryFunction<Real> {
119 PosGradNinfL(
void) {}
120 Real
apply(
const Real &x,
const Real &y)
const {
121 const Real
zero(0), one(1), NINF(ROL_NINF<Real>());
122 return (x >=
zero && y == NINF) ?
zero : one;
125 prim_->set(gc->dual());
126 prim_->applyBinary(PosGradNinfL(), *l);
137 const Real
zero(0), one(1), INF(ROL_INF<Real>()), NINF(ROL_NINF<Real>());
138 const int LESS_THAN = 0;
139 const int EQUAL_TO = 1;
140 const int GREATER_THAN = 2;
145 reflectStep_->applyBinary(Elementwise::ValueSet<Real>(
zero, LESS_THAN),gc->dual());
147 reflectScal_->applyBinary(Elementwise::ValueSet<Real>(INF, LESS_THAN),*u);
159 reflectScal_->applyBinary(Elementwise::ValueSet<Real>(INF, EQUAL_TO),*u);
164 prim_->applyUnary(Elementwise::Fill<Real>(-one));
172 reflectStep_->applyUnary(Elementwise::Shift<Real>(one));
174 reflectScal_->applyBinary(Elementwise::ValueSet<Real>(NINF, GREATER_THAN),*l);
186 reflectScal_->applyBinary(Elementwise::ValueSet<Real>(NINF, EQUAL_TO),*l);
191 prim_->applyUnary(Elementwise::Fill<Real>(one));
200 Dmat_->applyUnary(Elementwise::AbsoluteValue<Real>());
201 Dmat_->applyUnary(Elementwise::SquareRoot<Real>());
225 const Real stepBackMax = 0.9999,
const Real stepBackScale = 1.0,
226 const bool singleReflect =
true,
228 const bool useSecantPrecond =
false,
const bool useSecantHessVec =
false)
255 hv_->scale(static_cast<Real>(0.5));
289 Real tol = std::sqrt(ROL_EPSILON<Real>());
296 Real lowerBoundV(ROL_NINF<Real>()), upperBoundV(ROL_INF<Real>());
300 Real valueV =
minimize1D(tauV, lowerBoundV, upperBoundV, v);
318 Real lowerBoundR(ROL_NINF<Real>()), upperBoundR(ROL_INF<Real>());
328 bool useCauchyPoint = (valueG < valueV);
329 if (useCauchyPoint) {
342 bool useReflectStep = (valueR < VALUE);
343 if (useReflectStep) {
357 Real snorm =
step_->norm();
389 Real pnorm = p.
norm();
392 class PruneNegative :
public Elementwise::BinaryFunction<Real> {
396 PruneNegative(
const Real val ) : val_(val) {}
397 Real
apply(
const Real &x,
const Real &y)
const {
398 return (y < static_cast<Real>(0)) ? x/y : val_;
401 class PrunePositive :
public Elementwise::BinaryFunction<Real> {
405 PrunePositive(
const Real val ) : val_(val) {}
406 Real
apply(
const Real &x,
const Real &y)
const {
407 return (y > static_cast<Real>(0)) ? x/y : val_;
413 prim_->applyBinary(PrunePositive(ROL_NINF<Real>()),p);
414 Real lowerBound1 =
prim_->reduce(Elementwise::ReductionMax<Real>());
417 prim_->applyBinary(PruneNegative(ROL_NINF<Real>()),p);
418 Real lowerBound2 =
prim_->reduce(Elementwise::ReductionMax<Real>());
420 Real lowerBound3 = std::max(lowerBound1, lowerBound2);
424 prim_->applyBinary(PrunePositive(ROL_INF<Real>()),p);
425 Real upperBound1 =
prim_->reduce(Elementwise::ReductionMin<Real>());
428 prim_->applyBinary(PruneNegative(ROL_INF<Real>()),p);
429 Real upperBound2 =
prim_->reduce(Elementwise::ReductionMin<Real>());
431 Real upperBound3 = std::min(upperBound1, upperBound2);
434 lowerBound = std::max(lowerBound3, -
TRradius_/pnorm);
435 upperBound = std::min(upperBound3,
TRradius_/pnorm);
440 Real tol = std::sqrt(ROL_EPSILON<Real>());
444 Real c2 = static_cast<Real>(0.5) *
hv_->dot(p.
dual());
446 Real c1 =
prim_->dot(p);
449 Real lval = (c2 * lowerBound + c1) * lowerBound;
450 Real rval = (c2 * upperBound + c1) * upperBound;
451 tau = (lval < rval) ? lowerBound : upperBound;
452 if (c2 > static_cast<Real>(0)) {
453 Real uncMin = static_cast<Real>(-0.5) * c1/c2;
454 tau = (uncMin > lowerBound && uncMin < upperBound) ? uncMin : tau;
458 return (c2 * tau + c1) * tau;
471 Real lowerBound(ROL_NINF<Real>()), upperBound(ROL_INF<Real>());
475 Real tau(1),
value(0);
489 class LowerBound :
public Elementwise::BinaryFunction<Real> {
491 Real
apply(
const Real &x,
const Real &y )
const {
492 return (x == y) ? static_cast<Real>(-1) : static_cast<Real>(1);
499 class UpperBound :
public Elementwise::BinaryFunction<Real> {
501 Real
apply(
const Real &x,
const Real &y )
const {
502 return (x == y) ? static_cast<Real>(-1) : static_cast<Real>(1);
514 class LowerBound :
public Elementwise::BinaryFunction<Real> {
516 Real
apply(
const Real &x,
const Real &y )
const {
517 return (x < y) ? static_cast<Real>(-1) : static_cast<Real>(1);
524 class UpperBound :
public Elementwise::BinaryFunction<Real> {
526 Real
apply(
const Real &x,
const Real &y )
const {
527 return (x > y) ? static_cast<Real>(-1) : static_cast<Real>(1);
540 class SafeDivide :
public Elementwise::BinaryFunction<Real> {
544 SafeDivide(
const Real val ) : val_(val) {}
545 Real
apply(
const Real &x,
const Real &y)
const {
547 return (y ==
zero) ? val_ : x/y;
553 lx_->axpy(-one, *xc);
554 lx_->applyBinary(SafeDivide(ROL_INF<Real>()), d);
558 ux_->axpy(-one, *xc);
559 ux_->applyBinary(SafeDivide(ROL_INF<Real>()), d);
562 lx_->applyBinary(Elementwise::Max<Real>(),*
ux_);
565 return lx_->reduce(Elementwise::ReductionMin<Real>());
571 class Greater :
public Elementwise::BinaryFunction<Real> {
574 Real
apply(
const Real &x,
const Real &y)
const {
575 return (x > y) ? static_cast<Real>(1) : static_cast<Real>(0);
580 Real lowerFeasible =
prim_->reduce(Elementwise::ReductionMin<Real>());
582 class Lesser :
public Elementwise::BinaryFunction<Real> {
585 Real
apply(
const Real &x,
const Real &y)
const {
586 return (x < y) ? static_cast<Real>(1) : static_cast<Real>(0);
591 Real upperFeasible =
prim_->reduce(Elementwise::ReductionMin<Real>());
593 return (upperFeasible * lowerFeasible > 0);
600 #endif // ROL_COLEMANLIMODEL_HPP