ROL
Loading...
Searching...
No Matches
ROL_MonteCarloGeneratorDef.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_MONTECARLOGENERATORDEF_HPP
11#define ROL_MONTECARLOGENERATORDEF_HPP
12
13namespace ROL {
14
15template<typename Real>
16Real MonteCarloGenerator<Real>::ierf(Real input) const {
17 std::vector<Real> coeff;
18 const Real pi = ScalarTraits<Real>::pi(), zero(0), one(1), two(2), tol(1e-4);
19 Real c(1);
20 Real tmp = c * (std::sqrt(pi)/two * input);
21 Real val = tmp;
22 coeff.push_back(c);
23 int cnt = 1;
24 while (std::abs(tmp) > tol*std::abs(val)) {
25 c = zero;
26 for ( unsigned i = 0; i < coeff.size(); ++i )
27 c += coeff[i]*coeff[coeff.size()-1-i]/static_cast<Real>((i+1)*(2*i+1));
28 Real ind = static_cast<Real>(cnt);
29 tmp = c/(two*ind+one) * std::pow(std::sqrt(pi)/two*input, two*ind+one);
30 val += tmp;
31 coeff.push_back(c);
32 cnt++;
33 }
34 return val;
35}
36
37template<typename Real>
39 return static_cast<Real>(rand())/static_cast<Real>(RAND_MAX);
40}
41
42template<typename Real>
43std::vector<std::vector<Real>> MonteCarloGenerator<Real>::sample(int nSamp, bool store, bool refine) {
44 if (!refine) srand(seed_);
45 const Real zero(0), one(1), two(2), tol(0.1);
47 const int dim = (!useDist_ ? data_.size() : dist_.size());
48 std::vector<Real> pts(nSamp*dim, zero);
49 if (rank == 0) {
50 // Generate samples
51 for (int i = 0; i < nSamp; ++i) {
52 if ( !useDist_ ) {
53 for (int j = 0; j < dim; ++j) {
54 if ( use_normal_ )
55 pts[j + i*dim] = std::sqrt(two*(data_[j])[1])*ierf(two*random()-one) + (data_[j])[0];
56 else
57 pts[j + i*dim] = ((data_[j])[1]-(data_[j])[0])*random()+(data_[j])[0];
58 }
59 }
60 else {
61 for (int j = 0; j < dim; ++j) {
62 pts[j + i*dim] = (dist_[j])->invertCDF(random());
63 while (std::abs(pts[j + i*dim]) > tol*ROL_INF<Real>())
64 pts[j + i*dim] = (dist_[j])->invertCDF(random());
65 }
66 }
67 }
68 }
70 // Separate samples across processes
72 int frac = nSamp / nProc;
73 int rem = nSamp % nProc;
74 int N = frac + ((rank < rem) ? 1 : 0);
75 int offset = 0;
76 for (int i = 0; i < rank; ++i) offset += frac + ((i < rem) ? 1 : 0);
77 std::vector<std::vector<Real>> mypts;
78 std::vector<Real> pt(dim);
79 for (int i = 0; i < N; ++i) {
80 int I = offset+i;
81 for (int j = 0; j < dim; ++j) pt[j] = pts[j + I*dim];
82 mypts.push_back(pt);
83 }
84 if ( store ) {
85 std::vector<Real> mywts(N, one/static_cast<Real>(nSamp));
88 }
89 return mypts;
90}
91
92template<typename Real>
94 const std::vector<Ptr<Distribution<Real>>> &dist,
95 const Ptr<BatchManager<Real>> &bman,
96 bool use_SA, bool adaptive, int numNewSamps, int seed)
97 : SampleGenerator<Real>(bman),
98 dist_(dist),
99 use_normal_(false),
100 useDist_(true),
101 sum_val_(0),
102 sum_val2_(0),
103 sum_ng_(0),
104 sum_ng2_(0),
105 nSamp_(nSamp),
106 use_SA_(use_SA),
107 adaptive_(adaptive),
108 numNewSamps_(numNewSamps),
109 seed_(seed) {
111 ROL_TEST_FOR_EXCEPTION( nSamp_ < nProc, std::invalid_argument,
112 ">>> ERROR (ROL::MonteCarloGenerator): Total number of samples is less than the number of batches!");
113 sample(nSamp_,true,false);
114}
115
116template<typename Real>
118 std::vector<std::vector<Real>> &bounds,
119 const Ptr<BatchManager<Real>> &bman,
120 bool use_SA, bool adaptive, int numNewSamps, int seed)
121 : SampleGenerator<Real>(bman),
122 use_normal_(false),
123 useDist_(false),
124 sum_val_(0),
125 sum_val2_(0),
126 sum_ng_(0),
127 sum_ng2_(0),
128 nSamp_(nSamp),
129 use_SA_(use_SA),
130 adaptive_(adaptive),
131 numNewSamps_(numNewSamps),
132 seed_(seed) {
134 ROL_TEST_FOR_EXCEPTION( nSamp_ < nProc, std::invalid_argument,
135 ">>> ERROR (ROL::MonteCarloGenerator): Total number of samples is less than the number of batches!");
136 unsigned dim = bounds.size();
137 data_.clear();
138 Real tmp(0);
139 for ( unsigned j = 0; j < dim; ++j ) {
140 if ( (bounds[j])[0] > (bounds[j])[1] ) {
141 tmp = (bounds[j])[0];
142 (bounds[j])[0] = (bounds[j])[1];
143 (bounds[j])[1] = tmp;
144 data_.push_back(bounds[j]);
145 }
146 data_.push_back(bounds[j]);
147 }
148 sample(nSamp_,true,false);
149}
150
151template<typename Real>
153 const std::vector<Real> &mean,
154 const std::vector<Real> &std,
155 const Ptr<BatchManager<Real>> &bman,
156 bool use_SA, bool adaptive, int numNewSamps, int seed)
157 : SampleGenerator<Real>(bman),
158 use_normal_(true),
159 useDist_(false),
160 seed_(seed),
161 sum_val_(0),
162 sum_val2_(0),
163 sum_ng_(0),
164 sum_ng2_(0),
165 nSamp_(nSamp),
166 use_SA_(use_SA),
167 adaptive_(adaptive),
168 numNewSamps_(numNewSamps) {
170 ROL_TEST_FOR_EXCEPTION( nSamp_ < nProc, std::invalid_argument,
171 ">>> ERROR (ROL::MonteCarloGenerator): Total number of samples is less than the number of batches!");
172 unsigned dim = mean.size();
173 data_.clear();
174 for ( unsigned j = 0; j < dim; ++j )
175 data_.push_back({mean[j],std[j]});
176 sample(nSamp_,true,false);
177}
178
179
180template<typename Real>
182 const Ptr<BatchManager<Real>> &bman,
183 bool use_SA, bool adaptive, int numNewSamps, int seed)
184 : SampleGenerator<Real>(bman),
185 use_normal_(false),
186 useDist_(false),
187 sum_val_(0),
188 sum_val2_(0),
189 sum_ng_(0),
190 sum_ng2_(0),
191 nSamp_(0),
192 use_SA_(use_SA),
193 adaptive_(adaptive),
194 numNewSamps_(numNewSamps),
195 seed_(seed) {}
196
197template<typename Real>
200 sum_val_ = static_cast<Real>(0);
201 sum_val2_ = static_cast<Real>(0);
202 sum_ng_ = static_cast<Real>(0);
203 sum_ng_ = static_cast<Real>(0);
204 if ( use_SA_ ) sample(nSamp_,true,true);
205}
206
207template<typename Real>
208Real MonteCarloGenerator<Real>::computeError( std::vector<Real> &vals ) {
209 Real err(0);
210 if ( adaptive_ && !use_SA_ ) {
211 const Real zero(0), one(1), tol(1e-8);
212 // Compute unbiased sample variance
213 int cnt = 0;
214 for ( int i = SampleGenerator<Real>::start(); i < SampleGenerator<Real>::numMySamples(); ++i ) {
215 sum_val_ += vals[cnt];
216 sum_val2_ += vals[cnt]*vals[cnt];
217 cnt++;
218 }
219 Real mymean = sum_val_ / static_cast<Real>(nSamp_);
220 Real mean = zero;
221 SampleGenerator<Real>::sumAll(&mymean,&mean,1);
222
223 Real myvar = (sum_val2_ - mean*mean)/(static_cast<Real>(nSamp_)-one);
224 Real var = zero;
225 SampleGenerator<Real>::sumAll(&myvar,&var,1);
226 // Return Monte Carlo error
227 vals.clear();
228 err = std::sqrt(var/static_cast<Real>(nSamp_))*tol;
229 }
230 else {
231 vals.clear();
232 }
233 return err;
234}
235
236template<typename Real>
238 const Vector<Real> &x ) {
239 Real err(0);
240 if ( adaptive_ && !use_SA_ ) {
241 const Real zero(0), one(1), tol(1e-4);
242 // Compute unbiased sample variance
243 int cnt = 0;
244 Real ng = zero;
245 for ( int i = SampleGenerator<Real>::start(); i < SampleGenerator<Real>::numMySamples(); ++i ) {
246 ng = (vals[cnt])->norm();
247 sum_ng_ += ng;
248 sum_ng2_ += ng*ng;
249 cnt++;
250 }
251 Real mymean = sum_ng_ / static_cast<Real>(nSamp_);
252 Real mean = zero;
253 SampleGenerator<Real>::sumAll(&mymean,&mean,1);
254
255 Real myvar = (sum_ng2_ - mean*mean)/(static_cast<Real>(nSamp_)-one);
256 Real var = zero;
257 SampleGenerator<Real>::sumAll(&myvar,&var,1);
258 // Return Monte Carlo error
259 vals.clear();
260 err = std::sqrt(var/static_cast<Real>(nSamp_))*tol;
261 }
262 else {
263 vals.clear();
264 }
265 return err;
266}
267
268template<typename Real>
270 if ( adaptive_ && !use_SA_ ) {
271 std::vector<std::vector<Real>> pts;
272 for ( int i = 0; i < SampleGenerator<Real>::numMySamples(); ++i )
273 pts.push_back(SampleGenerator<Real>::getMyPoint(i));
274 std::vector<std::vector<Real>> pts_new = sample(numNewSamps_,false,true);
275 pts.insert(pts.end(),pts_new.begin(),pts_new.end());
276 nSamp_ += numNewSamps_;
277 std::vector<Real> wts(pts.size(),static_cast<Real>(1)/static_cast<Real>(nSamp_));
281 }
282}
283
284template<typename Real>
286 return nSamp_;
287}
288
289}
290#endif
Objective_SerialSimOpt(const Ptr< Obj > &obj, const V &ui) z0_ zero()
Real computeError(std::vector< Real > &vals) override
std::vector< std::vector< Real > > data_
MonteCarloGenerator(int nSamp, const std::vector< Ptr< Distribution< Real > > > &dist, const Ptr< BatchManager< Real > > &bman, bool use_SA=false, bool adaptive=false, int numNewSamps=0, int seed=123454321)
void update(const Vector< Real > &x) override
int numGlobalSamples(void) const override
virtual std::vector< std::vector< Real > > sample(int nSamp, bool store=true, bool refine=false)
void setPoints(std::vector< std::vector< Real > > &p)
void setWeights(std::vector< Real > &w)
void broadcast(Real *input, int cnt, int root) const
virtual void refine(void)
void sumAll(Real *input, Real *output, int dim) const
virtual void update(const Vector< Real > &x)
Defines the linear algebra or vector space interface.
Real random(const ROL::Ptr< const Teuchos::Comm< int > > &comm)
static constexpr Real pi() noexcept
constexpr auto dim