ROL
ROL_GenMoreauYosidaCVaR.hpp
Go to the documentation of this file.
1 // @HEADER
2 // *****************************************************************************
3 // Rapid Optimization Library (ROL) Package
4 //
5 // Copyright 2014 NTESS and the ROL contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 #ifndef ROL_GENMOREAUYOSIDACVAR_HPP
11 #define ROL_GENMOREAUYOSIDACVAR_HPP
12 
13 #include "ROL_ExpectationQuad.hpp"
14 
68 namespace ROL {
69 
70 template<class Real>
71 class GenMoreauYosidaCVaR : public ExpectationQuad<Real> {
72 private:
73 
74  Real prob_;
75  Real lam_;
76  Real eps_;
77 
78  Real alpha_;
79  Real beta_;
80 
81  Real omp_;
82  Real oma_;
83  Real bmo_;
84  Real lb_;
85  Real ub_;
86 
87  void parseParameterList(ROL::ParameterList &parlist) {
88  std::string type = parlist.sublist("SOL").get("Type","Risk Averse");
89  ROL::ParameterList list;
90  if (type == "Risk Averse") {
91  list = parlist.sublist("SOL").sublist("Risk Measure").sublist("Generalized Moreau-Yosida CVaR");
92  }
93  else if (type == "Error") {
94  list = parlist.sublist("SOL").sublist("Error Measure").sublist("Generalized Moreau-Yosida-Koenker-Bassett");
95  }
96  else if (type == "Deviation") {
97  list = parlist.sublist("SOL").sublist("Deviation Measure").sublist("Generalized Moreau-Yosida CVaR");
98  }
99  else if (type == "Regret") {
100  list = parlist.sublist("SOL").sublist("Regret Measure").sublist("Generalized Moreau-Yosida Mean Absolute Loss");
101  }
102  prob_ = list.get<Real>("Confidence Level");
103  lam_ = list.get<Real>("Convex Combination Parameter");
104  eps_ = list.get<Real>("Smoothing Parameter");
105  }
106 
107  void checkInputs(void) const {
108  Real zero(0), one(1);
109  ROL_TEST_FOR_EXCEPTION((prob_ <= zero) || (prob_ >= one), std::invalid_argument,
110  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Confidence level must be between 0 and 1!");
111  ROL_TEST_FOR_EXCEPTION((lam_ < zero) || (lam_ > one), std::invalid_argument,
112  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Convex combination parameter must be positive!");
113  ROL_TEST_FOR_EXCEPTION((eps_ <= zero), std::invalid_argument,
114  ">>> ERROR (ROL::GenMoreauYosidaCVaR): Smoothing parameter must be positive!");
115  }
116 
117  void setParameters(void) {
118  const Real one(1);
119  omp_ = one-prob_;
120  alpha_ = lam_;
121  beta_ = (one-alpha_*prob_)/omp_;
122  oma_ = one-alpha_;
123  bmo_ = beta_-one;
124  lb_ = -eps_*oma_;
125  ub_ = eps_*bmo_;
126  }
127 
128 public:
134  GenMoreauYosidaCVaR(Real prob, Real eps )
135  : ExpectationQuad<Real>(), prob_(prob), lam_(0), eps_(eps) {
136  checkInputs();
137  setParameters();
138  }
139 
146  GenMoreauYosidaCVaR(Real prob, Real lam, Real eps )
147  : ExpectationQuad<Real>(), prob_(prob), lam_(lam), eps_(eps) {
148  checkInputs();
149  setParameters();
150  }
151 
162  GenMoreauYosidaCVaR(ROL::ParameterList &parlist)
163  : ExpectationQuad<Real>() {
164  parseParameterList(parlist);
165  checkInputs();
166  setParameters();
167  }
168 
169  Real error(Real x, int deriv = 0) {
170  Real zero(0), one(1);
171  Real X = ((deriv==0) ? x : ((deriv==1) ? one : zero));
172  return regret(x,deriv) - X;
173  }
174 
175  Real regret(Real x, int deriv = 0) {
176  Real zero(0), half(0.5), one(1), reg(0);
177  if ( x <= lb_ ) {
178  reg = ((deriv == 0) ? alpha_*x + half*lb_*oma_
179  : ((deriv == 1) ? alpha_ : zero));
180  }
181  else if ( x >= ub_ ) {
182  reg = ((deriv == 0) ? beta_*x - half*ub_*bmo_
183  : ((deriv == 1) ? beta_ : zero));
184  }
185  else {
186  reg = ((deriv == 0) ? half/eps_*x*x + x
187  : ((deriv == 1) ? x/eps_ + one : one/eps_));
188  }
189  return reg;
190  }
191 
192  void check(void) {
194  Real zero(0), one(1), two(2), p1(0.1);
195  // Check v'(ub)
196  Real x = ub_;
197  Real vx = zero, vy = zero;
198  Real dv = regret(x,1);
199  Real t = one;
200  Real diff = zero;
201  Real err = zero;
202  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(ub) is correct? \n";
203  std::cout << std::right << std::setw(20) << "t"
204  << std::setw(20) << "v'(x)"
205  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
206  << std::setw(20) << "Error"
207  << "\n";
208  for (int i = 0; i < 13; i++) {
209  vy = regret(x+t,0);
210  vx = regret(x-t,0);
211  diff = (vy-vx)/(two*t);
212  err = std::abs(diff-dv);
213  std::cout << std::scientific << std::setprecision(11) << std::right
214  << std::setw(20) << t
215  << std::setw(20) << dv
216  << std::setw(20) << diff
217  << std::setw(20) << err
218  << "\n";
219  t *= p1;
220  }
221  std::cout << "\n";
222  // check v''(ub)
223  vx = zero;
224  vy = zero;
225  dv = regret(x,2);
226  t = one;
227  diff = zero;
228  err = zero;
229  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(ub) is correct? \n";
230  std::cout << std::right << std::setw(20) << "t"
231  << std::setw(20) << "v''(x)"
232  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
233  << std::setw(20) << "Error"
234  << "\n";
235  for (int i = 0; i < 13; i++) {
236  vy = regret(x+t,1);
237  vx = regret(x-t,1);
238  diff = (vy-vx)/(two*t);
239  err = std::abs(diff-dv);
240  std::cout << std::scientific << std::setprecision(11) << std::right
241  << std::setw(20) << t
242  << std::setw(20) << dv
243  << std::setw(20) << diff
244  << std::setw(20) << err
245  << "\n";
246  t *= p1;
247  }
248  std::cout << "\n";
249  // Check v'(0)
250  x = zero;
251  vx = zero;
252  vy = zero;
253  dv = regret(x,1);
254  t = one;
255  diff = zero;
256  err = zero;
257  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(0) is correct? \n";
258  std::cout << std::right << std::setw(20) << "t"
259  << std::setw(20) << "v'(x)"
260  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
261  << std::setw(20) << "Error"
262  << "\n";
263  for (int i = 0; i < 13; i++) {
264  vy = regret(x+t,0);
265  vx = regret(x-t,0);
266  diff = (vy-vx)/(two*t);
267  err = std::abs(diff-dv);
268  std::cout << std::scientific << std::setprecision(11) << std::right
269  << std::setw(20) << t
270  << std::setw(20) << dv
271  << std::setw(20) << diff
272  << std::setw(20) << err
273  << "\n";
274  t *= p1;
275  }
276  std::cout << "\n";
277  // check v''(0)
278  vx = zero;
279  vy = zero;
280  dv = regret(x,2);
281  t = one;
282  diff = zero;
283  err = zero;
284  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(0) is correct? \n";
285  std::cout << std::right << std::setw(20) << "t"
286  << std::setw(20) << "v''(x)"
287  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
288  << std::setw(20) << "Error"
289  << "\n";
290  for (int i = 0; i < 13; i++) {
291  vy = regret(x+t,1);
292  vx = regret(x-t,1);
293  diff = (vy-vx)/(two*t);
294  err = std::abs(diff-dv);
295  std::cout << std::scientific << std::setprecision(11) << std::right
296  << std::setw(20) << t
297  << std::setw(20) << dv
298  << std::setw(20) << diff
299  << std::setw(20) << err
300  << "\n";
301  t *= p1;
302  }
303  std::cout << "\n";
304  // Check v'(lb)
305  x = lb_;
306  vx = zero;
307  vy = zero;
308  dv = regret(x,1);
309  t = one;
310  diff = zero;
311  err = zero;
312  std::cout << std::right << std::setw(20) << "CHECK REGRET: v'(lb) is correct? \n";
313  std::cout << std::right << std::setw(20) << "t"
314  << std::setw(20) << "v'(x)"
315  << std::setw(20) << "(v(x+t)-v(x-t))/2t"
316  << std::setw(20) << "Error"
317  << "\n";
318  for (int i = 0; i < 13; i++) {
319  vy = regret(x+t,0);
320  vx = regret(x-t,0);
321  diff = (vy-vx)/(two*t);
322  err = std::abs(diff-dv);
323  std::cout << std::scientific << std::setprecision(11) << std::right
324  << std::setw(20) << t
325  << std::setw(20) << dv
326  << std::setw(20) << diff
327  << std::setw(20) << err
328  << "\n";
329  t *= p1;
330  }
331  std::cout << "\n";
332  // check v''(lb)
333  vx = zero;
334  vy = zero;
335  dv = regret(x,2);
336  t = one;
337  diff = zero;
338  err = zero;
339  std::cout << std::right << std::setw(20) << "CHECK REGRET: v''(lb) is correct? \n";
340  std::cout << std::right << std::setw(20) << "t"
341  << std::setw(20) << "v''(x)"
342  << std::setw(20) << "(v'(x+t)-v'(x-t))/2t"
343  << std::setw(20) << "Error"
344  << "\n";
345  for (int i = 0; i < 13; i++) {
346  vy = regret(x+t,1);
347  vx = regret(x-t,1);
348  diff = (vy-vx)/(two*t);
349  err = std::abs(diff-dv);
350  std::cout << std::scientific << std::setprecision(11) << std::right
351  << std::setw(20) << t
352  << std::setw(20) << dv
353  << std::setw(20) << diff
354  << std::setw(20) << err
355  << "\n";
356  t *= p1;
357  }
358  std::cout << "\n";
359  }
360 
361 };
362 
363 }
364 #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)