ROL
ROL_PD_MeanSemiDeviation.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Rapid Optimization Library (ROL) Package
5 // Copyright (2014) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact lead developers:
38 // Drew Kouri (dpkouri@sandia.gov) and
39 // Denis Ridzal (dridzal@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
44 #ifndef ROL_PD_MEANSEMIDEVIATION_HPP
45 #define ROL_PD_MEANSEMIDEVIATION_HPP
46 
48 
49 namespace ROL {
50 
51 template<class Real>
53 private:
54  Real coeff_;
55 
56  Ptr<SampledScalar<Real>> values_;
57  Ptr<SampledScalar<Real>> gradvecs_;
58  Ptr<SampledVector<Real>> gradients_;
59  Ptr<SampledVector<Real>> hessvecs_;
60 
66 
69 
74 
79 
80  void initializeStorage(void) {
81  values_ = makePtr<SampledScalar<Real>>();
82  gradvecs_ = makePtr<SampledScalar<Real>>();
83  gradients_ = makePtr<SampledVector<Real>>();
84  hessvecs_ = makePtr<SampledVector<Real>>();
85 
87  RandVarFunctional<Real>::setHessVecStorage(gradvecs_,hessvecs_);
88  }
89 
90  void clear(void) {
91  gradvecs_->update();
92  hessvecs_->update();
93  }
94 
95  void checkInputs(void) {
96  Real zero(0);
97  ROL_TEST_FOR_EXCEPTION((coeff_ < zero), std::invalid_argument,
98  ">>> ERROR (ROL::PD_MeanSemiDeviation): Element of coefficient array out of range!");
100  }
101 
102 public:
103  PD_MeanSemiDeviation(const Real coeff)
104  : PD_RandVarFunctional<Real>(), coeff_(coeff) {
105  checkInputs();
106  }
107 
108  void setStorage(const Ptr<SampledScalar<Real>> &value_storage,
109  const Ptr<SampledVector<Real>> &gradient_storage) {
110  values_ = value_storage;
111  gradients_ = gradient_storage;
113  }
114 
115  void setHessVecStorage(const Ptr<SampledScalar<Real>> &gradvec_storage,
116  const Ptr<SampledVector<Real>> &hessvec_storage) {
117  gradvecs_ = gradvec_storage;
118  hessvecs_ = hessvec_storage;
120  }
121 
122  void initialize(const Vector<Real> &x) {
124  clear();
125  }
126 
128  const Vector<Real> &x,
129  const std::vector<Real> &xstat,
130  Real &tol) {
131  Real val = computeValue(obj,x,tol);
132  val_ += weight_ * val;
133  }
134 
135  Real getValue(const Vector<Real> &x,
136  const std::vector<Real> &xstat,
137  SampleGenerator<Real> &sampler) {
138  // Compute expected value
139  Real ev(0);
140  sampler.sumAll(&val_,&ev,1);
141  // Compute deviation
142  Real diff(0), pf0(0), dev(0), weight(0), lam(0);
143  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
144  values_->get(diff,sampler.getMyPoint(i));
145  diff -= ev;
146  setValue(diff, sampler.getMyPoint(i));
147  getMultiplier(lam,sampler.getMyPoint(i));
148  weight = sampler.getMyWeight(i);
149  pf0 += weight * ppf(diff, lam, getPenaltyParameter(), 0);
150  }
151  sampler.sumAll(&pf0,&dev,1);
152  dev *= coeff_;
153  // Return mean plus deviation
154  return ev + dev;
155  }
156 
158  const Vector<Real> &x,
159  const std::vector<Real> &xstat,
160  Real &tol) {
161  Real val = computeValue(obj,x,tol);
162  val_ += weight_ * val;
163  computeGradient(*dualVector_,obj,x,tol);
164  g_->axpy(weight_,*dualVector_);
165  }
166 
168  std::vector<Real> &gstat,
169  const Vector<Real> &x,
170  const std::vector<Real> &xstat,
171  SampleGenerator<Real> &sampler) {
172  // Compute expected value
173  Real ev(0);
174  sampler.sumAll(&val_,&ev,1);
175  // Compute deviation
176  hv_->zero(); dualVector_->zero();
177  Real diff(0), pf(0), pf1(0), dev(0), one(1), weight(0), lam(0);
178  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
179  values_->get(diff,sampler.getMyPoint(i));
180  diff -= ev;
181  getMultiplier(lam,sampler.getMyPoint(i));
182  weight = sampler.getMyWeight(i);
183  pf1 = weight * ppf(diff, lam, getPenaltyParameter(), 1);
184  pf += pf1;
185  gradients_->get(*hv_, sampler.getMyPoint(i));
186  dualVector_->axpy(coeff_ * pf1, *hv_);
187  }
188  sampler.sumAll(&pf,&dev,1);
189  g_->scale(one - coeff_ * dev);
190  g_->plus(*dualVector_);
191  sampler.sumAll(*g_,g);
192  }
193 
195  const Vector<Real> &v,
196  const std::vector<Real> &vstat,
197  const Vector<Real> &x,
198  const std::vector<Real> &xstat,
199  Real &tol) {
200  Real val = computeValue(obj,x,tol);
201  val_ += weight_ * val;
202  Real gv = computeGradVec(*dualVector_,obj,v,x,tol);
203  gv_ += weight_ * gv;
204  g_->axpy(weight_, *dualVector_);
205  computeHessVec(*dualVector_,obj,v,x,tol);
206  hv_->axpy(weight_, *dualVector_);
207  }
208 
210  std::vector<Real> &hvstat,
211  const Vector<Real> &v,
212  const std::vector<Real> &vstat,
213  const Vector<Real> &x,
214  const std::vector<Real> &xstat,
215  SampleGenerator<Real> &sampler) {
216  const Real one(1);
217  // Compute expected value
218  std::vector<Real> mval(2), gval(2);
219  mval[0] = val_; mval[1] = gv_;
220  sampler.sumAll(&mval[0],&gval[0],2);
221  Real ev = gval[0], egv = gval[1];
222  // Compute deviation
223  std::vector<Real> mvec(3), gvec(3);
224  Real diff(0), gv(0), pf1(0), pf2(0), weight(0), lam(0);
225  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
226  values_->get(diff,sampler.getMyPoint(i));
227  gradvecs_->get(gv,sampler.getMyPoint(i));
228  getMultiplier(lam,sampler.getMyPoint(i));
229  weight = sampler.getMyWeight(i);
230  diff -= ev;
231  pf1 = ppf(diff, lam, getPenaltyParameter(), 1);
232  pf2 = ppf(diff, lam, getPenaltyParameter(), 2);
233  mvec[0] += weight * pf1;
234  mvec[1] += weight * pf2;
235  mvec[2] += weight * pf2 * gv;
236  }
237  sampler.sumAll(&mvec[0],&gvec[0],3);
238  Real c1 = one - coeff_ * gvec[0];
239  Real c2 = coeff_ * (gvec[1]*egv - gvec[2]);
240  hv_->scale(c1);
241  hv_->axpy(c2, *g_);
242  sampler.sumAll(*hv_,hv);
243 
244  dualVector_->zero(); hv_->zero(); g_->zero();
245  for (int i = sampler.start(); i < sampler.numMySamples(); ++i) {
246  values_->get(diff,sampler.getMyPoint(i));
247  gradients_->get(*g_,sampler.getMyPoint(i));
248  gradvecs_->get(gv,sampler.getMyPoint(i));
249  hessvecs_->get(*dualVector_,sampler.getMyPoint(i));
250  getMultiplier(lam,sampler.getMyPoint(i));
251  weight = sampler.getMyWeight(i);
252  diff -= ev;
253  pf1 = ppf(diff, lam, getPenaltyParameter(), 1);
254  pf2 = ppf(diff, lam, getPenaltyParameter(), 2);
255  hv_->axpy(weight * coeff_ * pf2 * (gv-egv), *g_);
256  hv_->axpy(weight * coeff_ *pf1, *dualVector_);
257  }
258  sampler.sumAll(*hv_, *dualVector_);
259  hv.plus(*dualVector_);
260  }
261 };
262 
263 }
264 
265 #endif
virtual void setHessVecStorage(const Ptr< SampledScalar< Real >> &gradvec_storage, const Ptr< SampledVector< Real >> &hessvec_storage)
Provides the interface to evaluate objective functions.
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)
virtual void plus(const Vector &x)=0
Compute , where .
Ptr< Vector< Real > > hv_
Ptr< SampledScalar< Real > > values_
Real ppf(const Real x, const Real t, const Real r, const int deriv=0) const
Ptr< SampledScalar< Real > > gradvecs_
Real getValue(const Vector< Real > &x, const std::vector< Real > &xstat, SampleGenerator< Real > &sampler)
Return risk measure value.
void setStorage(const Ptr< SampledScalar< Real >> &value_storage, const Ptr< SampledVector< Real >> &gradient_storage)
virtual std::vector< Real > getMyPoint(const int i) const
virtual Real getMyWeight(const int i) const
Ptr< Vector< Real > > dualVector_
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:80
virtual int numMySamples(void) const
void updateGradient(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal risk measure storage for gradient computation.
void sumAll(Real *input, Real *output, int dim) const
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
void setHessVecStorage(const Ptr< SampledScalar< Real >> &gradvec_storage, const Ptr< SampledVector< Real >> &hessvec_storage)
virtual void setStorage(const Ptr< SampledScalar< Real >> &value_storage, const Ptr< SampledVector< 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.
virtual void setStorage(const Ptr< SampledScalar< Real >> &value_storage, const Ptr< SampledVector< Real >> &gradient_storage)
void getMultiplier(Real &lam, const std::vector< Real > &pt) const
void computeGradient(Vector< Real > &g, Objective< Real > &obj, const Vector< Real > &x, Real &tol)
virtual void initialize(const Vector< Real > &x)
Initialize temporary variables.
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 setValue(const Real val, const std::vector< Real > &pt)
Ptr< SampledVector< Real > > gradients_
void updateValue(Objective< Real > &obj, const Vector< Real > &x, const std::vector< Real > &xstat, Real &tol)
Update internal storage for value computation.
virtual void setHessVecStorage(const Ptr< SampledScalar< Real >> &gradvec_storage, const Ptr< SampledVector< Real >> &hessvec_storage)
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.
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 initialize(const Vector< Real > &x)
Initialize temporary variables.
Ptr< SampledVector< Real > > hessvecs_