https://mooseframework.inl.gov
LatinHypercubeSampler.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "LatinHypercubeSampler.h"
11 #include "Distribution.h"
13 
14 registerMooseObjectAliased("StochasticToolsApp", LatinHypercubeSampler, "LatinHypercube");
15 
18 {
20  params.addClassDescription("Latin Hypercube Sampler.");
21  params.addRequiredParam<dof_id_type>("num_rows", "The size of the square matrix to generate.");
22  params.addRequiredParam<std::vector<DistributionName>>(
23  "distributions",
24  "The distribution names to be sampled, the number of distributions provided defines the "
25  "number of columns per matrix.");
26  return params;
27 }
28 
30  : Sampler(parameters)
31 {
32  const auto & distribution_names = getParam<std::vector<DistributionName>>("distributions");
33  for (const DistributionName & name : distribution_names)
35 
36  setNumberOfRows(getParam<dof_id_type>("num_rows"));
37  setNumberOfCols(distribution_names.size());
38  // Generator 0: within-bin uniform draws. Generator 1: column shuffler seeds.
40 }
41 
42 void
44 {
45  _shufflers.clear();
46  for (const auto col : make_range(getNumberOfCols()))
47  {
48  const auto seed = getRandl(col, 0, std::numeric_limits<uint32_t>::max(), 1);
49  _shufflers.push_back(std::make_unique<MooseRandomPerturbation>(seed, getNumberOfRows()));
50  }
51 }
52 
53 Real
55 {
56  mooseAssert(_shufflers.size() > 0, "Shufflers have not been initialized.");
57 
58  // Divide [0,1] into N equal bins of width 1/N.
59  const Real bin_size = 1. / getNumberOfRows();
60 
61  // Map row_index to a shuffled bin via the column's bijective permutation.
62  // Because permute() is a bijection on [0, N), each row gets a distinct bin,
63  // which is the core LHS stratification guarantee.
64  const auto bin = _shufflers[col_index]->permute(row_index);
65 
66  // Draw a uniform random point within the selected bin.
67  const auto lower = bin * bin_size;
68  const auto upper = (bin + 1) * bin_size;
69  const Real probability =
70  getRand(row_index * getNumberOfCols() + col_index) * (upper - lower) + lower;
71 
72  // Transform the probability through the inverse CDF to obtain the sample value.
73  return _distributions[col_index]->quantile(probability);
74 }
void setNumberOfRows(dof_id_type n_rows)
LatinHypercubeSampler(const InputParameters &parameters)
static InputParameters validParams()
unsigned int getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index=0) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
const std::string & name() const
Real getRand(std::size_t n, unsigned int index=0) const
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) override
Return the sample value for the given row and column.
static InputParameters validParams()
dof_id_type getNumberOfRows() const
const Distribution & getDistributionByName(const DistributionName &name) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void setNumberOfCols(dof_id_type n_cols)
virtual void executeTearDown() override
Constructs one MooseRandomPerturbation per column, each seeded independently from generator 1...
registerMooseObjectAliased("StochasticToolsApp", LatinHypercubeSampler, "LatinHypercube")
IntRange< T > make_range(T beg, T end)
std::vector< std::unique_ptr< MooseRandomPerturbation > > _shufflers
Per-column pseudo-random permuters that enforce the LHS bin assignment.
std::vector< Distribution const * > _distributions
Distribution objects, one per column, whose quantile functions are sampled.
void addClassDescription(const std::string &doc_string)
Implements Latin Hypercube Sampling (LHS) over a set of distributions.
dof_id_type getNumberOfCols() const
uint8_t dof_id_type
void setNumberOfRandomSeeds(std::size_t number)