ROL
ROL_GenMoreauYosidaCVaR.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_GENMOREAUYOSIDACVAR_HPP
45 #define ROL_GENMOREAUYOSIDACVAR_HPP
46 
47 #include "ROL_ExpectationQuad.hpp"
48 
102 namespace ROL {
103 
104 template<class Real>
105 class GenMoreauYosidaCVaR : public ExpectationQuad<Real> {
106 private:
107 
108  Real prob_;
109  Real lam_;
110  Real eps_;
111 
112  Real alpha_;
113  Real beta_;
114 
115  Real omp_;
116  Real oma_;
117  Real bmo_;
118  Real lb_;
119  Real ub_;
120 
121  void checkInputs(void) const {
122  Real zero(0), one(1);
123  TEUCHOS_TEST_FOR_EXCEPTION((prob_ <= zero) || (prob_ >= one), std::invalid_argument,
124  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Confidence level must be between 0 and 1!");
125  TEUCHOS_TEST_FOR_EXCEPTION((lam_ < zero) || (lam_ > one), std::invalid_argument,
126  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Convex combination parameter must be positive!");
127  TEUCHOS_TEST_FOR_EXCEPTION((eps_ <= zero), std::invalid_argument,
128  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Smoothing parameter must be positive!");
129  }
130 
131  void setParameters(void) {
132  const Real one(1);
133  omp_ = one-prob_;
134  alpha_ = lam_;
135  beta_ = (one-alpha_*prob_)/omp_;
136  oma_ = one-alpha_;
137  bmo_ = beta_-one;
138  lb_ = -eps_*oma_;
139  ub_ = eps_*bmo_;
140  }
141 
142 public:
148  GenMoreauYosidaCVaR(Real prob, Real eps )
149  : ExpectationQuad<Real>(), prob_(prob), lam_(0), eps_(eps) {
150  checkInputs();
151  setParameters();
152  }
153 
160  GenMoreauYosidaCVaR(Real prob, Real lam, Real eps )
161  : ExpectationQuad<Real>(), prob_(prob), lam_(lam), eps_(eps) {
162  checkInputs();
163  setParameters();
164  }
165 
176  GenMoreauYosidaCVaR(Teuchos::ParameterList &parlist)
177  : ExpectationQuad<Real>() {
178  Teuchos::ParameterList& list
179  = parlist.sublist("SOL").sublist("Risk Measure").sublist("Generalized Moreau-Yosida CVaR");
180  prob_ = list.get<Real>("Confidence Level");
181  lam_ = list.get<Real>("Convex Combination Parameter");
182  eps_ = list.get<Real>("Smoothing Parameter");
183  checkInputs();
184  setParameters();
185  }
186 
187  Real error(Real x, int deriv = 0) {
188  Real zero(0), one(1);
189  Real X = ((deriv==0) ? x : ((deriv==1) ? one : zero));
190  return regret(x,deriv) - X;
191  }
192 
193  Real regret(Real x, int deriv = 0) {
194  Real zero(0), half(0.5), one(1), reg(0);
195  if ( x <= lb_ ) {
196  reg = ((deriv == 0) ? alpha_*x + half*lb_*oma_
197  : ((deriv == 1) ? alpha_ : zero));
198  }
199  else if ( x >= ub_ ) {
200  reg = ((deriv == 0) ? beta_*x - half*ub_*bmo_
201  : ((deriv == 1) ? beta_ : zero));
202  }
203  else {
204  reg = ((deriv == 0) ? half/eps_*x*x + x
205  : ((deriv == 1) ? x/eps_ + one : one/eps_));
206  }
207  return reg;
208  }
209 
210  void checkRegret(void) {
212  Real zero(0), one(1), two(2), p1(0.1);
213  // Check v'(ub)
214  Real x = ub_;
215  Real vx = zero, vy = zero;
216  Real dv = regret(x,1);
217  Real t = one;
218  Real diff = zero;
219  Real err = zero;
220  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(ub) 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,0);
228  vx = regret(x-t,0);
229  diff = (vy-vx)/(two*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 *= p1;
238  }
239  std::cout << "\n";
240  // check v''(ub)
241  vx = zero;
242  vy = zero;
243  dv = regret(x,2);
244  t = one;
245  diff = zero;
246  err = zero;
247  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(ub) is correct? \n";
248  std::cout << std::right << std::setw(20) << "t"
249  << std::setw(20) << "v''(x)"
250  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
251  << std::setw(20) << "Error"
252  << "\n";
253  for (int i = 0; i < 13; i++) {
254  vy = regret(x+t,1);
255  vx = regret(x-t,1);
256  diff = (vy-vx)/(two*t);
257  err = std::abs(diff-dv);
258  std::cout << std::scientific << std::setprecision(11) << std::right
259  << std::setw(20) << t
260  << std::setw(20) << dv
261  << std::setw(20) << diff
262  << std::setw(20) << err
263  << "\n";
264  t *= p1;
265  }
266  std::cout << "\n";
267  // Check v'(0)
268  x = zero;
269  vx = zero;
270  vy = zero;
271  dv = regret(x,1);
272  t = one;
273  diff = zero;
274  err = zero;
275  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(0) 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,0);
283  vx = regret(x-t,0);
284  diff = (vy-vx)/(two*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 *= p1;
293  }
294  std::cout << "\n";
295  // check v''(0)
296  vx = zero;
297  vy = zero;
298  dv = regret(x,2);
299  t = one;
300  diff = zero;
301  err = zero;
302  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(0) is correct? \n";
303  std::cout << std::right << std::setw(20) << "t"
304  << std::setw(20) << "v''(x)"
305  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
306  << std::setw(20) << "Error"
307  << "\n";
308  for (int i = 0; i < 13; i++) {
309  vy = regret(x+t,1);
310  vx = regret(x-t,1);
311  diff = (vy-vx)/(two*t);
312  err = std::abs(diff-dv);
313  std::cout << std::scientific << std::setprecision(11) << std::right
314  << std::setw(20) << t
315  << std::setw(20) << dv
316  << std::setw(20) << diff
317  << std::setw(20) << err
318  << "\n";
319  t *= p1;
320  }
321  std::cout << "\n";
322  // Check v'(lb)
323  x = lb_;
324  vx = zero;
325  vy = zero;
326  dv = regret(x,1);
327  t = one;
328  diff = zero;
329  err = zero;
330  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(lb) is correct? \n";
331  std::cout << std::right << std::setw(20) << "t"
332  << std::setw(20) << "v'(x)"
333  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
334  << std::setw(20) << "Error"
335  << "\n";
336  for (int i = 0; i < 13; i++) {
337  vy = regret(x+t,0);
338  vx = regret(x-t,0);
339  diff = (vy-vx)/(two*t);
340  err = std::abs(diff-dv);
341  std::cout << std::scientific << std::setprecision(11) << std::right
342  << std::setw(20) << t
343  << std::setw(20) << dv
344  << std::setw(20) << diff
345  << std::setw(20) << err
346  << "\n";
347  t *= p1;
348  }
349  std::cout << "\n";
350  // check v''(lb)
351  vx = zero;
352  vy = zero;
353  dv = regret(x,2);
354  t = one;
355  diff = zero;
356  err = zero;
357  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(lb) is correct? \n";
358  std::cout << std::right << std::setw(20) << "t"
359  << std::setw(20) << "v''(x)"
360  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
361  << std::setw(20) << "Error"
362  << "\n";
363  for (int i = 0; i < 13; i++) {
364  vy = regret(x+t,1);
365  vx = regret(x-t,1);
366  diff = (vy-vx)/(two*t);
367  err = std::abs(diff-dv);
368  std::cout << std::scientific << std::setprecision(11) << std::right
369  << std::setw(20) << t
370  << std::setw(20) << dv
371  << std::setw(20) << diff
372  << std::setw(20) << err
373  << "\n";
374  t *= p1;
375  }
376  std::cout << "\n";
377  }
378 
379 };
380 
381 }
382 #endif
Provides a general interface for risk measures generated through the expectation risk quadrangle...
virtual void checkRegret(void)
Run default derivative tests for the scalar regret function.
Real regret(Real x, int deriv=0)
Evaluate the scalar regret function at x.
Real error(Real x, int deriv=0)
GenMoreauYosidaCVaR(Real prob, Real eps)
Constructor.
GenMoreauYosidaCVaR(Real prob, Real lam, Real eps)
Constructor.
void checkRegret(void)
Run default derivative tests for the scalar regret function.
GenMoreauYosidaCVaR(Teuchos::ParameterList &parlist)
Constructor.