ROL
ROL_CVaRQuadrangle.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_SMOOTHCVARQUAD_HPP
45 #define ROL_SMOOTHCVARQUAD_HPP
46 
47 #include "ROL_ExpectationQuad.hpp"
48 #include "ROL_PlusFunction.hpp"
49 
50 namespace ROL {
51 
52 template<class Real>
53 class CVaRQuadrangle : public ExpectationQuad<Real> {
54 private:
55 
56  Teuchos::RCP<PlusFunction<Real> > pf_;
57 
58  Real prob_;
59  Real eps_;
60 
61 public:
62 
63  CVaRQuadrangle(Real prob, Real eps, Teuchos::RCP<PlusFunction<Real> > &pf )
64  : ExpectationQuad<Real>(), pf_(pf) {
65  prob_ = ((prob >= 0.0) ? ((prob <= 1.0) ? prob : 0.5) : 0.5);
66  eps_ = ((eps > 0.0) ? eps : 1.0);
67  }
68 
69  Real error(Real x, int deriv = 0) {
70  Real err = (prob_/(1.0-prob_))*pf_->evaluate(x,deriv)
71  + ((deriv%2) ? -1.0 : 1.0)*pf_->evaluate(-x,deriv);
72  return err;
73  }
74 
75  Real regret(Real x, int deriv = 0) {
76  Real X = ((deriv==0) ? x : ((deriv==1) ? 1.0 : 0.0));
77  Real reg = error(x,deriv) + X;
78  return reg;
79  }
80 
81 /*
82  // This is derived from a smoothed Koenker-Bassett error function
83  Real regret(Real x, int deriv = 0) {
84  int dom = ((x >= eps_) ? 0 : ((x < eps_ && x >= 0.0) ? 1 : ((x < 0.0 && x > -eps_) ? 2 : 3)));
85 
86  Real val = 0.0;
87  Real c1 = prob_/(1.0-prob_);
88  Real c2 = 1.0/(1.0-prob_);
89  Real x2 = x*x;
90  Real x3 = x*x2;
91  Real x4 = x*x3;
92  Real e1 = eps_*0.5;
93  Real e2 = eps_*eps_;
94  Real e3 = e2*eps_*2.0;
95  switch (dom) {
96  case 0: // x is greater than or equal to eps
97  switch (deriv) {
98  case 0: val = c2*x - c1*e1; break;
99  case 1: val = c2; break;
100  case 2: val = 0.0; break;
101  }
102  break;
103  case 1: // x is between 0 and eps
104  switch (deriv) {
105  case 0: val = c1*(x3/e2 - x4/e3) + x; break;
106  case 1: val = c1*(3.0*x2/e2 - 4.0*x3/e3) + 1.0; break;
107  case 2: val = c1*(6.0*x/e2 - 12.0*x2/e3); break;
108  }
109  break;
110  case 2: // x is between -eps and 0
111  switch (deriv) {
112  case 0: val = (-x3/e2 - x4/e3) + x; break;
113  case 1: val = (-3.0*x2/e2 - 4.0*x3/e3) + 1.0; break;
114  case 2: val = (-6.0*x/e2 - 12.0*x2/e3); break;
115  }
116  break;
117  case 3: // x is less than or equal to eps
118  switch (deriv) {
119  case 0: val = -e1; break;
120  case 1: val = 0.0; break;
121  case 2: val = 0.0; break;
122  }
123  break;
124  }
125  return val;
126  }
127 */
128 
129  void checkRegret(void) {
131  // Check v'(eps)
132  Real x = eps_;
133  Real vx = 0.0, vy = 0.0;
134  Real dv = regret(x,1);
135  Real t = 1.0;
136  Real diff = 0.0;
137  Real err = 0.0;
138  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(eps) is correct? \n";
139  std::cout << std::right << std::setw(20) << "t"
140  << std::setw(20) << "v'(x)"
141  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
142  << std::setw(20) << "Error"
143  << "\n";
144  for (int i = 0; i < 13; i++) {
145  vy = regret(x+t,0);
146  vx = regret(x-t,0);
147  diff = (vy-vx)/(2.0*t);
148  err = std::abs(diff-dv);
149  std::cout << std::scientific << std::setprecision(11) << std::right
150  << std::setw(20) << t
151  << std::setw(20) << dv
152  << std::setw(20) << diff
153  << std::setw(20) << err
154  << "\n";
155  t *= 0.1;
156  }
157  std::cout << "\n";
158  // check v''(eps)
159  vx = 0.0;
160  vy = 0.0;
161  dv = regret(x,2);
162  t = 1.0;
163  diff = 0.0;
164  err = 0.0;
165  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(eps) is correct? \n";
166  std::cout << std::right << std::setw(20) << "t"
167  << std::setw(20) << "v''(x)"
168  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
169  << std::setw(20) << "Error"
170  << "\n";
171  for (int i = 0; i < 13; i++) {
172  vy = regret(x+t,1);
173  vx = regret(x-t,1);
174  diff = (vy-vx)/(2.0*t);
175  err = std::abs(diff-dv);
176  std::cout << std::scientific << std::setprecision(11) << std::right
177  << std::setw(20) << t
178  << std::setw(20) << dv
179  << std::setw(20) << diff
180  << std::setw(20) << err
181  << "\n";
182  t *= 0.1;
183  }
184  std::cout << "\n";
185  // Check v'(0)
186  x = 0.0;
187  vx = 0.0;
188  vy = 0.0;
189  dv = regret(x,1);
190  t = 1.0;
191  diff = 0.0;
192  err = 0.0;
193  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(0) is correct? \n";
194  std::cout << std::right << std::setw(20) << "t"
195  << std::setw(20) << "v'(x)"
196  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
197  << std::setw(20) << "Error"
198  << "\n";
199  for (int i = 0; i < 13; i++) {
200  vy = regret(x+t,0);
201  vx = regret(x-t,0);
202  diff = (vy-vx)/(2.0*t);
203  err = std::abs(diff-dv);
204  std::cout << std::scientific << std::setprecision(11) << std::right
205  << std::setw(20) << t
206  << std::setw(20) << dv
207  << std::setw(20) << diff
208  << std::setw(20) << err
209  << "\n";
210  t *= 0.1;
211  }
212  std::cout << "\n";
213  // check v''(eps)
214  vx = 0.0;
215  vy = 0.0;
216  dv = regret(x,2);
217  t = 1.0;
218  diff = 0.0;
219  err = 0.0;
220  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(0) is correct? \n";
221  std::cout << std::right << std::setw(20) << "t"
222  << std::setw(20) << "v''(x)"
223  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
224  << std::setw(20) << "Error"
225  << "\n";
226  for (int i = 0; i < 13; i++) {
227  vy = regret(x+t,1);
228  vx = regret(x-t,1);
229  diff = (vy-vx)/(2.0*t);
230  err = std::abs(diff-dv);
231  std::cout << std::scientific << std::setprecision(11) << std::right
232  << std::setw(20) << t
233  << std::setw(20) << dv
234  << std::setw(20) << diff
235  << std::setw(20) << err
236  << "\n";
237  t *= 0.1;
238  }
239  std::cout << "\n";
240  // Check v'(0)
241  x = -eps_;
242  vx = 0.0;
243  vy = 0.0;
244  dv = regret(x,1);
245  t = 1.0;
246  diff = 0.0;
247  err = 0.0;
248  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(-eps) is correct? \n";
249  std::cout << std::right << std::setw(20) << "t"
250  << std::setw(20) << "v'(x)"
251  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
252  << std::setw(20) << "Error"
253  << "\n";
254  for (int i = 0; i < 13; i++) {
255  vy = regret(x+t,0);
256  vx = regret(x-t,0);
257  diff = (vy-vx)/(2.0*t);
258  err = std::abs(diff-dv);
259  std::cout << std::scientific << std::setprecision(11) << std::right
260  << std::setw(20) << t
261  << std::setw(20) << dv
262  << std::setw(20) << diff
263  << std::setw(20) << err
264  << "\n";
265  t *= 0.1;
266  }
267  std::cout << "\n";
268  // check v''(eps)
269  vx = 0.0;
270  vy = 0.0;
271  dv = regret(x,2);
272  t = 1.0;
273  diff = 0.0;
274  err = 0.0;
275  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(-eps) is correct? \n";
276  std::cout << std::right << std::setw(20) << "t"
277  << std::setw(20) << "v''(x)"
278  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
279  << std::setw(20) << "Error"
280  << "\n";
281  for (int i = 0; i < 13; i++) {
282  vy = regret(x+t,1);
283  vx = regret(x-t,1);
284  diff = (vy-vx)/(2.0*t);
285  err = std::abs(diff-dv);
286  std::cout << std::scientific << std::setprecision(11) << std::right
287  << std::setw(20) << t
288  << std::setw(20) << dv
289  << std::setw(20) << diff
290  << std::setw(20) << err
291  << "\n";
292  t *= 0.1;
293  }
294  std::cout << "\n";
295  }
296 
297 };
298 
299 }
300 #endif
Real regret(Real x, int deriv=0)
virtual void checkRegret(void)
Real error(Real x, int deriv=0)
Teuchos::RCP< PlusFunction< Real > > pf_
CVaRQuadrangle(Real prob, Real eps, Teuchos::RCP< PlusFunction< Real > > &pf)