ROL
ROL_AbsoluteValue.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_ABSOLUTEVALUE_HPP
11#define ROL_ABSOLUTEVALUE_HPP
12
13#include "ROL_Types.hpp"
15#include "ROL_ParameterList.hpp"
16
17namespace ROL {
18
26
27template<class Real>
28class AbsoluteValue : public PositiveFunction<Real> {
29private:
30 Real param_;
32
33public:
35 : param_(1./param), eav_(eav) {
36 if ( eav != ABSOLUTEVALUE_TRUE && std::abs(param) < ROL_EPSILON<Real>() ) { param_ = 1.e2; }
37 }
38
39 AbsoluteValue(ROL::ParameterList &parlist) {
40 Real param = parlist.get("Smoothing Parameter",1.);
41 param_ = 1./((param > 0.) ? param : 1.);
42 std::string type = parlist.get("Absolute Value Approximation","true");
44 if ( type == "Square Root" ) { eav_ = ABSOLUTEVALUE_SQUAREROOT; }
45 else if ( type == "Square Root Denominator" ) { eav_ = ABSOLUTEVALUE_SQRTDENOM; }
46 else if ( type == "C2") { eav_ = ABSOLUTEVALUE_C2; }
47 else if ( type == "true") { eav_ = ABSOLUTEVALUE_TRUE; }
48 }
49
50 Real evaluate(Real input, int deriv) {
51 Real val = 0.0;
52 switch(eav_) {
53 case ABSOLUTEVALUE_TRUE: val = true_absolute_value(input,deriv); break;
54 case ABSOLUTEVALUE_SQUAREROOT: val = sqrt_absolute_value(input,deriv); break;
55 case ABSOLUTEVALUE_SQRTDENOM: val = sqrtd_absolute_value(input,deriv); break;
56 case ABSOLUTEVALUE_C2: val = c2_absolute_value(input,deriv); break;
57 default:
58 ROL_TEST_FOR_EXCEPTION( true, std::invalid_argument,
59 ">>> ERROR (ROL::AbsoluteValue): Absolute value approximation not defined!");
60 }
61 return val;
62 }
63
64private:
65 Real true_absolute_value( Real input, int deriv ) {
66 Real output = 0.0, e = 0.0;
67 if ( std::abs(param_) > ROL_EPSILON<Real>() ) { e = 0.5/param_; }
68
69 int region = 0;
70 if ( input < -e ) { region = -1; }
71 else if ( input > e ) { region = 1; }
72
73 if ( deriv == 0 ) { output = std::abs(input); }
74 else if ( deriv == 1 ) { output = (input < 0.0 ? -1.0 : 1.0); }
75 else if ( deriv == 2 ) {
76 if ( region == -1 ) { output = 0.0; }
77 else if ( region == 0 ) { output = e*std::exp( -1.0/(1.0 - std::pow(std::abs(input/e),2.0)) ); }
78 else if ( region == 1 ) { output = 0.0; }
79 }
80 return output;
81 }
82
83 Real sqrt_absolute_value( Real input, int deriv ) {
84 Real output = 0.0;
85 if ( deriv == 0 ) { output = std::sqrt(input*input + 1.0/param_); }
86 else if ( deriv == 1 ) { output = input/std::sqrt(input*input+1.0/param_); }
87 else if ( deriv == 2 ) { output = (1.0/param_)/std::pow(input*input+1.0/param_,1.5); }
88 return output;
89 }
90
91 Real sqrtd_absolute_value( Real input, int deriv ) {
92 Real output = 0.0;
93 if ( deriv == 0 ) { output = input*input/std::sqrt(input*input + 1.0/param_); }
94 else if ( deriv == 1 ) { output = (2.0/param_*input+std::pow(input,3.0)) /
95 std::pow(input*input+1.0/param_,1.5); }
96 else if ( deriv == 2 ) { output = ((2.0/param_-input*input)/param_) /
97 std::pow(input*input+1.0/param_,2.5); }
98 return output;
99 }
100
101 Real c2_absolute_value( Real input, int deriv ) {
102 Real output = 0.0, e = 1.0;
103 if ( std::abs(param_) > ROL_EPSILON<Real>() ) { e = 0.5/param_; }
104
105 int region = 0;
106 if ( input < -e ) { region = -1; }
107 else if ( input > e ) { region = 1; }
108
109 if ( deriv == 0 ) {
110 if ( std::abs(region) == 1 ) { output = std::abs(input); }
111 else if ( region == 0 ) { output = 1.875*std::pow(input*e,2.0) -
112 1.25 *std::pow(input*e,4.0) +
113 0.375*std::pow(input*e,6.0); }
114 }
115 else if ( deriv == 1 ) {
116 if ( std::abs(region) == 1 ) { output = (input < 0.0 ? -1.0 : 1.0); }
117 else if ( region == 0 ) { output = e*2.0*1.875*input*e -
118 e*4.0*1.25 *std::pow(input*e,3.0) +
119 e*6.0*0.375*std::pow(input*e,5.0); }
120 }
121 else if ( deriv == 2 ) {
122 if ( std::abs(region) == 1 ) { output = 0.0; }
123 else if ( region == 0 ) { output = e* 2.0*1.875 -
124 e*e*12.0*1.25 *std::pow(input*e,2.0) +
125 e*e*30.0*0.375*std::pow(input*e,4.0); }
126 }
127 return output;
128 }
129};
130
131}
132
133#endif
Contains definitions of custom data types in ROL.
Real true_absolute_value(Real input, int deriv)
Real c2_absolute_value(Real input, int deriv)
AbsoluteValue(Real param=1., EAbsoluteValue eav=ABSOLUTEVALUE_TRUE)
Real sqrt_absolute_value(Real input, int deriv)
Real evaluate(Real input, int deriv)
AbsoluteValue(ROL::ParameterList &parlist)
Real sqrtd_absolute_value(Real input, int deriv)
@ ABSOLUTEVALUE_SQUAREROOT
@ ABSOLUTEVALUE_SQRTDENOM