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