OPAL (Object Oriented Parallel Accelerator Library)  2024.1
OPAL
OpalSample.cpp
Go to the documentation of this file.
1 //
2 // Class OpalSample
3 // The SAMPLING definition.
4 // A SAMPLING definition is used to run the optimizer in sample mode.
5 //
6 // Copyright (c) 2018, Matthias Frey, Paul Scherrer Institut, Villigen PSI, Switzerland
7 // All rights reserved
8 //
9 // Implemented as part of the PhD thesis
10 // "Precise Simulations of Multibunches in High Intensity Cyclotrons"
11 //
12 // This file is part of OPAL.
13 //
14 // OPAL is free software: you can redistribute it and/or modify
15 // it under the terms of the GNU General Public License as published by
16 // the Free Software Foundation, either version 3 of the License, or
17 // (at your option) any later version.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with OPAL. If not, see <https://www.gnu.org/licenses/>.
21 //
22 #include "Sample/OpalSample.h"
23 
25 #include "Attributes/Attributes.h"
26 #include "Sample/FromFile.h"
27 #include "Sample/LatinHyperCube.h"
28 #include "Sample/Normal.h"
31 #include "Sample/SampleSequence.h"
32 #include "Sample/Uniform.h"
34 #include "Utilities/Util.h"
35 
36 #include <unordered_map>
37 
38 // The attributes of class OpalSample.
39 namespace {
40  enum {
41  TYPE, // The type of sampling
42  VARIABLE, // name of design variable
43  SEED, // for random sample methods
44  FNAME, // file to read from sampling points
45  N,
46  RANDOM,
47  STEP,
48  SIZE
49  };
50 }
51 
53  Definition(SIZE, "SAMPLING",
54  "The \"SAMPLING\" statement defines methods used for the optimizer in sample mode.")
55  , size_m(1)
56 {
58  ("TYPE", "Distribution type.",
59  {"UNIFORM_INT",
60  "UNIFORM",
61  "GAUSSIAN",
62  "FROMFILE",
63  "LATIN_HYPERCUBE",
64  "RANDOM_SEQUENCE_UNIFORM_INT",
65  "RANDOM_SEQUENCE_UNIFORM"});
66 
68  ("VARIABLE", "Name of design variable");
69 
70  itsAttr[SEED] = Attributes::makeReal
71  ("SEED", "seed for random sampling");
72 
73  itsAttr[FNAME] = Attributes::makeString
74  ("FNAME", "File to read from the sampling points");
75 
76  itsAttr[N] = Attributes::makeReal
77  ("N", "Number of sampling points", 1);
78 
79  itsAttr[RANDOM] = Attributes::makeBool
80  ("RANDOM", "Whether sequence should be sampled randomly (default: false)", false);
81 
82  itsAttr[STEP] = Attributes::makeReal
83  ("STEP", "Increment for randomized sequences (default: 1)", 1.0);
84 
86 }
87 
88 
89 OpalSample::OpalSample(const std::string& name, OpalSample* parent):
90  Definition(name, parent)
91 {}
92 
93 
94 OpalSample* OpalSample::clone(const std::string& name) {
95  return new OpalSample(name, this);
96 }
97 
98 
100 
101 }
102 
103 
104 OpalSample* OpalSample::find(const std::string& name) {
105  OpalSample* sampling = dynamic_cast<OpalSample*>(OpalData::getInstance()->find(name));
106 
107  if (sampling == nullptr) {
108  throw OpalException("OpalSample::find()",
109  "OpalSample \"" + name + "\" not found.");
110  }
111  return sampling;
112 }
113 
114 
115 void OpalSample::initialize(const std::string& dvarName,
116  double lower, double upper,
117  size_t modulo, bool /*sequence*/) {
118 
119  if ( lower >= upper ) {
120  throw OpalException("OpalSample::initialize()",
121  "Lower bound >= upper bound.");
122  }
123 
124  static const std::unordered_map<std::string, OpalSampleMethod> stringOpalSampleMethod_s = {
125  {"UNIFORM_INT", OpalSampleMethod::UNIFORM_INT},
126  {"UNIFORM", OpalSampleMethod::UNIFORM},
127  {"GAUSSIAN", OpalSampleMethod::GAUSSIAN},
128  {"FROMFILE", OpalSampleMethod::FROMFILE},
129  {"LATIN_HYPERCUBE", OpalSampleMethod::LATIN_HYPERCUBE},
130  {"RANDOM_SEQUENCE_UNIFORM_INT", OpalSampleMethod::RANDOM_SEQUENCE_UNIFORM_INT},
131  {"RANDOM_SEQUENCE_UNIFORM", OpalSampleMethod::RANDOM_SEQUENCE_UNIFORM}
132  };
133  std::string type = Attributes::getString(itsAttr[TYPE]);
134  if (type.empty()) {
135  throw OpalException("OpalSample::initialize",
136  "The attribute \"TYPE\" isn't set for the \"SAMPLING\" statement");
137  }
138  OpalSampleMethod method = stringOpalSampleMethod_s.at(type);
139 
140  int seed = Attributes::getReal(itsAttr[SEED]);
142  double step = Attributes::getReal(itsAttr[STEP]);
143  bool random = Attributes::getBool(itsAttr[RANDOM]);
144 
145  if (!random) {
146  if (method == OpalSampleMethod::UNIFORM_INT) {
147  sampleMethod_m.reset( new SampleSequence<int>(lower, upper, modulo, size_m) );
148  } else if (method == OpalSampleMethod::UNIFORM) {
149  sampleMethod_m.reset( new SampleSequence<double>(lower, upper, modulo, size_m) );
150  } else if (method == OpalSampleMethod::GAUSSIAN) {
151  sampleMethod_m.reset( new SampleGaussianSequence(lower, upper, modulo, size_m) );
152  } else if (method == OpalSampleMethod::FROMFILE) {
153  std::string fname = Attributes::getString(itsAttr[FNAME]);
154  sampleMethod_m.reset( new FromFile(fname, dvarName, modulo) );
155  } else {
156  throw OpalException("OpalSample::initialize",
157  "The sampling method \"TYPE=" + type + "\" is not supported out of random sampling mode");
158  }
159  } else {
160  switch (method) {
162  if (Attributes::getReal(itsAttr[SEED])) {
163  sampleMethod_m.reset( new Uniform<int>(lower, upper, seed) );
164  } else {
165  sampleMethod_m.reset( new Uniform<int>(lower, upper) );
166  }
167  break;
168  }
170  if (Attributes::getReal(itsAttr[SEED])) {
171  sampleMethod_m.reset( new Uniform<double>(lower, upper, seed) );
172  } else {
173  sampleMethod_m.reset( new Uniform<double>(lower, upper) );
174  }
175  break;
176  }
178  if (Attributes::getReal(itsAttr[SEED])) {
179  sampleMethod_m.reset( new Normal(lower, upper, seed) );
180  } else {
181  sampleMethod_m.reset( new Normal(lower, upper) );
182  }
183  break;
184  }
186  std::string fname = Attributes::getString(itsAttr[FNAME]);
187  sampleMethod_m.reset( new FromFile(fname, dvarName, modulo) );
188  size_m = static_cast<FromFile*>(sampleMethod_m.get())->getSize();
189  break;
190  }
192  if (Attributes::getReal(itsAttr[SEED])) {
193  sampleMethod_m.reset( new LatinHyperCube(lower, upper, seed) );
194  } else {
195  sampleMethod_m.reset( new LatinHyperCube(lower, upper) );
196  }
197  break;
198  }
200  if (Attributes::getReal(itsAttr[SEED])) {
201  sampleMethod_m.reset(
202  new SampleRandomizedSequence<int>(lower, upper, step, seed)
203  );
204  } else {
205  sampleMethod_m.reset(
206  new SampleRandomizedSequence<int>(lower, upper, step)
207  );
208  }
209  break;
210  }
212  if (Attributes::getReal(itsAttr[SEED])) {
213  sampleMethod_m.reset(
214  new SampleRandomizedSequence<double>(lower, upper, step, seed)
215  );
216  } else {
217  sampleMethod_m.reset(
218  new SampleRandomizedSequence<double>(lower, upper, step)
219  );
220  }
221  break;
222  }
223  default: {
224  throw OpalException("OpalSample::initialize",
225  "Invalid \"TYPE\" for the \"SAMPLING\" statement");
226  }
227  }
228  }
229 }
230 
231 
232 std::string OpalSample::getVariable() const {
234 }
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:240
static OpalData * getInstance()
Definition: OpalData.cpp:196
unsigned int getSize() const
Definition: OpalSample.h:82
int seed
The current random seed.
Definition: Options.cpp:37
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:343
virtual OpalSample * clone(const std::string &name)
Make clone.
Definition: OpalSample.cpp:94
Definition: Normal.h:26
std::shared_ptr< SamplingMethod > sampleMethod_m
Definition: OpalSample.h:58
std::string getVariable() const
Definition: OpalSample.cpp:232
bool getBool(const Attribute &attr)
Return logical value.
Definition: Attributes.cpp:100
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
Definition: Attributes.cpp:90
double FromFile(std::string file, const std::vector< double > &referencePoint)
void initialize(const std::string &dvarName, double lower, double upper, size_t modulo=1, bool sequence=false)
Definition: OpalSample.cpp:115
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:191
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Definition: Attributes.cpp:409
d1 VARIABLE
Definition: Problem.in:1
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:332
static OpalSample * find(const std::string &name)
Find sampling method.
Definition: OpalSample.cpp:104
std::vector< Attribute > itsAttr
The object attributes.
Definition: Object.h:216
const std::string name
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:252
unsigned int size_m
Definition: OpalSample.h:78
OpalSample()
Exemplar constructor.
Definition: OpalSample.cpp:52
The base class for all OPAL definitions.
Definition: Definition.h:30
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:571
virtual void execute()
Check the OpalSample data.
Definition: OpalSample.cpp:99
SDDS1 &description type
Definition: test.stat:4