https://mooseframework.inl.gov
Loading...
Searching...
No Matches
NestedMonteCarloSampler.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
11#include "Distribution.h"
12
13registerMooseObjectAliased("StochasticToolsApp", NestedMonteCarloSampler, "NestedMonteCarlo");
14
17{
19 params.addClassDescription("Monte Carlo sampler for nested loops of parameters.");
20 params.addRequiredParam<std::vector<dof_id_type>>(
21 "num_rows",
22 "The number of rows for each loop of parameters. The first number represents the outermost "
23 "loop.");
24 params.addRequiredParam<std::vector<std::vector<DistributionName>>>(
25 "distributions",
26 "Sets of distribution names to be sampled. Each set defines the parameters for the nested "
27 "loop, with the first set being the outermost loop.");
28 return params;
29}
30
32 : Sampler(parameters)
33{
34 // Grab inputs and make sure size is consistent
35 const auto & dnames = getParam<std::vector<std::vector<DistributionName>>>("distributions");
36 const auto & nrows = getParam<std::vector<dof_id_type>>("num_rows");
37 if (dnames.size() != nrows.size())
38 paramError("distributions",
39 "There must be a set of distributions for each loop defined by 'num_rows'.");
40
41 // Gather distribution pointers and fill in loop index
42 const std::size_t nloop = dnames.size();
43 std::vector<std::size_t> loop_index;
44 for (const auto & n : make_range(nloop))
45 for (const auto & name : dnames[n])
46 {
48 loop_index.push_back(n);
49 }
50
51 // Compute what row indices need to recompute which columns
52 std::vector<dof_id_type> loop_mod(nloop);
53 std::partial_sum(nrows.rbegin(), nrows.rend(), loop_mod.rbegin(), std::multiplies<dof_id_type>());
54 loop_mod.erase(loop_mod.begin());
55 loop_mod.push_back(1);
56
57 // Fill in the mod for each column
58 _col_mod.resize(_distributions.size());
59 for (const auto j : index_range(_distributions))
60 _col_mod[j] = loop_mod[loop_index[j]];
61
62 setNumberOfRows(std::accumulate(nrows.begin(), nrows.end(), 1, std::multiplies<dof_id_type>()));
64}
65
66Real
67NestedMonteCarloSampler::computeSample(dof_id_type row_index, dof_id_type col_index)
68{
69 const auto mod = _col_mod[col_index];
70 const dof_id_type target_row = std::floor(row_index / mod) * mod;
71 const Real rn = getRand(target_row * getNumberOfCols() + col_index);
72 return _distributions[col_index]->quantile(rn);
73}
registerMooseObjectAliased("StochasticToolsApp", NestedMonteCarloSampler, "NestedMonteCarlo")
const Distribution & getDistributionByName(const DistributionName &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const std::string & name() const
void paramError(const std::string &param, Args... args) const
A class used to perform nested Monte Carlo Sampling.
NestedMonteCarloSampler(const InputParameters &parameters)
std::vector< dof_id_type > _col_mod
Helper for determining the target row for the given column index: target_row = std::floor(row_index /...
static InputParameters validParams()
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) override
Return the sample for the given row and column.
std::vector< const Distribution * > _distributions
Storage for distribution objects to be utilized.
void setNumberOfCols(dof_id_type n_cols)
Real getRand(std::size_t n, unsigned int index=0) const
static InputParameters validParams()
dof_id_type getNumberOfCols() const
void setNumberOfRows(dof_id_type n_rows)