OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
LatinHyperCube.h
Go to the documentation of this file.
1 //
2 // Class LatinHyperCube
3 // This class does Latin hypercube sampling.
4 //
5 // Copyright (c) 2018, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved
7 //
8 // Implemented as part of the PhD thesis
9 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
10 //
11 // This file is part of OPAL.
12 //
13 // OPAL is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
20 //
21 #ifndef OPAL_LATIN_HYPERCUBE_H
22 #define OPAL_LATIN_HYPERCUBE_H
23 
24 #include "Sample/SamplingMethod.h"
25 #include "Sample/RNGStream.h"
26 
27 #include <algorithm>
28 #include <deque>
29 
31 {
32 
33 public:
34  typedef typename std::uniform_real_distribution<double> dist_t;
35 
36  LatinHyperCube(double lower, double upper)
37  : binsize_m(0.0)
38  , upper_m(upper)
39  , lower_m(lower)
40  , dist_m(0.0, 1.0)
41  , RNGInstance_m(RNGStream::getInstance())
42  , seed_m(RNGStream::getGlobalSeed())
43  {}
44 
45  LatinHyperCube(double lower, double upper, int seed)
46  : binsize_m(0.0)
47  , upper_m(upper)
48  , lower_m(lower)
49  , dist_m(0.0, 1.0)
50  , RNGInstance_m(nullptr)
51  , seed_m(seed)
52  {}
53 
55  if ( RNGInstance_m )
57  }
58 
59  void create(boost::shared_ptr<SampleIndividual>& ind, std::size_t i) {
60  /* values are created within [0, 1], thus, they need to be mapped
61  * the domain [lower, upper]
62  */
63  ind->genes[i] = map2domain_m(RNGInstance_m->getNext(dist_m));
64  }
65 
66  void allocate(const CmdArguments_t& args, const Comm::Bundle_t& comm) {
67  int id = comm.island_id;
68 
69  if ( !RNGInstance_m )
71 
72  int nSamples = args->getArg<int>("nsamples", true);
73  int nMasters = args->getArg<int>("num-masters", true);
74 
75  int nLocSamples = nSamples / nMasters;
76  int rest = nSamples - nMasters * nLocSamples;
77 
78  if ( id < rest )
79  nLocSamples++;
80 
81  int startBin = 0;
82 
83  if ( rest == 0 )
84  startBin = nLocSamples * id;
85  else {
86  if ( id < rest ) {
87  startBin = nLocSamples * id;
88  } else {
89  startBin = (nLocSamples + 1) * rest + (id - rest) * nLocSamples;
90  }
91  }
92 
93  binsize_m = ( upper_m - lower_m ) / double(nSamples);
94 
95  this->fillBins_m(nSamples, nLocSamples, startBin, seed_m);
96  }
97 
98 private:
99  double map2domain_m(double val) {
100  /* y = mx + q
101  *
102  * [0, 1] --> [a, b]
103  *
104  * y = (b - a) * x + a
105  *
106  * where a and b are the lower, respectively, upper
107  * bound of the current bin.
108  */
109 
110  std::size_t bin = bin_m.back();
111  bin_m.pop_back();
112 
113  return binsize_m * (val + bin) + lower_m;
114  }
115 
116  void fillBins_m(std::size_t nTotal, std::size_t nLocal, int startBin,
117  std::size_t seed)
118  {
119  std::deque<std::size_t> tmp;
120  tmp.resize(nTotal);
121  std::iota(tmp.begin(), tmp.end(), 0);
122 
123  // all masters need to shuffle the same way
124  std::mt19937_64 eng(seed);
125  std::shuffle(tmp.begin(), tmp.end(), eng);
126 
127  // each master takes its bins
128  std::copy(tmp.begin()+startBin,
129  tmp.begin()+startBin+nLocal,
130  std::back_inserter(bin_m));
131  }
132 
133 private:
134  std::deque<std::size_t> bin_m;
135  double binsize_m;
136 
137  double upper_m;
138  double lower_m;
139 
141 
143 
144  std::size_t seed_m;
145 };
146 
147 #endif
boost::shared_ptr< CmdArguments > CmdArguments_t
Definition: CmdArguments.h:176
int seed
The current random seed.
Definition: Options.cpp:37
void create(boost::shared_ptr< SampleIndividual > &ind, std::size_t i)
LatinHyperCube(double lower, double upper, int seed)
RNGStream * RNGInstance_m
std::size_t seed_m
double map2domain_m(double val)
void allocate(const CmdArguments_t &args, const Comm::Bundle_t &comm)
std::deque< std::size_t > bin_m
LatinHyperCube(double lower, double upper)
void fillBins_m(std::size_t nTotal, std::size_t nLocal, int startBin, std::size_t seed)
std::uniform_real_distribution< double > dist_t
static RNGStream * getInstance()
Definition: RNGStream.cpp:26
static void deleteInstance(RNGStream *&generator)
Definition: RNGStream.cpp:38
DISTR::result_type getNext(DISTR &RNGDist)
Definition: RNGStream.h:37
bundles all communicators for a specific role/pid
Definition: types.h:32
int island_id
Definition: types.h:33