ROL
ROL_CDFObjective.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_CDFOBJECTIVE_H
45 #define ROL_CDFOBJECTIVE_H
46 
47 #include "ROL_Objective.hpp"
48 #include "ROL_Vector.hpp"
49 #include "ROL_Distribution.hpp"
50 #include "Teuchos_RCP.hpp"
51 #include <math.h>
52 
53 namespace ROL {
54 
55 template <class Real>
56 class CDFObjective : public Objective<Real> {
57 private:
58  std::vector<Teuchos::RCP<Distribution<Real> > > dist_;
59  const std::vector<Real> lowerBound_;
60  const std::vector<Real> upperBound_;
61  const Real scale_;
62  const Real sqrt2_;
63  const Real sqrtpi_;
64 
65  std::vector<Real> pts_;
66  std::vector<Real> wts_;
67  size_t numPoints_;
68 
69  void initializeQuadrature(void) {
70  numPoints_ = 20;
71  pts_.clear(); pts_.resize(numPoints_,0.);
72  wts_.clear(); wts_.resize(numPoints_,0.);
73  wts_[0] = 0.1527533871307258; pts_[0] = -0.0765265211334973;
74  wts_[1] = 0.1527533871307258; pts_[1] = 0.0765265211334973;
75  wts_[2] = 0.1491729864726037; pts_[2] = -0.2277858511416451;
76  wts_[3] = 0.1491729864726037; pts_[3] = 0.2277858511416451;
77  wts_[4] = 0.1420961093183820; pts_[4] = -0.3737060887154195;
78  wts_[5] = 0.1420961093183820; pts_[5] = 0.3737060887154195;
79  wts_[6] = 0.1316886384491766; pts_[6] = -0.5108670019508271;
80  wts_[7] = 0.1316886384491766; pts_[7] = 0.5108670019508271;
81  wts_[8] = 0.1181945319615184; pts_[8] = -0.6360536807265150;
82  wts_[9] = 0.1181945319615184; pts_[9] = 0.6360536807265150;
83  wts_[10] = 0.1019301198172404; pts_[10] = -0.7463319064601508;
84  wts_[11] = 0.1019301198172404; pts_[11] = 0.7463319064601508;
85  wts_[12] = 0.0832767415767048; pts_[12] = -0.8391169718222188;
86  wts_[13] = 0.0832767415767048; pts_[13] = 0.8391169718222188;
87  wts_[14] = 0.0626720483341091; pts_[14] = -0.9122344282513259;
88  wts_[15] = 0.0626720483341091; pts_[15] = 0.9122344282513259;
89  wts_[16] = 0.0406014298003869; pts_[16] = -0.9639719272779138;
90  wts_[17] = 0.0406014298003869; pts_[17] = 0.9639719272779138;
91  wts_[18] = 0.0176140071391521; pts_[18] = -0.9931285991850949;
92  wts_[19] = 0.0176140071391521; pts_[19] = 0.9931285991850949;
93  for (size_t i = 0; i < numPoints_; i++) {
94  wts_[i] *= 0.5;
95  pts_[i] += 1.; pts_[i] *= 0.5;
96  }
97  }
98 
99  Real valueCDF(const size_t dim, const Real loc, const SROMVector<Real> &x) const {
100  const size_t numSamples = x.getNumSamples();
101  Real val = 0., hs = 0., xpt = 0., xwt = 0.;
102  for (size_t k = 0; k < numSamples; k++) {
103  xpt = (*x.getPoint(k))[dim]; xwt = x.getWeight(k);
104  hs = 0.5 * (1. + erf((loc-xpt)/(sqrt2_*scale_)));
105  val += xwt * hs;
106  }
107  return val;
108  }
109 
110  Real gradientCDF(std::vector<Real> &gradx, std::vector<Real> &gradp,
111  const size_t dim, const Real loc, const SROMVector<Real> &x) const {
112  const size_t numSamples = x.getNumSamples();
113  gradx.resize(numSamples,0.); gradp.resize(numSamples,0.);
114  Real val = 0., hs = 0., xpt = 0., xwt = 0.;
115  for (size_t k = 0; k < numSamples; k++) {
116  xpt = (*x.getPoint(k))[dim]; xwt = x.getWeight(k);
117  hs = 0.5 * (1. + erf((loc-xpt)/(sqrt2_*scale_)));
118  val += xwt * hs;
119  gradx[k] = -(xwt/(sqrt2_*sqrtpi_*scale_))
120  * std::exp(-std::pow((loc-xpt)/(sqrt2_*scale_),2));
121  gradp[k] = hs;
122  }
123  return val;
124  }
125 
126  Real hessVecCDF(std::vector<Real> &hvxx, std::vector<Real> &hvxp, std::vector<Real> &hvpx,
127  std::vector<Real> &gradx, std::vector<Real> &gradp,
128  Real &sumx, Real &sump,
129  const size_t dim, const Real loc, const SROMVector<Real> &x, const SROMVector<Real> &v) const {
130  const size_t numSamples = x.getNumSamples();
131  hvxx.resize(numSamples,0.); hvxp.resize(numSamples,0.); hvpx.resize(numSamples,0.);
132  gradx.resize(numSamples,0.); gradp.resize(numSamples,0.);
133  sumx = 0.; sump = 0.;
134  Real val = 0., hs = 0., dval = 0., scale3 = std::pow(scale_,3);
135  Real xpt = 0., xwt = 0., vpt = 0., vwt = 0.;
136  for (size_t k = 0; k < numSamples; k++) {
137  xpt = (*x.getPoint(k))[dim]; xwt = x.getWeight(k);
138  vpt = (*v.getPoint(k))[dim]; vwt = v.getWeight(k);
139  hs = 0.5 * (1. + erf((loc-xpt)/(sqrt2_*scale_)));
140  val += xwt * hs;
141  dval = std::exp(-std::pow((loc-xpt)/(sqrt2_*scale_),2));
142  gradx[k] = -(xwt/(sqrt2_*sqrtpi_*scale_)) * dval;
143  gradp[k] = hs;
144  hvxx[k] = -(xwt/(sqrt2_*sqrtpi_*scale3)) * dval * (loc-xpt) * vpt;
145  hvxp[k] = -dval/(sqrt2_*sqrtpi_*scale_)*vwt;
146  hvpx[k] = -dval/(sqrt2_*sqrtpi_*scale_)*vpt;
147  sumx += vpt*gradx[k];
148  sump += vwt*gradp[k];
149  }
150  return val;
151  }
152 
153 public:
154  CDFObjective(const std::vector<Teuchos::RCP<Distribution<Real> > > &dist,
155  const std::vector<Real> &lo, const std::vector<Real> &up,
156  const Real scale = 1.e-2)
157  : Objective<Real>(), dist_(dist), lowerBound_(lo), upperBound_(up), scale_(scale),
158  sqrt2_(std::sqrt(2.)), sqrtpi_(std::sqrt(M_PI)) {
160  }
161 
162  Real value( const Vector<Real> &x, Real &tol ) {
163  const SROMVector<Real> &ex = Teuchos::dyn_cast<const SROMVector<Real> >(x);
164  const size_t dimension = ex.getDimension();
165  Real val = 0., diff = 0., pt = 0., wt = 0., meas = 0., lb = 0.;
166  for (size_t d = 0; d < dimension; d++) {
167  lb = lowerBound_[d];
168  meas = (upperBound_[d] - lb);
169  for (size_t k = 0; k < numPoints_; k++) {
170  pt = meas*pts_[k] + lb;
171  wt = wts_[k]/meas;
172  diff = (valueCDF(d,pt,ex)-dist_[d]->evaluateCDF(pt));
173  val += wt*std::pow(diff,2);
174  }
175  }
176  return 0.5*val;
177  }
178 
179  void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
180  SROMVector<Real> &eg = Teuchos::dyn_cast<SROMVector<Real> >(g);
181  const SROMVector<Real> &ex = Teuchos::dyn_cast<const SROMVector<Real> >(x);
182  const size_t dimension = ex.getDimension();
183  const size_t numSamples = ex.getNumSamples();
184  std::vector<Real> gradx(numSamples,0.), gradp(numSamples,0.);
185  Real diff = 0., pt = 0., wt = 0., meas = 0., lb = 0., val = 0.;
186  std::vector<Real> val_wt(numSamples,0.), tmp(dimension,0.);
187  std::vector<std::vector<Real> > val_pt(numSamples,tmp);
188  for (size_t d = 0; d < dimension; d++) {
189  lb = lowerBound_[d];
190  meas = (upperBound_[d] - lb);
191  for (size_t k = 0; k < numPoints_; k++) {
192  pt = meas*pts_[k] + lb;
193  wt = wts_[k]/meas;
194  val = gradientCDF(gradx,gradp,d,pt,ex);
195  diff = (val-dist_[d]->evaluateCDF(pt));
196  for (size_t j = 0; j < numSamples; j++) {
197  (val_pt[j])[d] += wt * diff * gradx[j];
198  val_wt[j] += wt * diff * gradp[j];
199  }
200  }
201  }
202  for (size_t k = 0; k < numSamples; k++) {
203  eg.setPoint(k,val_pt[k]);
204  eg.setWeight(k,val_wt[k]);
205  }
206  }
207 
208  void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
209  SROMVector<Real> &ehv = Teuchos::dyn_cast<SROMVector<Real> >(hv);
210  const SROMVector<Real> &ev = Teuchos::dyn_cast<const SROMVector<Real> >(v);
211  const SROMVector<Real> &ex = Teuchos::dyn_cast<const SROMVector<Real> >(x);
212  const size_t dimension = ex.getDimension();
213  const size_t numSamples = ex.getNumSamples();
214  std::vector<Real> hvxx(numSamples,0.), hvxp(numSamples,0.), hvpx(numSamples,0.);
215  std::vector<Real> gradx(numSamples,0.), gradp(numSamples,0.);
216  Real diff = 0., pt = 0., wt = 0., meas = 0., lb = 0., val = 0., sumx = 0., sump = 0.;
217  std::vector<Real> val_wt(numSamples,0.), tmp(dimension,0.);
218  std::vector<std::vector<Real> > val_pt(numSamples,tmp);
219  for (size_t d = 0; d < dimension; d++) {
220  lb = lowerBound_[d];
221  meas = (upperBound_[d] - lb);
222  for (size_t k = 0; k < numPoints_; k++) {
223  pt = meas*pts_[k] + lb;
224  wt = wts_[k]/meas;
225  val = hessVecCDF(hvxx,hvxp,hvpx,gradx,gradp,sumx,sump,d,pt,ex,ev);
226  diff = (val-dist_[d]->evaluateCDF(pt));
227  for (size_t j = 0; j < numSamples; j++) {
228  (val_pt[j])[d] += wt * ( (sump + sumx) * gradx[j] + diff * (hvxx[j] + hvxp[j]) );
229  val_wt[j] += wt * ( (sump + sumx) * gradp[j] + diff * hvpx[j] );
230  }
231  }
232  }
233  for (size_t k = 0; k < numSamples; k++) {
234  ehv.setPoint(k,val_pt[k]);
235  ehv.setWeight(k,val_wt[k]);
236  }
237  }
238 }; // class LinearCombinationObjective
239 
240 } // namespace ROL
241 
242 #endif
Provides the interface to evaluate objective functions.
std::vector< Teuchos::RCP< Distribution< Real > > > dist_
Teuchos::RCP< const std::vector< Element > > getPoint(const size_t i) const
CDFObjective(const std::vector< Teuchos::RCP< Distribution< Real > > > &dist, const std::vector< Real > &lo, const std::vector< Real > &up, const Real scale=1.e-2)
Real value(const Vector< Real > &x, Real &tol)
Compute value.
const size_t getDimension(void) const
const Element getWeight(const size_t i) const
void setWeight(const size_t i, const Element wt)
Real valueCDF(const size_t dim, const Real loc, const SROMVector< Real > &x) const
const std::vector< Real > lowerBound_
Real gradientCDF(std::vector< Real > &gradx, std::vector< Real > &gradp, const size_t dim, const Real loc, const SROMVector< Real > &x) const
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:74
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
const size_t getNumSamples(void) const
std::vector< Real > wts_
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
void initializeQuadrature(void)
Provides the std::vector implementation of the ROL::Vector interface.
Real hessVecCDF(std::vector< Real > &hvxx, std::vector< Real > &hvxp, std::vector< Real > &hvpx, std::vector< Real > &gradx, std::vector< Real > &gradp, Real &sumx, Real &sump, const size_t dim, const Real loc, const SROMVector< Real > &x, const SROMVector< Real > &v) const
const std::vector< Real > upperBound_
std::vector< Real > pts_
void setPoint(const size_t i, const std::vector< Element > &pt)