ROL
ROL_MomentObjective.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_MOMENTOBJECTIVE_H
11#define ROL_MOMENTOBJECTIVE_H
12
13#include "ROL_Objective.hpp"
14#include "ROL_BatchManager.hpp"
15#include "ROL_Distribution.hpp"
16#include "ROL_SROMVector.hpp"
17#include "ROL_Types.hpp"
18#include <iostream>
19
20namespace ROL {
21
22template <class Real>
23class MomentObjective : public Objective<Real> {
24private:
25 std::vector<std::vector<std::pair<int, Real> > > moments_;
26 ROL::Ptr<BatchManager<Real> > bman_;
29 const bool optProb_;
30 const bool optAtom_;
31
32 Real momentValue(const int dim, const Real power, const Real moment,
33 const ProbabilityVector<Real> &prob,
34 const AtomVector<Real> &atom) const {
35 const int numSamples = prob.getNumMyAtoms();
36 Real val(0), xpt(0), xwt(0), sum(0), half(0.5), one(1), two(2);
37 for (int k = 0; k < numSamples; k++) {
38 xpt = (*atom.getAtom(k))[dim]; xwt = prob.getProbability(k);
39 val += xwt * ((power==one) ? xpt : std::pow(xpt,power));
40 }
41 bman_->sumAll(&val,&sum,1);
42 Real denom = ((std::abs(moment) < ROL_EPSILON<Real>()) ? one : moment);
43 return half*std::pow((sum-moment)/denom,two);
44 }
45
46 void momentGradient(std::vector<Real> &gradx, std::vector<Real> &gradp, Real &scale,
47 const int dim, const Real power, const Real moment,
48 const ProbabilityVector<Real> &prob,
49 const AtomVector<Real> &atom) const {
50 const int numSamples = prob.getNumMyAtoms();
51 gradx.resize(numSamples,0); gradp.resize(numSamples,0);
52 scale = 0;
53 Real xpt(0), xwt(0), xpow(0), psum(0), one(1), two(2);
54 for (int k = 0; k < numSamples; k++) {
55 xpt = (*atom.getAtom(k))[dim]; xwt = prob.getProbability(k);
56 xpow = ((power==one) ? one : ((power==two) ? xpt : std::pow(xpt,power-one)));
57 psum += xwt * xpow * xpt;
58 gradx[k] = xwt * xpow * power;
59 gradp[k] = xpow * xpt;
60 }
61 bman_->sumAll(&psum,&scale,1);
62 scale -= moment;
63 Real denom = ((std::abs(moment) < ROL_EPSILON<Real>()) ? one : moment);
64 scale /= std::pow(denom,two);
65 }
66
67 void momentHessVec(std::vector<Real> &hvx1, std::vector<Real> &hvx2, std::vector<Real> &hvx3,
68 std::vector<Real> &hvp1, std::vector<Real> &hvp2,
69 Real &scale1, Real &scale2, Real &scale3,
70 const int dim, const Real power, const Real moment,
71 const ProbabilityVector<Real> &prob,
72 const AtomVector<Real> &atom,
73 const ProbabilityVector<Real> &vprob,
74 const AtomVector<Real> &vatom) const {
75 const int numSamples = prob.getNumMyAtoms();
76 hvx1.resize(numSamples,0); hvx2.resize(numSamples,0); hvx3.resize(numSamples,0);
77 hvp1.resize(numSamples,0); hvp2.resize(numSamples,0);
78 scale1 = 0; scale2 = 0; scale3 = 0;
79 std::vector<Real> psum(3,0), scale(3,0);
80 Real xpt(0), xwt(0), vpt(0), vwt(0);
81 Real xpow0(0), xpow1(0), xpow2(0), zero(0), one(1), two(2), three(3);
82 for (int k = 0; k < numSamples; k++) {
83 xpt = (*atom.getAtom(k))[dim]; xwt = prob.getProbability(k);
84 vpt = (*vatom.getAtom(k))[dim]; vwt = vprob.getProbability(k);
85 xpow2 = ((power==one) ? zero : ((power==two) ? one : ((power==three) ? xpt :
86 std::pow(xpt,power-two))));
87 xpow1 = ((power==one) ? one : xpow2 * xpt);
88 xpow0 = xpow1 * xpt;
89 psum[0] += xwt * xpow1 * vpt;
90 psum[1] += xwt * xpow0;
91 psum[2] += vwt * xpow0;
92 hvx1[k] = power * xwt * xpow1;
93 hvx2[k] = power * (power-one) * xwt * xpow2 * vpt;
94 hvx3[k] = power * vwt * xpow1;
95 hvp1[k] = xpow0;
96 hvp2[k] = power * xpow1 * vpt;
97 }
98 bman_->sumAll(&psum[0],&scale[0],3);
99 Real denom = ((std::abs(moment) < ROL_EPSILON<Real>()) ? one : moment);
100 Real denom2 = denom*denom;
101 //const Real moment2 = std::pow(moment,2);
102 scale1 = scale[0] * power/denom2;
103 scale2 = (scale[1] - moment)/denom2 ;
104 scale3 = scale[2]/denom2;
105 }
106
107public:
108 MomentObjective(const std::vector<std::vector<std::pair<int, Real> > > &moments,
109 const ROL::Ptr<BatchManager<Real> > &bman,
110 const bool optProb = true, const bool optAtom = true)
111 : Objective<Real>(), moments_(moments), bman_(bman),
112 optProb_(optProb), optAtom_(optAtom) {
113 dimension_ = moments_.size();
114 numMoments_ = moments_[0].size();
115 }
116
117 MomentObjective(const std::vector<ROL::Ptr<Distribution<Real> > > &dist,
118 const std::vector<int> &order,
119 const ROL::Ptr<BatchManager<Real> > &bman,
120 const bool optProb = true, const bool optAtom = true)
121 : Objective<Real>(), bman_(bman), optProb_(optProb), optAtom_(optAtom) {
122 numMoments_ = order.size();
123 dimension_ = dist.size();
124 std::vector<std::pair<int,Real> > data(numMoments_);
125 moments_.clear(); moments_.resize(dimension_);
126 for (int d = 0; d < dimension_; d++) {
127 for (int i = 0; i < numMoments_; i++) {
128 data[i] = std::make_pair(order[i],dist[d]->moment(order[i]));
129 }
130 moments_[d].assign(data.begin(),data.end());
131 }
132 }
133
134 Real value( const Vector<Real> &x, Real &tol ) {
135 const SROMVector<Real> &ex = dynamic_cast<const SROMVector<Real>&>(x);
136 const ProbabilityVector<Real> &prob = *(ex.getProbabilityVector());
137 const AtomVector<Real> &atom = *(ex.getAtomVector());
138 Real val(0);
139 std::vector<std::pair<int, Real> > data;
140 for (int d = 0; d < dimension_; d++) {
141 data = moments_[d];
142 for (int m = 0; m < numMoments_; m++) {
143 val += momentValue(d,(Real)data[m].first,data[m].second,prob,atom);
144 }
145 }
146 return val;
147 }
148
149 void gradient( Vector<Real> &g, const Vector<Real> &x, Real &tol ) {
150 g.zero();
151 const SROMVector<Real> &ex = dynamic_cast<const SROMVector<Real>&>(x);
152 const ProbabilityVector<Real> &prob = *(ex.getProbabilityVector());
153 const AtomVector<Real> &atom = *(ex.getAtomVector());
154 int numSamples = prob.getNumMyAtoms();
155 std::vector<Real> gradx(numSamples,0), gradp(numSamples,0);
156 Real scale(0);
157 std::vector<std::pair<int, Real> > data;
158 std::vector<Real> val_wt(numSamples,0), tmp(dimension_,0);
159 std::vector<std::vector<Real> > val_pt(numSamples,tmp);
160 for (int d = 0; d < dimension_; d++) {
161 data = moments_[d];
162 for (int m = 0; m < numMoments_; m++) {
163 momentGradient(gradx,gradp,scale,d,(Real)data[m].first,data[m].second,prob,atom);
164 for (int k = 0; k < numSamples; k++) {
165 (val_pt[k])[d] += scale*gradx[k];
166 val_wt[k] += scale*gradp[k];
167 }
168 }
169 }
170 SROMVector<Real> &eg = dynamic_cast<SROMVector<Real>&>(g);
172 AtomVector<Real> &gatom = *(eg.getAtomVector());
173 for (int k = 0; k < numSamples; k++) {
174 if ( optProb_ ) {
175 gprob.setProbability(k,val_wt[k]);
176 }
177 if ( optAtom_ ) {
178 gatom.setAtom(k,val_pt[k]);
179 }
180 }
181 }
182
183 void hessVec( Vector<Real> &hv, const Vector<Real> &v, const Vector<Real> &x, Real &tol ) {
184 hv.zero();
185 const SROMVector<Real> &ev = dynamic_cast<const SROMVector<Real>&>(v);
186 const ProbabilityVector<Real> &vprob = *(ev.getProbabilityVector());
187 const AtomVector<Real> &vatom = *(ev.getAtomVector());
188 const SROMVector<Real> &ex = dynamic_cast<const SROMVector<Real>&>(x);
189 const ProbabilityVector<Real> &prob = *(ex.getProbabilityVector());
190 const AtomVector<Real> &atom = *(ex.getAtomVector());
191 const int numSamples = prob.getNumMyAtoms();
192 std::vector<Real> hvx1(numSamples,0), hvx2(numSamples,0), hvx3(numSamples,0);
193 std::vector<Real> hvp1(numSamples,0), hvp2(numSamples,0);
194 Real scale1(0), scale2(0), scale3(0);
195 std::vector<std::pair<int, Real> > data;
196 std::vector<Real> val_wt(numSamples,0), tmp(dimension_,0);
197 std::vector<std::vector<Real> > val_pt(numSamples,tmp);
198 for (int d = 0; d < dimension_; d++) {
199 data = moments_[d];
200 for (int m = 0; m < numMoments_; m++) {
201 momentHessVec(hvx1,hvx2,hvx3,hvp1,hvp2,scale1,scale2,scale3,
202 d,(Real)data[m].first,data[m].second,prob,atom,vprob,vatom);
203 for (int k = 0; k < numSamples; k++) {
204 (val_pt[k])[d] += (scale1+scale3)*hvx1[k] + scale2*(hvx2[k]+hvx3[k]);
205 val_wt[k] += (scale1+scale3)*hvp1[k] + scale2*hvp2[k];
206 }
207 }
208 }
209 SROMVector<Real> &ehv = dynamic_cast<SROMVector<Real>&>(hv);
211 AtomVector<Real> &hatom = *(ehv.getAtomVector());
212 for (int k = 0; k < numSamples; k++) {
213 if ( optProb_ ) {
214 hprob.setProbability(k,val_wt[k]);
215 }
216 if ( optAtom_ ) {
217 hatom.setAtom(k,val_pt[k]);
218 }
219 }
220 }
221}; // class SROMObjective
222
223} // namespace ROL
224
225#endif
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Contains definitions of custom data types in ROL.
Provides the std::vector implementation of the ROL::Vector interface.
ROL::Ptr< const std::vector< Real > > getAtom(const int i) const
void setAtom(const int i, const std::vector< Real > &pt)
void momentHessVec(std::vector< Real > &hvx1, std::vector< Real > &hvx2, std::vector< Real > &hvx3, std::vector< Real > &hvp1, std::vector< Real > &hvp2, Real &scale1, Real &scale2, Real &scale3, const int dim, const Real power, const Real moment, const ProbabilityVector< Real > &prob, const AtomVector< Real > &atom, const ProbabilityVector< Real > &vprob, const AtomVector< Real > &vatom) const
MomentObjective(const std::vector< ROL::Ptr< Distribution< Real > > > &dist, const std::vector< int > &order, const ROL::Ptr< BatchManager< Real > > &bman, const bool optProb=true, const bool optAtom=true)
void hessVec(Vector< Real > &hv, const Vector< Real > &v, const Vector< Real > &x, Real &tol)
Apply Hessian approximation to vector.
Real momentValue(const int dim, const Real power, const Real moment, const ProbabilityVector< Real > &prob, const AtomVector< Real > &atom) const
void momentGradient(std::vector< Real > &gradx, std::vector< Real > &gradp, Real &scale, const int dim, const Real power, const Real moment, const ProbabilityVector< Real > &prob, const AtomVector< Real > &atom) const
std::vector< std::vector< std::pair< int, Real > > > moments_
Real value(const Vector< Real > &x, Real &tol)
Compute value.
MomentObjective(const std::vector< std::vector< std::pair< int, Real > > > &moments, const ROL::Ptr< BatchManager< Real > > &bman, const bool optProb=true, const bool optAtom=true)
ROL::Ptr< BatchManager< Real > > bman_
void gradient(Vector< Real > &g, const Vector< Real > &x, Real &tol)
Compute gradient.
Provides the interface to evaluate objective functions.
Provides the std::vector implementation of the ROL::Vector interface.
const Real getProbability(const int i) const
Provides the std::vector implementation of the ROL::Vector interface.
const ROL::Ptr< const ProbabilityVector< Real > > getProbabilityVector(void) const
const ROL::Ptr< const AtomVector< Real > > getAtomVector(void) const
Defines the linear algebra or vector space interface.
virtual void zero()
Set to zero vector.
constexpr auto dim