ROL
ROL_AbsoluteValue.hpp
Go to the documentation of this file.
1// @HEADER
2// ************************************************************************
3//
4// Rapid Optimization Library (ROL) Package
5// Copyright (2014) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact lead developers:
38// Drew Kouri (dpkouri@sandia.gov) and
39// Denis Ridzal (dridzal@sandia.gov)
40//
41// ************************************************************************
42// @HEADER
43
44#ifndef ROL_ABSOLUTEVALUE_HPP
45#define ROL_ABSOLUTEVALUE_HPP
46
47#include "ROL_Types.hpp"
49
50namespace ROL {
51
58};
59
60template<class Real>
61class AbsoluteValue : public PositiveFunction<Real> {
62private:
63 Real param_;
65
66public:
68 : param_(1./param), eav_(eav) {
69 if ( eav != ABSOLUTEVALUE_TRUE && std::abs(param) < ROL_EPSILON<Real>() ) { param_ = 1.e2; }
70 }
71
72 AbsoluteValue(ROL::ParameterList &parlist) {
73 Real param = parlist.get("Smoothing Parameter",1.);
74 param_ = 1./((param > 0.) ? param : 1.);
75 std::string type = parlist.get("Absolute Value Approximation","true");
77 if ( type == "Square Root" ) { eav_ = ABSOLUTEVALUE_SQUAREROOT; }
78 else if ( type == "Square Root Denominator" ) { eav_ = ABSOLUTEVALUE_SQRTDENOM; }
79 else if ( type == "C2") { eav_ = ABSOLUTEVALUE_C2; }
80 else if ( type == "true") { eav_ = ABSOLUTEVALUE_TRUE; }
81 }
82
83 Real evaluate(Real input, int deriv) {
84 Real val = 0.0;
85 switch(eav_) {
86 case ABSOLUTEVALUE_TRUE: val = true_absolute_value(input,deriv); break;
87 case ABSOLUTEVALUE_SQUAREROOT: val = sqrt_absolute_value(input,deriv); break;
88 case ABSOLUTEVALUE_SQRTDENOM: val = sqrtd_absolute_value(input,deriv); break;
89 case ABSOLUTEVALUE_C2: val = c2_absolute_value(input,deriv); break;
90 default:
91 ROL_TEST_FOR_EXCEPTION( true, std::invalid_argument,
92 ">>> ERROR (ROL::AbsoluteValue): Absolute value approximation not defined!");
93 }
94 return val;
95 }
96
97private:
98 Real true_absolute_value( Real input, int deriv ) {
99 Real output = 0.0, e = 0.0;
100 if ( std::abs(param_) > ROL_EPSILON<Real>() ) { e = 0.5/param_; }
101
102 int region = 0;
103 if ( input < -e ) { region = -1; }
104 else if ( input > e ) { region = 1; }
105
106 if ( deriv == 0 ) { output = std::abs(input); }
107 else if ( deriv == 1 ) { output = (input < 0.0 ? -1.0 : 1.0); }
108 else if ( deriv == 2 ) {
109 if ( region == -1 ) { output = 0.0; }
110 else if ( region == 0 ) { output = e*std::exp( -1.0/(1.0 - std::pow(std::abs(input/e),2.0)) ); }
111 else if ( region == 1 ) { output = 0.0; }
112 }
113 return output;
114 }
115
116 Real sqrt_absolute_value( Real input, int deriv ) {
117 Real output = 0.0;
118 if ( deriv == 0 ) { output = std::sqrt(input*input + 1.0/param_); }
119 else if ( deriv == 1 ) { output = input/std::sqrt(input*input+1.0/param_); }
120 else if ( deriv == 2 ) { output = (1.0/param_)/std::pow(input*input+1.0/param_,1.5); }
121 return output;
122 }
123
124 Real sqrtd_absolute_value( Real input, int deriv ) {
125 Real output = 0.0;
126 if ( deriv == 0 ) { output = input*input/std::sqrt(input*input + 1.0/param_); }
127 else if ( deriv == 1 ) { output = (2.0/param_*input+std::pow(input,3.0)) /
128 std::pow(input*input+1.0/param_,1.5); }
129 else if ( deriv == 2 ) { output = ((2.0/param_-input*input)/param_) /
130 std::pow(input*input+1.0/param_,2.5); }
131 return output;
132 }
133
134 Real c2_absolute_value( Real input, int deriv ) {
135 Real output = 0.0, e = 1.0;
136 if ( std::abs(param_) > ROL_EPSILON<Real>() ) { e = 0.5/param_; }
137
138 int region = 0;
139 if ( input < -e ) { region = -1; }
140 else if ( input > e ) { region = 1; }
141
142 if ( deriv == 0 ) {
143 if ( std::abs(region) == 1 ) { output = std::abs(input); }
144 else if ( region == 0 ) { output = 1.875*std::pow(input*e,2.0) -
145 1.25 *std::pow(input*e,4.0) +
146 0.375*std::pow(input*e,6.0); }
147 }
148 else if ( deriv == 1 ) {
149 if ( std::abs(region) == 1 ) { output = (input < 0.0 ? -1.0 : 1.0); }
150 else if ( region == 0 ) { output = e*2.0*1.875*input*e -
151 e*4.0*1.25 *std::pow(input*e,3.0) +
152 e*6.0*0.375*std::pow(input*e,5.0); }
153 }
154 else if ( deriv == 2 ) {
155 if ( std::abs(region) == 1 ) { output = 0.0; }
156 else if ( region == 0 ) { output = e* 2.0*1.875 -
157 e*e*12.0*1.25 *std::pow(input*e,2.0) +
158 e*e*30.0*0.375*std::pow(input*e,4.0); }
159 }
160 return output;
161 }
162};
163
164}
165
166#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_C2
@ ABSOLUTEVALUE_LAST
@ ABSOLUTEVALUE_TRUE
@ ABSOLUTEVALUE_SQRTDENOM