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 parseParameterList(ROL::ParameterList &parlist) {
122  std::string type = parlist.sublist("SOL").get("Stochastic Component Type","Risk Averse");
123  ROL::ParameterList list;
124  if (type == "Risk Averse") {
125  list = parlist.sublist("SOL").sublist("Risk Measure").sublist("Generalized Moreau-Yosida CVaR");
126  }
127  else if (type == "Error") {
128  list = parlist.sublist("SOL").sublist("Error Measure").sublist("Generalized Moreau-Yosida-Koenker-Bassett");
129  }
130  else if (type == "Deviation") {
131  list = parlist.sublist("SOL").sublist("Deviation Measure").sublist("Generalized Moreau-Yosida CVaR");
132  }
133  else if (type == "Regret") {
134  list = parlist.sublist("SOL").sublist("Regret Measure").sublist("Generalized Moreau-Yosida Mean Absolute Loss");
135  }
136  prob_ = list.get<Real>("Confidence Level");
137  lam_ = list.get<Real>("Convex Combination Parameter");
138  eps_ = list.get<Real>("Smoothing Parameter");
139  }
140 
141  void checkInputs(void) const {
142  Real zero(0), one(1);
143  ROL_TEST_FOR_EXCEPTION((prob_ <= zero) || (prob_ >= one), std::invalid_argument,
144  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Confidence level must be between 0 and 1!");
145  ROL_TEST_FOR_EXCEPTION((lam_ < zero) || (lam_ > one), std::invalid_argument,
146  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Convex combination parameter must be positive!");
147  ROL_TEST_FOR_EXCEPTION((eps_ <= zero), std::invalid_argument,
148  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Smoothing parameter must be positive!");
149  }
150 
151  void setParameters(void) {
152  const Real one(1);
153  omp_ = one-prob_;
154  alpha_ = lam_;
155  beta_ = (one-alpha_*prob_)/omp_;
156  oma_ = one-alpha_;
157  bmo_ = beta_-one;
158  lb_ = -eps_*oma_;
159  ub_ = eps_*bmo_;
160  }
161 
162 public:
168  GenMoreauYosidaCVaR(Real prob, Real eps )
169  : ExpectationQuad<Real>(), prob_(prob), lam_(0), eps_(eps) {
170  checkInputs();
171  setParameters();
172  }
173 
180  GenMoreauYosidaCVaR(Real prob, Real lam, Real eps )
181  : ExpectationQuad<Real>(), prob_(prob), lam_(lam), eps_(eps) {
182  checkInputs();
183  setParameters();
184  }
185 
196  GenMoreauYosidaCVaR(ROL::ParameterList &parlist)
197  : ExpectationQuad<Real>() {
198  parseParameterList(parlist);
199  checkInputs();
200  setParameters();
201  }
202 
203  Real error(Real x, int deriv = 0) {
204  Real zero(0), one(1);
205  Real X = ((deriv==0) ? x : ((deriv==1) ? one : zero));
206  return regret(x,deriv) - X;
207  }
208 
209  Real regret(Real x, int deriv = 0) {
210  Real zero(0), half(0.5), one(1), reg(0);
211  if ( x <= lb_ ) {
212  reg = ((deriv == 0) ? alpha_*x + half*lb_*oma_
213  : ((deriv == 1) ? alpha_ : zero));
214  }
215  else if ( x >= ub_ ) {
216  reg = ((deriv == 0) ? beta_*x - half*ub_*bmo_
217  : ((deriv == 1) ? beta_ : zero));
218  }
219  else {
220  reg = ((deriv == 0) ? half/eps_*x*x + x
221  : ((deriv == 1) ? x/eps_ + one : one/eps_));
222  }
223  return reg;
224  }
225 
226  void check(void) {
228  Real zero(0), one(1), two(2), p1(0.1);
229  // Check v'(ub)
230  Real x = ub_;
231  Real vx = zero, vy = zero;
232  Real dv = regret(x,1);
233  Real t = one;
234  Real diff = zero;
235  Real err = zero;
236  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(ub) is correct? \n";
237  std::cout << std::right << std::setw(20) << "t"
238  << std::setw(20) << "v'(x)"
239  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
240  << std::setw(20) << "Error"
241  << "\n";
242  for (int i = 0; i < 13; i++) {
243  vy = regret(x+t,0);
244  vx = regret(x-t,0);
245  diff = (vy-vx)/(two*t);
246  err = std::abs(diff-dv);
247  std::cout << std::scientific << std::setprecision(11) << std::right
248  << std::setw(20) << t
249  << std::setw(20) << dv
250  << std::setw(20) << diff
251  << std::setw(20) << err
252  << "\n";
253  t *= p1;
254  }
255  std::cout << "\n";
256  // check v''(ub)
257  vx = zero;
258  vy = zero;
259  dv = regret(x,2);
260  t = one;
261  diff = zero;
262  err = zero;
263  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(ub) is correct? \n";
264  std::cout << std::right << std::setw(20) << "t"
265  << std::setw(20) << "v''(x)"
266  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
267  << std::setw(20) << "Error"
268  << "\n";
269  for (int i = 0; i < 13; i++) {
270  vy = regret(x+t,1);
271  vx = regret(x-t,1);
272  diff = (vy-vx)/(two*t);
273  err = std::abs(diff-dv);
274  std::cout << std::scientific << std::setprecision(11) << std::right
275  << std::setw(20) << t
276  << std::setw(20) << dv
277  << std::setw(20) << diff
278  << std::setw(20) << err
279  << "\n";
280  t *= p1;
281  }
282  std::cout << "\n";
283  // Check v'(0)
284  x = zero;
285  vx = zero;
286  vy = zero;
287  dv = regret(x,1);
288  t = one;
289  diff = zero;
290  err = zero;
291  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(0) is correct? \n";
292  std::cout << std::right << std::setw(20) << "t"
293  << std::setw(20) << "v'(x)"
294  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
295  << std::setw(20) << "Error"
296  << "\n";
297  for (int i = 0; i < 13; i++) {
298  vy = regret(x+t,0);
299  vx = regret(x-t,0);
300  diff = (vy-vx)/(two*t);
301  err = std::abs(diff-dv);
302  std::cout << std::scientific << std::setprecision(11) << std::right
303  << std::setw(20) << t
304  << std::setw(20) << dv
305  << std::setw(20) << diff
306  << std::setw(20) << err
307  << "\n";
308  t *= p1;
309  }
310  std::cout << "\n";
311  // check v''(0)
312  vx = zero;
313  vy = zero;
314  dv = regret(x,2);
315  t = one;
316  diff = zero;
317  err = zero;
318  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(0) is correct? \n";
319  std::cout << std::right << std::setw(20) << "t"
320  << std::setw(20) << "v''(x)"
321  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
322  << std::setw(20) << "Error"
323  << "\n";
324  for (int i = 0; i < 13; i++) {
325  vy = regret(x+t,1);
326  vx = regret(x-t,1);
327  diff = (vy-vx)/(two*t);
328  err = std::abs(diff-dv);
329  std::cout << std::scientific << std::setprecision(11) << std::right
330  << std::setw(20) << t
331  << std::setw(20) << dv
332  << std::setw(20) << diff
333  << std::setw(20) << err
334  << "\n";
335  t *= p1;
336  }
337  std::cout << "\n";
338  // Check v'(lb)
339  x = lb_;
340  vx = zero;
341  vy = zero;
342  dv = regret(x,1);
343  t = one;
344  diff = zero;
345  err = zero;
346  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(lb) is correct? \n";
347  std::cout << std::right << std::setw(20) << "t"
348  << std::setw(20) << "v'(x)"
349  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
350  << std::setw(20) << "Error"
351  << "\n";
352  for (int i = 0; i < 13; i++) {
353  vy = regret(x+t,0);
354  vx = regret(x-t,0);
355  diff = (vy-vx)/(two*t);
356  err = std::abs(diff-dv);
357  std::cout << std::scientific << std::setprecision(11) << std::right
358  << std::setw(20) << t
359  << std::setw(20) << dv
360  << std::setw(20) << diff
361  << std::setw(20) << err
362  << "\n";
363  t *= p1;
364  }
365  std::cout << "\n";
366  // check v''(lb)
367  vx = zero;
368  vy = zero;
369  dv = regret(x,2);
370  t = one;
371  diff = zero;
372  err = zero;
373  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(lb) is correct? \n";
374  std::cout << std::right << std::setw(20) << "t"
375  << std::setw(20) << "v''(x)"
376  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
377  << std::setw(20) << "Error"
378  << "\n";
379  for (int i = 0; i < 13; i++) {
380  vy = regret(x+t,1);
381  vx = regret(x-t,1);
382  diff = (vy-vx)/(two*t);
383  err = std::abs(diff-dv);
384  std::cout << std::scientific << std::setprecision(11) << std::right
385  << std::setw(20) << t
386  << std::setw(20) << dv
387  << std::setw(20) << diff
388  << std::setw(20) << err
389  << "\n";
390  t *= p1;
391  }
392  std::cout << "\n";
393  }
394 
395 };
396 
397 }
398 #endif
Provides a general interface for risk and error measures generated through the expectation risk quadr...
Real regret(Real x, int deriv=0)
Evaluate the scalar regret function at x.
Real error(Real x, int deriv=0)
Evaluate the scalar error function at x.
virtual void check(void)
Run default derivative tests for the scalar regret function.
GenMoreauYosidaCVaR(Real prob, Real eps)
Constructor.
GenMoreauYosidaCVaR(Real prob, Real lam, Real eps)
Constructor.
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
void check(void)
Run default derivative tests for the scalar regret function.
GenMoreauYosidaCVaR(ROL::ParameterList &parlist)
Constructor.
void parseParameterList(ROL::ParameterList &parlist)