ROL
ROL_MeanSemiDeviation.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_MEANSEMIDEVIATION_HPP
11 #define ROL_MEANSEMIDEVIATION_HPP
12 
14 #include "ROL_PlusFunction.hpp"
15 
34 namespace ROL {
35 
36 template<class Real>
37 class MeanSemiDeviation : public RandVarFunctional<Real> {
38 private:
39  Ptr<PlusFunction<Real> > plusFunction_;
40  Real coeff_;
41 
42  Ptr<ScalarController<Real>> values_;
43  Ptr<ScalarController<Real>> gradvecs_;
44  Ptr<VectorController<Real>> gradients_;
45  Ptr<VectorController<Real>> hessvecs_;
46 
52 
55 
60 
61  void initializeStorage(void) {
62  values_ = makePtr<ScalarController<Real>>();
63  gradvecs_ = makePtr<ScalarController<Real>>();
64  gradients_ = makePtr<VectorController<Real>>();
65  hessvecs_ = makePtr<VectorController<Real>>();
66 
68  RandVarFunctional<Real>::setHessVecStorage(gradvecs_,hessvecs_);
69  }
70 
71  void clear(void) {
72  gradvecs_->reset();
73  hessvecs_->reset();
74  }
75 
76  void checkInputs(void) {
77  const Real zero(0);
78  ROL_TEST_FOR_EXCEPTION((coeff_ < zero), std::invalid_argument,
79  ">>> ERROR (ROL::MeanSemiDeviation): Coefficient must be positive!");
80  ROL_TEST_FOR_EXCEPTION(plusFunction_ == nullPtr, std::invalid_argument,
81  ">>> ERROR (ROL::MeanSemiDeviation): PlusFunction pointer is null!");
83  }
84 
85 public:
86 
92  MeanSemiDeviation( const Real coeff, const Ptr<PlusFunction<Real> > &pf )
93  : RandVarFunctional<Real>(), plusFunction_(pf), coeff_(coeff) {
94  checkInputs();
95  }
96 
106  MeanSemiDeviation( ROL::ParameterList &parlist )
107  : RandVarFunctional<Real>() {
108  ROL::ParameterList &list
109  = parlist.sublist("SOL").sublist("Risk Measure").sublist("Mean Plus Semi-Deviation");
110  // Check CVaR inputs
111  coeff_ = list.get<Real>("Coefficient");
112  // Build (approximate) plus function
113  plusFunction_ = makePtr<PlusFunction<Real>>(list);
114  // Check Inputs
115  checkInputs();
116  }
117 
118  void setStorage(const Ptr<ScalarController<Real>> &value_storage,
119  const Ptr<VectorController<Real>> &gradient_storage) {
120  values_ = value_storage;
121  gradients_ = gradient_storage;
123  }
124 
125  void setHessVecStorage(const Ptr<ScalarController<Real>> &gradvec_storage,
126  const Ptr<VectorController<Real>> &hessvec_storage) {
127  gradvecs_ = gradvec_storage;
128  hessvecs_ = hessvec_storage;
130  }
131 
132  void initialize(const Vector<Real> &x) {
134  clear();
135  }
136 
138  const Vector<Real> &x,
139  const std::vector<Real> &xstat,
140  Real &tol) {
141  Real val = computeValue(obj,x,tol);
142  val_ += weight_ * val;
143  }
144 
145  Real getValue(const Vector<Real> &x,
146  const std::vector<Real> &xstat,
147  SampleGenerator<Real> &sampler) {
148  // Compute expected value
149  Real ev(0);
150  sampler.sumAll(&val_,&ev,1);
151  // Compute deviation
152  Real diff(0), pf(0), dev(0), weight(0);
153  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
154  values_->get(diff,sampler.getMyPoint(i));
155  weight = sampler.getMyWeight(i);
156  diff -= ev;
157  pf += weight * plusFunction_->evaluate(diff,0);
158  }
159  sampler.sumAll(&pf,&dev,1);
160  // Return mean plus deviation
161  return ev + coeff_ * dev;
162  }
163 
165  const Vector<Real> &x,
166  const std::vector<Real> &xstat,
167  Real &tol) {
168  Real val = computeValue(obj,x,tol);
169  val_ += weight_ * val;
170  computeGradient(*dualVector_,obj,x,tol);
171  }
172 
174  std::vector<Real> &gstat,
175  const Vector<Real> &x,
176  const std::vector<Real> &xstat,
177  SampleGenerator<Real> &sampler) {
178  // Compute expected value
179  Real ev(0);
180  sampler.sumAll(&val_,&ev,1);
181  // Compute deviation
182  Real diff(0), dev(0), pf (0), c(0), one(1), weight(0);
183  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
184  values_->get(diff,sampler.getMyPoint(i));
185  weight = sampler.getMyWeight(i);
186  diff -= ev;
187  pf += weight * plusFunction_->evaluate(diff,1);
188  }
189  sampler.sumAll(&pf,&dev,1);
190  // Compute derivative
191  g_->zero(); dualVector_->zero();
192  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
193  values_->get(diff,sampler.getMyPoint(i));
194  weight = sampler.getMyWeight(i);
195  diff -= ev;
196  pf = plusFunction_->evaluate(diff,1);
197  c = one + coeff_ * (pf - dev);
198  gradients_->get(*dualVector_, sampler.getMyPoint(i));
199  g_->axpy(weight * c, *dualVector_);
200  }
201  sampler.sumAll(*g_, g);
202  }
203 
205  const Vector<Real> &v,
206  const std::vector<Real> &vstat,
207  const Vector<Real> &x,
208  const std::vector<Real> &xstat,
209  Real &tol) {
210  Real val = computeValue(obj,x,tol);
211  val_ += weight_ * val;
212  Real gv = computeGradVec(*dualVector_,obj,v,x,tol);
213  gv_ += weight_ * gv;
214  computeHessVec(*dualVector_,obj,v,x,tol);
215  }
216 
218  std::vector<Real> &hvstat,
219  const Vector<Real> &v,
220  const std::vector<Real> &vstat,
221  const Vector<Real> &x,
222  const std::vector<Real> &xstat,
223  SampleGenerator<Real> &sampler) {
224  const Real one(1);
225  // Compute expected value
226  std::vector<Real> mval = {val_, gv_};
227  std::vector<Real> gval(2,0);
228  sampler.sumAll(&mval[0],&gval[0],2);
229  Real ev = gval[0], egv = gval[1];
230  // Compute deviation
231  Real diff(0), pf1(0), pf2(0), weight(0), gv(0), c(0);
232  std::vector<Real> pf(2,0), dev(2,0);
233  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
234  values_->get(diff, sampler.getMyPoint(i));
235  gradvecs_->get(gv, sampler.getMyPoint(i));
236  weight = sampler.getMyWeight(i);
237  diff -= ev;
238  pf[0] += weight * plusFunction_->evaluate(diff,1);
239  pf[1] += weight * plusFunction_->evaluate(diff,2) * (gv - egv);
240  }
241  sampler.sumAll(&pf[0],&dev[0],2);
242  hv_->zero(); dualVector_->zero();
243  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
244  values_->get(diff, sampler.getMyPoint(i));
245  gradvecs_->get(gv, sampler.getMyPoint(i));
246  weight = sampler.getMyWeight(i);
247  diff -= ev;
248  pf1 = plusFunction_->evaluate(diff,1);
249  c = one + coeff_ * (pf1 - dev[0]);
250  hessvecs_->get(*dualVector_, sampler.getMyPoint(i));
251  hv_->axpy(weight * c, *dualVector_);
252  pf2 = plusFunction_->evaluate(diff,2) * (gv - egv);
253  c = coeff_ * (pf2 - dev[1]);
254  gradients_->get(*dualVector_, sampler.getMyPoint(i));
255  hv_->axpy(weight * c, *dualVector_);
256  }
257  sampler.sumAll(*hv_, hv);
258  }
259 };
260 
261 }
262 
263 #endif
Provides the interface to evaluate objective functions.
Ptr< PlusFunction< Real > > plusFunction_
void setHessVecStorage(const Ptr< ScalarController< Real >> &gradvec_storage, const Ptr< VectorController< Real >> &hessvec_storage)
Ptr< ScalarController< Real > > gradvecs_
void computeHessVec(Vector< Real > &hv, Objective< Real > &obj, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Ptr< Vector< Real > > g_
Real computeValue(Objective< Real > &obj, const Vector< Real > &x, Real &tol)
Ptr< VectorController< Real > > gradients_
Ptr< Vector< Real > > hv_
void initialize(const Vector< Real > &x)
Initialize temporary variables.
virtual std::vector< Real > getMyPoint(const int i) const
virtual Real getMyWeight(const int i) const
Ptr< Vector< Real > > dualVector_
virtual void setStorage(const Ptr< ScalarController< Real >> &value_storage, const Ptr< VectorController< Real >> &gradient_storage)
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:46
virtual int numMySamples(void) const
void sumAll(Real *input, Real *output, int dim) const
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
void getGradient(Vector< Real > &g, std::vector< Real > &gstat, const Vector< Real > &x, const std::vector< Real > &xstat, SampleGenerator< Real > &sampler)
Return risk measure (sub)gradient.
MeanSemiDeviation(const Real coeff, const Ptr< PlusFunction< Real > > &pf)
Constructor.
void updateValue(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal storage for value computation.
MeanSemiDeviation(ROL::ParameterList &parlist)
Constructor.
void updateHessVec(Objective< Real > &obj, const Vector< Real > &v, const std::vector< Real > &vstat, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal risk measure storage for Hessian-time-a-vector computation.
void updateGradient(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal risk measure storage for gradient computation.
Ptr< VectorController< Real > > hessvecs_
void computeGradient(Vector< Real > &g, Objective< Real > &obj, const Vector< Real > &x, Real &tol)
Real getValue(const Vector< Real > &x, const std::vector< Real > &xstat, SampleGenerator< Real > &sampler)
Return risk measure value.
Provides an interface for the mean plus upper semideviation of order 1.
Real computeGradVec(Vector< Real > &g, Objective< Real > &obj, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Provides the interface to implement any functional that maps a random variable to a (extended) real n...
void setStorage(const Ptr< ScalarController< Real >> &value_storage, const Ptr< VectorController< Real >> &gradient_storage)
void getHessVec(Vector< Real > &hv, std::vector< Real > &hvstat, const Vector< Real > &v, const std::vector< Real > &vstat, const Vector< Real > &x, const std::vector< Real > &xstat, SampleGenerator< Real > &sampler)
Return risk measure Hessian-times-a-vector.
Ptr< ScalarController< Real > > values_
virtual void setHessVecStorage(const Ptr< ScalarController< Real >> &gradvec_storage, const Ptr< VectorController< Real >> &hessvec_storage)
virtual void initialize(const Vector< Real > &x)
Initialize temporary variables.