ROL
ROL_MeanVariance.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_MEANVARIANCE_HPP
11 #define ROL_MEANVARIANCE_HPP
12 
14 #include "ROL_PositiveFunction.hpp"
15 #include "ROL_PlusFunction.hpp"
16 #include "ROL_AbsoluteValue.hpp"
17 
18 #include "ROL_ParameterList.hpp"
19 
41 namespace ROL {
42 
43 template<class Real>
44 class MeanVariance : public RandVarFunctional<Real> {
46 private:
47  Ptr<PositiveFunction<Real> > positiveFunction_;
48  std::vector<Real> order_;
49  std::vector<Real> coeff_;
51 
52  Ptr<ScalarController<Real>> values_;
53  Ptr<ScalarController<Real>> gradvecs_;
54  Ptr<VectorController<Real>> gradients_;
55  Ptr<VectorController<Real>> hessvecs_;
56 
62 
65 
70 
71  void initializeMV(void) {
72  values_ = makePtr<ScalarController<Real>>();
73  gradvecs_ = makePtr<ScalarController<Real>>();
74  gradients_ = makePtr<VectorController<Real>>();
75  hessvecs_ = makePtr<VectorController<Real>>();
76 
78  RandVarFunctional<Real>::setHessVecStorage(gradvecs_,hessvecs_);
79  }
80 
81  void checkInputs(void) {
82  int oSize = order_.size(), cSize = coeff_.size();
83  ROL_TEST_FOR_EXCEPTION((oSize!=cSize),std::invalid_argument,
84  ">>> ERROR (ROL::MeanVariance): Order and coefficient arrays have different sizes!");
85  Real zero(0), two(2);
86  for (int i = 0; i < oSize; i++) {
87  ROL_TEST_FOR_EXCEPTION((order_[i] < two), std::invalid_argument,
88  ">>> ERROR (ROL::MeanVariance): Element of order array out of range!");
89  ROL_TEST_FOR_EXCEPTION((coeff_[i] < zero), std::invalid_argument,
90  ">>> ERROR (ROL::MeanVariance): Element of coefficient array out of range!");
91  }
92  ROL_TEST_FOR_EXCEPTION(positiveFunction_ == nullPtr, std::invalid_argument,
93  ">>> ERROR (ROL::MeanVariance): PositiveFunction pointer is null!");
94  initializeMV();
95  }
96 
97 public:
107  MeanVariance( const Real order, const Real coeff,
108  const Ptr<PositiveFunction<Real> > &pf )
109  : RandVarFunctional<Real>(), positiveFunction_(pf) {
110  order_.clear(); order_.push_back(order);
111  coeff_.clear(); coeff_.push_back(coeff);
112  checkInputs();
113  NumMoments_ = order_.size();
114  }
115 
125  MeanVariance( const std::vector<Real> &order,
126  const std::vector<Real> &coeff,
127  const Ptr<PositiveFunction<Real> > &pf )
128  : RandVarFunctional<Real>(), positiveFunction_(pf) {
129  order_.clear(); coeff_.clear();
130  for ( uint i = 0; i < order.size(); i++ ) {
131  order_.push_back(order[i]);
132  }
133  for ( uint i = 0; i < coeff.size(); i++ ) {
134  coeff_.push_back(coeff[i]);
135  }
136  checkInputs();
137  NumMoments_ = order_.size();
138  }
139 
151  MeanVariance( ROL::ParameterList &parlist )
152  : RandVarFunctional<Real>() {
153  ROL::ParameterList &list
154  = parlist.sublist("SOL").sublist("Risk Measure").sublist("Mean Plus Variance");
155  // Get data from parameter list
156  order_ = ROL::getArrayFromStringParameter<double>(list,"Orders");
157  coeff_ = ROL::getArrayFromStringParameter<double>(list,"Coefficients");
158  // Build (approximate) positive function
159  std::string type = list.get<std::string>("Deviation Type");
160  if ( type == "Upper" ) {
161  positiveFunction_ = makePtr<PlusFunction<Real>>(list);
162  }
163  else if ( type == "Absolute" ) {
164  positiveFunction_ = makePtr<AbsoluteValue<Real>>(list);
165  }
166  else {
167  ROL_TEST_FOR_EXCEPTION(true, std::invalid_argument,
168  ">>> (ROL::MeanVariance): Variance type is not recoginized!");
169  }
170  // Check inputs
171  checkInputs();
172  NumMoments_ = order_.size();
173  }
174 
175  void setStorage(const Ptr<ScalarController<Real>> &value_storage,
176  const Ptr<VectorController<Real>> &gradient_storage) {
177  values_ = value_storage;
178  gradients_ = gradient_storage;
180  }
181 
182  void setHessVecStorage(const Ptr<ScalarController<Real>> &gradvec_storage,
183  const Ptr<VectorController<Real>> &hessvec_storage) {
184  gradvecs_ = gradvec_storage;
185  hessvecs_ = hessvec_storage;
187  }
188 
190  const Vector<Real> &x,
191  const std::vector<Real> &xstat,
192  Real &tol) {
193  Real val = computeValue(obj,x,tol);
194  val_ += weight_ * val;
195  }
196 
197  Real getValue(const Vector<Real> &x,
198  const std::vector<Real> &xstat,
199  SampleGenerator<Real> &sampler) {
200  // Compute expected value
201  Real ev(0);
202  sampler.sumAll(&val_,&ev,1);
203  // Compute deviation
204  Real val(0), diff(0), pf0(0), var(0), weight(0);
205  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
206  values_->get(diff,sampler.getMyPoint(i));
207  weight = sampler.getMyWeight(i);
208  diff -= ev;
209  pf0 = positiveFunction_->evaluate(diff,0);
210  for ( uint p = 0; p < NumMoments_; p++ ) {
211  val += coeff_[p] * std::pow(pf0,order_[p]) * weight;
212  }
213  }
214  sampler.sumAll(&val,&var,1);
215  // Return mean plus deviation
216  return ev + var;
217  }
218 
220  const Vector<Real> &x,
221  const std::vector<Real> &xstat,
222  Real &tol) {
223  Real val = computeValue(obj,x,tol);
224  val_ += weight_ * val;
225  computeGradient(*dualVector_,obj,x,tol);
226  g_->axpy(weight_,*dualVector_);
227  }
228 
230  std::vector<Real> &gstat,
231  const Vector<Real> &x,
232  const std::vector<Real> &xstat,
233  SampleGenerator<Real> &sampler) {
234  // Compute expected value
235  Real ev(0), zero(0), one(1);
236  sampler.sumAll(&val_,&ev,1);
237  sampler.sumAll(*g_,g);
238  // Compute deviation
239  g_->zero(); dualVector_->zero();
240  Real diff(0), pf0(0), pf1(0), c(0), ec(0), ecs(0), weight(0);
241  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
242  values_->get(diff,sampler.getMyPoint(i));
243  weight = sampler.getMyWeight(i);
244  diff -= ev;
245  pf0 = positiveFunction_->evaluate(diff,0);
246  pf1 = positiveFunction_->evaluate(diff,1);
247  c = zero;
248  for ( uint p = 0; p < NumMoments_; p++ ) {
249  c += coeff_[p]*order_[p]*std::pow(pf0,order_[p]-one)*pf1;
250  }
251  ec += weight*c;
252  gradients_->get(*dualVector_,sampler.getMyPoint(i));
253  g_->axpy(weight*c,*dualVector_);
254  }
255  dualVector_->zero();
256  sampler.sumAll(&ec,&ecs,1);
257  g.scale(one-ecs);
258  sampler.sumAll(*g_,*dualVector_);
259  g.plus(*dualVector_);
260  }
261 
263  const Vector<Real> &v,
264  const std::vector<Real> &vstat,
265  const Vector<Real> &x,
266  const std::vector<Real> &xstat,
267  Real &tol) {
268  Real val = computeValue(obj,x,tol);
269  val_ += weight_ * val;
270  Real gv = computeGradVec(*dualVector_,obj,v,x,tol);
271  gv_ += weight_ * gv;
272  g_->axpy(weight_,*dualVector_);
273  computeHessVec(*dualVector_,obj,v,x,tol);
274  hv_->axpy(weight_,*dualVector_);
275  }
276 
278  std::vector<Real> &hvstat,
279  const Vector<Real> &v,
280  const std::vector<Real> &vstat,
281  const Vector<Real> &x,
282  const std::vector<Real> &xstat,
283  SampleGenerator<Real> &sampler) {
284  // Compute expected value
285  std::vector<Real> myval(2), val(2);
286  myval[0] = val_;
287  myval[1] = gv_;
288  sampler.sumAll(&myval[0],&val[0],2);
289  Real ev = myval[0], egv = myval[1];
290  dualVector_->zero();
291  sampler.sumAll(*g_,*dualVector_);
292  sampler.sumAll(*hv_,hv);
293  // Compute deviation
294  g_->zero(); hv_->zero();
295  Real diff(0), pf0(0), pf1(0), pf2(0), zero(0), one(1), two(2);
296  Real cg(0), ecg(0), ecgs(0), ch(0), ech(0), echs(0), weight(0), gv(0);
297  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
298  values_->get(diff,sampler.getMyPoint(i));
299  gradvecs_->get(gv,sampler.getMyPoint(i));
300  weight = sampler.getMyWeight(i);
301  diff -= ev;
302  pf0 = positiveFunction_->evaluate(diff,0);
303  pf1 = positiveFunction_->evaluate(diff,1);
304  pf2 = positiveFunction_->evaluate(diff,2);
305  cg = zero;
306  ch = zero;
307  for ( uint p = 0; p < NumMoments_; p++ ) {
308  cg += coeff_[p]*order_[p]*(gv-egv)*
309  ((order_[p]-one)*std::pow(pf0,order_[p]-two)*pf1*pf1+
310  std::pow(pf0,order_[p]-one)*pf2);
311  ch += coeff_[p]*order_[p]*std::pow(pf0,order_[p]-one)*pf1;
312  }
313  ecg += weight*cg;
314  ech += weight*ch;
315  gradients_->get(*hv_,sampler.getMyPoint(i));
316  g_->axpy(weight*cg,*hv_);
317  hessvecs_->get(*hv_,sampler.getMyPoint(i));
318  g_->axpy(weight*ch,*hv_);
319  }
320  sampler.sumAll(&ech,&echs,1);
321  hv.scale(one-echs);
322  sampler.sumAll(&ecg,&ecgs,1);
323  hv.axpy(-ecgs,*dualVector_);
324  dualVector_->zero();
325  sampler.sumAll(*g_,*dualVector_);
326  hv.plus(*dualVector_);
327  }
328 };
329 
330 }
331 
332 #endif
void updateValue(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal storage for value computation.
Provides the interface to evaluate objective functions.
MeanVariance(const Real order, const Real coeff, const Ptr< PositiveFunction< Real > > &pf)
Constructor.
void computeHessVec(Vector< Real > &hv, Objective< Real > &obj, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
typename PV< Real >::size_type size_type
virtual void scale(const Real alpha)=0
Compute where .
Ptr< Vector< Real > > g_
Real getValue(const Vector< Real > &x, const std::vector< Real > &xstat, SampleGenerator< Real > &sampler)
Return risk measure value.
void updateGradient(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal risk measure storage for gradient computation.
Real computeValue(Objective< Real > &obj, const Vector< Real > &x, Real &tol)
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .
Definition: ROL_Vector.hpp:119
Ptr< Vector< Real > > hv_
std::vector< Real > order_
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)
std::vector< Real > coeff_
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 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.
MeanVariance(ROL::ParameterList &parlist)
Constructor.
Ptr< ScalarController< Real > > gradvecs_
void setStorage(const Ptr< ScalarController< Real >> &value_storage, const Ptr< VectorController< Real >> &gradient_storage)
void computeGradient(Vector< Real > &g, Objective< Real > &obj, const Vector< Real > &x, Real &tol)
std::vector< Real >::size_type uint
Real computeGradVec(Vector< Real > &g, Objective< Real > &obj, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Ptr< VectorController< Real > > hessvecs_
Provides the interface to implement any functional that maps a random variable to a (extended) real n...
Ptr< ScalarController< Real > > values_
void setHessVecStorage(const Ptr< ScalarController< Real >> &gradvec_storage, const Ptr< VectorController< Real >> &hessvec_storage)
Provides an interface for the mean plus a sum of arbitrary order variances.
virtual void setHessVecStorage(const Ptr< ScalarController< Real >> &gradvec_storage, const Ptr< VectorController< Real >> &hessvec_storage)
Ptr< VectorController< Real > > gradients_
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.
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.
MeanVariance(const std::vector< Real > &order, const std::vector< Real > &coeff, const Ptr< PositiveFunction< Real > > &pf)
Constructor.
Ptr< PositiveFunction< Real > > positiveFunction_