ROL
ROL_MeanDeviation.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_MEANDEVIATION_HPP
45 #define ROL_MEANDEVIATION_HPP
46 
47 #include "ROL_RiskMeasure.hpp"
48 #include "ROL_PositiveFunction.hpp"
49 
50 namespace ROL {
51 
52 template<class Real>
53 class MeanDeviation : public RiskMeasure<Real> {
54 private:
55 
56  Teuchos::RCP<PositiveFunction<Real> > positiveFunction_;
57 
58  std::vector<Real> order_;
59  std::vector<Real> coeff_;
60 
61  std::vector<Real> weights_;
62  std::vector<Real> value_storage_;
63  std::vector<Real> gradvec_storage_;
64  std::vector<Teuchos::RCP<Vector<Real> > > gradient_storage_;
65  std::vector<Teuchos::RCP<Vector<Real> > > hessvec_storage_;
66 
67 public:
68 
69  MeanDeviation( Real order, Real coeff,
70  Teuchos::RCP<PositiveFunction<Real> > &pf )
71  : RiskMeasure<Real>(), positiveFunction_(pf) {
72  order_.clear(); coeff_.clear();
73  order_.push_back((order < 2.0) ? 2.0 : order);
74  coeff_.push_back((coeff < 0.0) ? 1.0 : coeff);
75  }
76 
77  MeanDeviation( std::vector<Real> &order, std::vector<Real> &coeff,
78  Teuchos::RCP<PositiveFunction<Real> > &pf )
79  : RiskMeasure<Real>(), positiveFunction_(pf) {
80  order_.clear(); coeff_.clear();
81  if ( order.size() != coeff.size() ) {
82  coeff.resize(order.size(),1.0);
83  }
84  for ( unsigned i = 0; i < order.size(); i++ ) {
85  order_.push_back((order[i] < 2.0) ? 2.0 : order[i]);
86  coeff_.push_back((coeff[i] < 0.0) ? 1.0 : coeff[i]);
87  }
88  }
89 
90  void reset(Teuchos::RCP<Vector<Real> > &x0, const Vector<Real> &x) {
92  value_storage_.clear();
93  gradient_storage_.clear();
94  gradvec_storage_.clear();
95  hessvec_storage_.clear();
96  weights_.clear();
97  }
98 
99  void reset(Teuchos::RCP<Vector<Real> > &x0, const Vector<Real> &x,
100  Teuchos::RCP<Vector<Real> > &v0, const Vector<Real> &v) {
101  RiskMeasure<Real>::reset(x0,x,v0,v);
102  value_storage_.clear();
103  gradient_storage_.clear();
104  gradvec_storage_.clear();
105  hessvec_storage_.clear();
106  weights_.clear();
107  }
108 
109  void update(const Real val, const Real weight) {
110  RiskMeasure<Real>::val_ += weight * val;
111  value_storage_.push_back(val);
112  weights_.push_back(weight);
113  }
114 
115  void update(const Real val, const Vector<Real> &g, const Real weight) {
116  RiskMeasure<Real>::val_ += weight * val;
117  RiskMeasure<Real>::g_->axpy(weight,g);
118  value_storage_.push_back(val);
119  gradient_storage_.push_back(g.clone());
120  typename std::vector<Teuchos::RCP<Vector<Real> > >::iterator it = gradient_storage_.end();
121  it--;
122  (*it)->set(g);
123  weights_.push_back(weight);
124  }
125 
126  void update(const Real val, const Vector<Real> &g, const Real gv, const Vector<Real> &hv,
127  const Real weight) {
128  RiskMeasure<Real>::val_ += weight * val;
129  RiskMeasure<Real>::gv_ += weight * gv;
130  RiskMeasure<Real>::g_->axpy(weight,g);
131  RiskMeasure<Real>::hv_->axpy(weight,hv);
132  value_storage_.push_back(val);
133  gradient_storage_.push_back(g.clone());
134  typename std::vector<Teuchos::RCP<Vector<Real> > >::iterator it = gradient_storage_.end();
135  it--;
136  (*it)->set(g);
137  gradvec_storage_.push_back(gv);
138  hessvec_storage_.push_back(hv.clone());
139  it = hessvec_storage_.end();
140  it--;
141  (*it)->set(hv);
142  weights_.push_back(weight);
143  }
144 
146  // Compute expected value
147  Real val = RiskMeasure<Real>::val_;
148  Real ev = 0.0;
149  sampler.sumAll(&val,&ev,1);
150  // Compute deviation
151  Real diff = 0.0, pf0 = 0.0, dev = 0.0;
152  std::vector<Real> devp(order_.size(),0.0);
153  std::vector<Real> devs(order_.size(),0.0);
154  for ( unsigned i = 0; i < weights_.size(); i++ ) {
155  diff = value_storage_[i]-ev;
156  pf0 = positiveFunction_->evaluate(diff,0);
157  for ( unsigned p = 0; p < order_.size(); p++ ) {
158  devp[p] += std::pow(pf0,order_[p]) * weights_[i];
159  }
160  }
161  sampler.sumAll(&devp[0],&devs[0],devp.size());
162  for ( unsigned p = 0; p < order_.size(); p++ ) {
163  dev += coeff_[p]*std::pow(devs[p],1.0/order_[p]);
164  }
165  // Return mean plus deviation
166  return ev + dev;
167  }
168 
170  g.zero();
171  // Compute expected value
172  Real val = RiskMeasure<Real>::val_;
173  Real ev = 0.0;
174  sampler.sumAll(&val,&ev,1);
175  // Compute deviation
176  Real diff = 0.0, pf0 = 0.0, pf1 = 0.0, c = 0.0;
177  std::vector<Real> dev0(order_.size(),0.0);
178  std::vector<Real> des0(order_.size(),0.0);
179  std::vector<Real> dev1(order_.size(),0.0);
180  std::vector<Real> des1(order_.size(),0.0);
181  for ( unsigned i = 0; i < weights_.size(); i++ ) {
182  diff = value_storage_[i]-ev;
183  pf0 = positiveFunction_->evaluate(diff,0);
184  pf1 = positiveFunction_->evaluate(diff,1);
185  for ( unsigned p = 0; p < order_.size(); p++ ) {
186  dev0[p] += weights_[i] * std::pow(pf0,order_[p]);
187  dev1[p] += weights_[i] * std::pow(pf0,order_[p]-1.0) * pf1;
188  }
189  }
190  sampler.sumAll(&dev0[0],&des0[0],dev0.size());
191  sampler.sumAll(&dev1[0],&des1[0],dev1.size());
192  for ( unsigned p = 0; p < order_.size(); p++ ) {
193  dev0[p] = std::pow(des0[p],1.0-1.0/order_[p]);
194  }
195  // Compute derivative
196  Teuchos::RCP<Vector<Real> > gtmp = g.clone();
197  gtmp->zero();
198  for ( unsigned i = 0; i < weights_.size(); i++ ) {
199  c = 0.0;
200  diff = value_storage_[i]-ev;
201  pf0 = positiveFunction_->evaluate(diff,0);
202  pf1 = positiveFunction_->evaluate(diff,1);
203  for ( unsigned p = 0; p < order_.size(); p++ ) {
204  if ( dev0[p] > 0.0 ) {
205  c += coeff_[p]/dev0[p] * (std::pow(pf0,order_[p]-1.0)*pf1 - des1[p]);
206  }
207  }
208  gtmp->axpy(weights_[i]*c,*(gradient_storage_[i]));
209  }
210  gtmp->axpy(1.0,*(RiskMeasure<Real>::g_));
211  sampler.sumAll(*gtmp,g);
212  }
213 
215  hv.zero();
216  // Compute expected value
217  Real val = RiskMeasure<Real>::val_;
218  Real ev = 0.0;
219  sampler.sumAll(&val,&ev,1);
220  Real gv = RiskMeasure<Real>::gv_;
221  Real egv = 0.0;
222  sampler.sumAll(&gv,&egv,1);
223  // Compute deviation
224  Real diff = 0.0, pf0 = 0.0, pf1 = 0.0, pf2 = 0.0;
225  Real cg = 0.0, ch = 0.0, diff1 = 0.0, diff2 = 0.0, diff3 = 0.0;
226  std::vector<Real> dev0(order_.size(),0.0);
227  std::vector<Real> dev1(order_.size(),0.0);
228  std::vector<Real> dev2(order_.size(),0.0);
229  std::vector<Real> dev3(order_.size(),0.0);
230  std::vector<Real> des0(order_.size(),0.0);
231  std::vector<Real> des1(order_.size(),0.0);
232  std::vector<Real> des2(order_.size(),0.0);
233  std::vector<Real> des3(order_.size(),0.0);
234  std::vector<Real> devp(order_.size(),0.0);
235  std::vector<Real> gvp1(order_.size(),0.0);
236  std::vector<Real> gvp2(order_.size(),0.0);
237  std::vector<Real> gvp3(order_.size(),0.0);
238  std::vector<Real> gvs1(order_.size(),0.0);
239  std::vector<Real> gvs2(order_.size(),0.0);
240  std::vector<Real> gvs3(order_.size(),0.0);
241  for ( unsigned i = 0; i < weights_.size(); i++ ) {
242  diff = value_storage_[i]-ev;
243  pf0 = positiveFunction_->evaluate(diff,0);
244  pf1 = positiveFunction_->evaluate(diff,1);
245  pf2 = positiveFunction_->evaluate(diff,2);
246  for ( unsigned p = 0; p < order_.size(); p++ ) {
247  dev0[p] += weights_[i] * std::pow(pf0,order_[p]);
248  dev1[p] += weights_[i] * std::pow(pf0,order_[p]-1.0) * pf1;
249  dev2[p] += weights_[i] * std::pow(pf0,order_[p]-2.0) * pf1 * pf1;
250  dev3[p] += weights_[i] * std::pow(pf0,order_[p]-1.0) * pf2;
251  }
252  }
253  sampler.sumAll(&dev0[0],&des0[0],dev0.size());
254  sampler.sumAll(&dev1[0],&des1[0],dev1.size());
255  sampler.sumAll(&dev2[0],&des2[0],dev2.size());
256  sampler.sumAll(&dev3[0],&des3[0],dev3.size());
257  for ( unsigned p = 0; p < order_.size(); p++ ) {
258  devp[p] = std::pow(des0[p],2.0-1.0/order_[p]);
259  dev0[p] = std::pow(des0[p],1.0-1.0/order_[p]);
260  }
261  for ( unsigned i = 0; i < value_storage_.size(); i++ ) {
262  diff = value_storage_[i]-ev;
263  pf0 = positiveFunction_->evaluate(diff,0);
264  pf1 = positiveFunction_->evaluate(diff,1);
265  pf2 = positiveFunction_->evaluate(diff,2);
266  for ( unsigned p = 0; p < order_.size(); p++ ) {
267  gvp1[p] += weights_[i] * (std::pow(pf0,order_[p]-1.0)*pf1-des1[p]) *
268  (gradvec_storage_[i] - egv);
269  gvp2[p] += weights_[i] * (std::pow(pf0,order_[p]-2.0)*pf1*pf1-des2[p]) *
270  (gradvec_storage_[i] - egv);
271  gvp3[p] += weights_[i] * (std::pow(pf0,order_[p]-1.0)*pf2-des3[p]) *
272  (gradvec_storage_[i] - egv);
273  }
274  }
275  sampler.sumAll(&gvp1[0],&gvs1[0],gvp1.size());
276  sampler.sumAll(&gvp2[0],&gvs2[0],gvp2.size());
277  sampler.sumAll(&gvp3[0],&gvs3[0],gvp3.size());
278  // Compute derivative
279  Teuchos::RCP<Vector<Real> > htmp = hv.clone();
280  htmp->zero();
281  for ( unsigned i = 0; i < weights_.size(); i++ ) {
282  cg = 1.0;
283  ch = 0.0;
284  diff = value_storage_[i]-ev;
285  pf0 = positiveFunction_->evaluate(diff,0);
286  pf1 = positiveFunction_->evaluate(diff,1);
287  pf2 = positiveFunction_->evaluate(diff,2);
288  for ( unsigned p = 0; p < order_.size(); p++ ) {
289  if ( dev0[p] > 0.0 ) {
290  diff1 = std::pow(pf0,order_[p]-1.0)*pf1-des1[p];
291  diff2 = std::pow(pf0,order_[p]-2.0)*pf1*pf1*(gradvec_storage_[i]-egv)-gvs2[p];
292  diff3 = std::pow(pf0,order_[p]-1.0)*pf2*(gradvec_storage_[i]-egv)-gvs3[p];
293  cg += coeff_[p]*diff1/dev0[p];
294  ch += coeff_[p]*(((order_[p]-1.0)*diff2+diff3)/dev0[p] -
295  (order_[p]-1.0)*gvs1[p]*diff1/devp[p]);
296  }
297  }
298  htmp->axpy(weights_[i]*ch,*(gradient_storage_[i]));
299  htmp->axpy(weights_[i]*cg,*(hessvec_storage_[i]));
300  }
301  sampler.sumAll(*htmp,hv);
302  }
303 };
304 
305 }
306 
307 #endif
Real getValue(SampleGenerator< Real > &sampler)
MeanDeviation(Real order, Real coeff, Teuchos::RCP< PositiveFunction< Real > > &pf)
virtual Teuchos::RCP< Vector > clone() const =0
Clone to make a new (uninitialized) vector.
virtual void zero()
Set to zero vector.
Definition: ROL_Vector.hpp:157
Defines the linear algebra or vector space interface.
Definition: ROL_Vector.hpp:74
void sumAll(Real *input, Real *output, int dim) const
void getGradient(Vector< Real > &g, SampleGenerator< Real > &sampler)
void reset(Teuchos::RCP< Vector< Real > > &x0, const Vector< Real > &x, Teuchos::RCP< Vector< Real > > &v0, const Vector< Real > &v)
std::vector< Real > order_
std::vector< Real > value_storage_
std::vector< Teuchos::RCP< Vector< Real > > > gradient_storage_
std::vector< Real > gradvec_storage_
void update(const Real val, const Real weight)
void update(const Real val, const Vector< Real > &g, const Real gv, const Vector< Real > &hv, const Real weight)
void update(const Real val, const Vector< Real > &g, const Real weight)
virtual void reset(Teuchos::RCP< Vector< Real > > &x0, const Vector< Real > &x)
MeanDeviation(std::vector< Real > &order, std::vector< Real > &coeff, Teuchos::RCP< PositiveFunction< Real > > &pf)
Teuchos::RCP< PositiveFunction< Real > > positiveFunction_
void reset(Teuchos::RCP< Vector< Real > > &x0, const Vector< Real > &x)
std::vector< Real > weights_
std::vector< Real > coeff_
std::vector< Teuchos::RCP< Vector< Real > > > hessvec_storage_
void getHessVec(Vector< Real > &hv, SampleGenerator< Real > &sampler)