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 
35 namespace ROL {
36 
37 template<class Real>
38 class MeanSemiDeviation : public RandVarFunctional<Real> {
39 private:
40  Ptr<PlusFunction<Real> > plusFunction_;
41  Real coeff_;
42 
43  Ptr<ScalarController<Real>> values_;
44  Ptr<ScalarController<Real>> gradvecs_;
45  Ptr<VectorController<Real>> gradients_;
46  Ptr<VectorController<Real>> hessvecs_;
47 
53 
56 
61 
62  void initializeStorage(void) {
63  values_ = makePtr<ScalarController<Real>>();
64  gradvecs_ = makePtr<ScalarController<Real>>();
65  gradients_ = makePtr<VectorController<Real>>();
66  hessvecs_ = makePtr<VectorController<Real>>();
67 
69  RandVarFunctional<Real>::setHessVecStorage(gradvecs_,hessvecs_);
70  }
71 
72  void clear(void) {
73  gradvecs_->reset();
74  hessvecs_->reset();
75  }
76 
77  void checkInputs(void) {
78  const Real zero(0);
79  ROL_TEST_FOR_EXCEPTION((coeff_ < zero), std::invalid_argument,
80  ">>> ERROR (ROL::MeanSemiDeviation): Coefficient must be positive!");
81  ROL_TEST_FOR_EXCEPTION(plusFunction_ == nullPtr, std::invalid_argument,
82  ">>> ERROR (ROL::MeanSemiDeviation): PlusFunction pointer is null!");
84  }
85 
86 public:
87 
93  MeanSemiDeviation( const Real coeff, const Ptr<PlusFunction<Real> > &pf )
94  : RandVarFunctional<Real>(), plusFunction_(pf), coeff_(coeff) {
95  checkInputs();
96  }
97 
107  MeanSemiDeviation( ROL::ParameterList &parlist )
108  : RandVarFunctional<Real>() {
109  ROL::ParameterList &list
110  = parlist.sublist("SOL").sublist("Risk Measure").sublist("Mean Plus Semi-Deviation");
111  // Check CVaR inputs
112  coeff_ = list.get<Real>("Coefficient");
113  // Build (approximate) plus function
114  plusFunction_ = makePtr<PlusFunction<Real>>(list);
115  // Check Inputs
116  checkInputs();
117  }
118 
119  void setStorage(const Ptr<ScalarController<Real>> &value_storage,
120  const Ptr<VectorController<Real>> &gradient_storage) {
121  values_ = value_storage;
122  gradients_ = gradient_storage;
124  }
125 
126  void setHessVecStorage(const Ptr<ScalarController<Real>> &gradvec_storage,
127  const Ptr<VectorController<Real>> &hessvec_storage) {
128  gradvecs_ = gradvec_storage;
129  hessvecs_ = hessvec_storage;
131  }
132 
133  void initialize(const Vector<Real> &x) {
135  clear();
136  }
137 
139  const Vector<Real> &x,
140  const std::vector<Real> &xstat,
141  Real &tol) {
142  Real val = computeValue(obj,x,tol);
143  val_ += weight_ * val;
144  }
145 
146  Real getValue(const Vector<Real> &x,
147  const std::vector<Real> &xstat,
148  SampleGenerator<Real> &sampler) {
149  // Compute expected value
150  Real ev(0);
151  sampler.sumAll(&val_,&ev,1);
152  // Compute deviation
153  Real diff(0), pf(0), dev(0), weight(0);
154  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
155  values_->get(diff,sampler.getMyPoint(i));
156  weight = sampler.getMyWeight(i);
157  diff -= ev;
158  pf += weight * plusFunction_->evaluate(diff,0);
159  }
160  sampler.sumAll(&pf,&dev,1);
161  // Return mean plus deviation
162  return ev + coeff_ * dev;
163  }
164 
166  const Vector<Real> &x,
167  const std::vector<Real> &xstat,
168  Real &tol) {
169  Real val = computeValue(obj,x,tol);
170  val_ += weight_ * val;
171  computeGradient(*dualVector_,obj,x,tol);
172  }
173 
175  std::vector<Real> &gstat,
176  const Vector<Real> &x,
177  const std::vector<Real> &xstat,
178  SampleGenerator<Real> &sampler) {
179  // Compute expected value
180  Real ev(0);
181  sampler.sumAll(&val_,&ev,1);
182  // Compute deviation
183  Real diff(0), dev(0), pf (0), c(0), one(1), weight(0);
184  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
185  values_->get(diff,sampler.getMyPoint(i));
186  weight = sampler.getMyWeight(i);
187  diff -= ev;
188  pf += weight * plusFunction_->evaluate(diff,1);
189  }
190  sampler.sumAll(&pf,&dev,1);
191  // Compute derivative
192  g_->zero(); dualVector_->zero();
193  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
194  values_->get(diff,sampler.getMyPoint(i));
195  weight = sampler.getMyWeight(i);
196  diff -= ev;
197  pf = plusFunction_->evaluate(diff,1);
198  c = one + coeff_ * (pf - dev);
199  gradients_->get(*dualVector_, sampler.getMyPoint(i));
200  g_->axpy(weight * c, *dualVector_);
201  }
202  sampler.sumAll(*g_, g);
203  }
204 
206  const Vector<Real> &v,
207  const std::vector<Real> &vstat,
208  const Vector<Real> &x,
209  const std::vector<Real> &xstat,
210  Real &tol) {
211  Real val = computeValue(obj,x,tol);
212  val_ += weight_ * val;
213  Real gv = computeGradVec(*dualVector_,obj,v,x,tol);
214  gv_ += weight_ * gv;
215  computeHessVec(*dualVector_,obj,v,x,tol);
216  }
217 
219  std::vector<Real> &hvstat,
220  const Vector<Real> &v,
221  const std::vector<Real> &vstat,
222  const Vector<Real> &x,
223  const std::vector<Real> &xstat,
224  SampleGenerator<Real> &sampler) {
225  const Real one(1);
226  // Compute expected value
227  std::vector<Real> mval = {val_, gv_};
228  std::vector<Real> gval(2,0);
229  sampler.sumAll(&mval[0],&gval[0],2);
230  Real ev = gval[0], egv = gval[1];
231  // Compute deviation
232  Real diff(0), pf1(0), pf2(0), weight(0), gv(0), c(0);
233  std::vector<Real> pf(2,0), dev(2,0);
234  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
235  values_->get(diff, sampler.getMyPoint(i));
236  gradvecs_->get(gv, sampler.getMyPoint(i));
237  weight = sampler.getMyWeight(i);
238  diff -= ev;
239  pf[0] += weight * plusFunction_->evaluate(diff,1);
240  pf[1] += weight * plusFunction_->evaluate(diff,2) * (gv - egv);
241  }
242  sampler.sumAll(&pf[0],&dev[0],2);
243  hv_->zero(); dualVector_->zero();
244  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
245  values_->get(diff, sampler.getMyPoint(i));
246  gradvecs_->get(gv, sampler.getMyPoint(i));
247  weight = sampler.getMyWeight(i);
248  diff -= ev;
249  pf1 = plusFunction_->evaluate(diff,1);
250  c = one + coeff_ * (pf1 - dev[0]);
251  hessvecs_->get(*dualVector_, sampler.getMyPoint(i));
252  hv_->axpy(weight * c, *dualVector_);
253  pf2 = plusFunction_->evaluate(diff,2) * (gv - egv);
254  c = coeff_ * (pf2 - dev[1]);
255  gradients_->get(*dualVector_, sampler.getMyPoint(i));
256  hv_->axpy(weight * c, *dualVector_);
257  }
258  sampler.sumAll(*hv_, hv);
259  }
260 };
261 
262 }
263 
264 #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.