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
15#include "ROL_PlusFunction.hpp"
16#include "ROL_AbsoluteValue.hpp"
17
18#include "ROL_ParameterList.hpp"
19
41namespace ROL {
42
43template<class Real>
44class MeanVariance : public RandVarFunctional<Real> {
45 typedef typename std::vector<Real>::size_type uint;
46private:
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
57 using RandVarFunctional<Real>::val_;
58 using RandVarFunctional<Real>::gv_;
59 using RandVarFunctional<Real>::g_;
60 using RandVarFunctional<Real>::hv_;
62
63 using RandVarFunctional<Real>::point_;
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
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!");
95 }
96
97public:
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
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Provides an interface for the mean plus a sum of arbitrary order variances.
void updateGradient(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal risk measure storage for gradient computation.
MeanVariance(const Real order, const Real coeff, const Ptr< PositiveFunction< Real > > &pf)
Constructor.
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(ROL::ParameterList &parlist)
Constructor.
Ptr< ScalarController< Real > > gradvecs_
Ptr< ScalarController< Real > > values_
std::vector< Real >::size_type uint
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< VectorController< Real > > gradients_
Ptr< VectorController< Real > > hessvecs_
Real getValue(const Vector< Real > &x, const std::vector< Real > &xstat, SampleGenerator< Real > &sampler)
Return risk measure value.
MeanVariance(const std::vector< Real > &order, const std::vector< Real > &coeff, const Ptr< PositiveFunction< Real > > &pf)
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.
Ptr< PositiveFunction< Real > > positiveFunction_
void setHessVecStorage(const Ptr< ScalarController< Real > > &gradvec_storage, const Ptr< VectorController< Real > > &hessvec_storage)
void setStorage(const Ptr< ScalarController< Real > > &value_storage, const Ptr< VectorController< Real > > &gradient_storage)
void updateValue(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal storage for value computation.
std::vector< Real > order_
std::vector< Real > coeff_
Provides the interface to evaluate objective functions.
Provides the interface to implement any functional that maps a random variable to a (extended) real n...
Real computeValue(Objective< Real > &obj, const Vector< Real > &x, Real &tol)
void computeHessVec(Vector< Real > &hv, Objective< Real > &obj, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
virtual 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)
Ptr< Vector< Real > > dualVector_
virtual void setHessVecStorage(const Ptr< ScalarController< Real > > &gradvec_storage, const Ptr< VectorController< Real > > &hessvec_storage)
Real computeGradVec(Vector< Real > &g, Objective< Real > &obj, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
virtual int numMySamples(void) const
virtual std::vector< Real > getMyPoint(const int i) const
void sumAll(Real *input, Real *output, int dim) const
virtual Real getMyWeight(const int i) const
Defines the linear algebra or vector space interface.
virtual void scale(const Real alpha)=0
Compute where .
virtual void plus(const Vector &x)=0
Compute , where .
virtual void axpy(const Real alpha, const Vector &x)
Compute where .