Commit 48cc80f3 authored by frey_m's avatar frey_m
Browse files

Sampler: Add Latin Hypercube sampling

parent ca0a434c
......@@ -13,6 +13,7 @@ add_opal_sources(${_SRCS})
set (HDRS
FromFile.h
LatinHyperCube.h
Normal.h
OpalSample.h
RNGStream.h
......
#ifndef OPAL_LATIN_HYPERCUBE_H
#define OPAL_LATIN_HYPERCUBE_H
#include "Sample/SamplingMethod.h"
#include "Sample/RNGStream.h"
#include <type_traits>
class LatinHyperCube : public SamplingMethod
{
public:
typedef typename std::uniform_real_distribution<double> dist_t;
LatinHyperCube(double lower, double upper, std::size_t n)
: bin_m(0)
, binsize_m((upper - lower) / double(n))
, dist_m(0.0, 1.0)
{
RNGInstance_m = RNGStream::getInstance();
}
LatinHyperCube(double lower, double upper, int seed, std::size_t n)
: bin_m(0)
, binsize_m((upper - lower) / double(n))
, dist_m(0.0, 1.0)
{
RNGInstance_m = RNGStream::getInstance(seed);
}
~LatinHyperCube() {
RNGStream::deleteInstance(RNGInstance_m);
}
void create(boost::shared_ptr<SampleIndividual>& ind, std::size_t i) {
/* values are created within [0, 1], thus, they need to be mapped
* the domain [lower, upper]
*/
ind->genes[i] = map2domain_m(RNGInstance_m->getNext(dist_m));
}
private:
double map2domain_m(double val) {
/* y = mx + q
*
* [0, 1] --> [a, b]
*
* y = (b - a) * x + a
*
* where a and b are the lower, respectively, upper
* bound of the current bin.
*/
double high = (bin_m + 1) * binsize_m;
double low = bin_m * binsize_m;
++bin_m;
return (high - low) * val + low;
}
private:
RNGStream *RNGInstance_m;
std::size_t bin_m;
double binsize_m;
std::size_t sampled_m;
dist_t dist_m;
};
#endif
......@@ -10,6 +10,7 @@
#include "Sample/SampleSequence.h"
#include "Sample/SampleGaussianSequence.h"
#include "Sample/FromFile.h"
#include "Sample/LatinHyperCube.h"
// Class OpalSample
......@@ -34,7 +35,7 @@ OpalSample::OpalSample():
, size_m(1)
{
itsAttr[TYPE] = Attributes::makeString
("TYPE", "UNIFORM_INT, UNIFORM, GAUSSIAN, FROMFILE");
("TYPE", "UNIFORM_INT, UNIFORM, GAUSSIAN, FROMFILE, LATIN_HYPERCUBE");
itsAttr[VARIABLE] = Attributes::makeString
("VARIABLE", "Name of design variable");
......@@ -136,6 +137,12 @@ void OpalSample::initialize(const std::string &dvarName,
std::string fname = Attributes::getString(itsAttr[FNAME]);
sampleMethod_m.reset( new FromFile(fname, dvarName, modulo) );
size_m = static_cast<FromFile*>(sampleMethod_m.get())->getSize();
} else if (type == "LATIN_HYPERCUBE") {
if (Attributes::getReal(itsAttr[SEED])) {
sampleMethod_m.reset( new LatinHyperCube(lower, upper, seed, size_m) );
} else {
sampleMethod_m.reset( new LatinHyperCube(lower, upper, size_m) );
}
} else {
throw OpalException("OpalSample::initialize()",
"Unknown sampling method: '" + type + "'.");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment