OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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
25#include "Sample/RNGStream.h"
26
27#include <algorithm>
28#include <deque>
29
31{
32
33public:
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
98private:
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
133private:
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