https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PMCMCBase.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 "PMCMCBase.h"
12#include "Uniform.h"
13#include "DelimitedFileReader.h"
14
15registerMooseObject("StochasticToolsApp", PMCMCBase);
16
19{
21 params.addClassDescription("Parallel Markov chain Monte Carlo base.");
22 params.addRequiredParam<std::vector<DistributionName>>(
23 "prior_distributions", "The prior distributions of the parameters to be calibrated.");
24 params.addParam<DistributionName>(
25 "prior_variance", "The prior distribution of the variance parameter to be calibrated.");
26 params.addRequiredParam<unsigned int>(
27 "num_parallel_proposals",
28 "Number of proposals to make and corresponding subApps executed in "
29 "parallel.");
30 params.addRequiredParam<FileName>("file_name", "Name of the CSV file with configuration values.");
31 params.addParam<std::string>(
32 "file_column_name", "Name of column in CSV file to use, by default first column is used.");
33 params.addParam<unsigned int>(
34 "num_columns", "Number of columns to be used in the CSV file with the configuration values.");
35 params.addParam<std::vector<Real>>("lower_bound", "Lower bounds for making the next proposal.");
36 params.addParam<std::vector<Real>>("upper_bound", "Upper bounds for making the next proposal.");
37 params.addParam<Real>("variance_bound",
38 std::numeric_limits<Real>::max(),
39 "Upper bound for variance for making the next proposal.");
40 params.addRequiredParam<std::vector<Real>>("initial_values",
41 "The starting values of the inputs to be calibrated.");
42 params.addParam<unsigned int>(
43 "num_random_seeds",
44 100000,
45 "Initialize a certain number of random seeds. Change from the default only if you have to.");
46 return params;
47}
48
50 : Sampler(parameters),
52 _num_parallel_proposals(getParam<unsigned int>("num_parallel_proposals")),
53 _lower_bound(isParamValid("lower_bound") ? &getParam<std::vector<Real>>("lower_bound")
54 : nullptr),
55 _upper_bound(isParamValid("upper_bound") ? &getParam<std::vector<Real>>("upper_bound")
56 : nullptr),
57 _variance_bound(getParam<Real>("variance_bound")),
58 _initial_values(getParam<std::vector<Real>>("initial_values")),
59 _num_random_seeds(getParam<unsigned int>("num_random_seeds")),
60 _seed_index(0),
61 _rand_index(0)
62{
63 // Filling the `priors` vector with the user-provided distributions.
64 for (const DistributionName & name :
65 getParam<std::vector<DistributionName>>("prior_distributions"))
67
68 // Filling the `var_prior` object with the user-provided distribution for the variance.
69 if (isParamValid("prior_variance"))
70 _var_prior = &getDistributionByName(getParam<DistributionName>("prior_variance"));
71 else
72 _var_prior = nullptr;
73
74 // Read the experimental configurations from a csv file
75 MooseUtils::DelimitedFileReader reader(getParam<FileName>("file_name"));
76 reader.read();
77 _confg_values.resize(1);
78 if (isParamValid("file_column_name"))
79 _confg_values[0] = reader.getData(getParam<std::string>("file_column_name"));
80 else if (isParamValid("num_columns"))
81 {
82 _confg_values.resize(getParam<unsigned int>("num_columns"));
83 for (unsigned int i = 0; i < _confg_values.size(); ++i)
84 _confg_values[i] = reader.getData(i);
85 }
86 else
87 _confg_values[0] = reader.getData(0);
88
89 // Setting the number of sampler rows to be equal to the number of parallel proposals
91
92 // Setting the number of columns in the sampler matrix (equal to the number of distributions).
93 setNumberOfCols(_priors.size() + _confg_values.size());
94
95 // Resizing the vectors and vector of vectors
98 std::vector<Real>(_priors.size() + _confg_values.size(), 0.0));
101
104
105 // Check whether both the lower and the upper bounds are specified and of same size
106 bool bound_check1 = _lower_bound && !_upper_bound;
107 bool bound_check2 = !_lower_bound && _upper_bound;
108 if (bound_check1 || bound_check2)
109 mooseError("Both lower and upper bounds should be specified.");
110 bool size_check = _lower_bound ? ((*_lower_bound).size() != (*_upper_bound).size()) : 0;
111 if (size_check)
112 mooseError("Lower and upper bounds should be of the same size.");
113
114 // Check whether the priors, bounds, and initial values are all of the same size
115 if (_priors.size() != _initial_values.size())
116 mooseError("The priors and initial values should be of the same size.");
117}
118
119void
121{
122 for (unsigned int j = 0; j < _num_parallel_proposals; ++j)
123 for (unsigned int i = 0; i < _priors.size(); ++i)
124 _new_samples[j][i] = _priors[i]->quantile(random());
125}
126
127void
129{
131 _rand_index = 0;
132
133 // Filling the new_samples vector of vectors with new proposal samples
135
136 // Draw random numbers to facilitate decision making later on
137 for (unsigned int j = 0; j < _num_parallel_proposals; ++j)
138 _rnd_vec[j] = random();
139}
140
141Real
146
147unsigned int
148PMCMCBase::randomIndex(const unsigned int & upper_bound, const unsigned int & exclude)
149{
150 auto req_index = exclude;
151 while (req_index == exclude)
152 req_index = getRandl(_rand_index++, 0, upper_bound, _seed_index);
153 return req_index;
154}
155
156std::pair<unsigned int, unsigned int>
157PMCMCBase::randomIndexPair(const unsigned int & upper_bound, const unsigned int & exclude)
158{
159 auto req_index1 = randomIndex(upper_bound, exclude);
160 auto req_index2 = req_index1;
161 while (req_index1 == req_index2)
162 req_index2 = randomIndex(upper_bound, exclude);
163 return {req_index1, req_index2};
164}
165
166void
168{
169 unsigned int index1;
170 int index2 = -1;
171 std::vector<Real> tmp;
172 for (unsigned int i = 0; i < _num_parallel_proposals * _confg_values[0].size(); ++i)
173 {
174 index1 = i % _num_parallel_proposals;
175 if (index1 == 0)
176 ++index2;
177 tmp = _new_samples[index1];
178 for (unsigned int j = 0; j < _confg_values.size(); ++j)
179 tmp.push_back(_confg_values[j][index2]);
180 _new_samples_confg[i] = tmp;
181 }
182}
183
184const std::vector<Real> &
186{
187 return _rnd_vec;
188}
189
190const std::vector<Real> &
192{
193 return _new_var_samples;
194}
195
196const std::vector<std::vector<Real>> &
198{
199 return _new_samples;
200}
201
202const std::vector<const Distribution *>
204{
205 return _priors;
206}
207
208const Distribution *
210{
211 return _var_prior;
212}
213
214Real
215PMCMCBase::computeSample(dof_id_type row_index, dof_id_type col_index)
216{
217 if (_t_step < 1)
218 for (unsigned int i = 0; i < _num_parallel_proposals; ++i)
220
221 // Combine the proposed samples with experimental configurations
223
224 return _new_samples_confg[row_index][col_index];
225}
registerMooseObject("StochasticToolsApp", PMCMCBase)
void ErrorVector unsigned int
const Distribution & getDistributionByName(const DistributionName &name) const
void addRequiredParam(const std::string &name, const std::string &doc_string)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
void addClassDescription(const std::string &doc_string)
const std::string & name() const
void mooseError(Args &&... args) const
bool isParamValid(const std::string &name) const
const std::vector< std::vector< T > > & getData() const
A base class used to perform Parallel Markov Chain Monte Carlo (MCMC) sampling.
Definition PMCMCBase.h:20
const std::vector< Real > * _lower_bound
Lower bounds for making the next proposal.
Definition PMCMCBase.h:121
const std::vector< std::vector< Real > > & getSamples() const
Return the proposed samples to facilitate decision making in reporters.
Definition PMCMCBase.C:197
std::vector< const Distribution * > _priors
Storage for prior distribution objects to be utilized.
Definition PMCMCBase.h:115
const std::vector< Real > & getVarSamples() const
Return the proposed variance samples to facilitate decision making in reporters.
Definition PMCMCBase.C:191
void combineWithExperimentalConfig()
Generates combinations of the new samples with the experimental configurations.
Definition PMCMCBase.C:167
const std::vector< const Distribution * > getPriors() const
Return the priors to facilitate decision making in reporters.
Definition PMCMCBase.C:203
static InputParameters validParams()
Definition PMCMCBase.C:18
Real random()
Sample a random number between 0 and 1.
Definition PMCMCBase.C:142
unsigned int _seed_index
Generator index when requesting random numbers.
Definition PMCMCBase.h:151
const std::vector< Real > & _initial_values
Initial values of the input params to get the MCMC scheme started.
Definition PMCMCBase.h:130
virtual void executeSetUp() override
Definition PMCMCBase.C:128
const Distribution * getVarPrior() const
Return the prior over variance to facilitate decision making in reporters.
Definition PMCMCBase.C:209
virtual void proposeSamples()
Fill in the _new_samples vector of vectors (happens within sampleSetUp)
Definition PMCMCBase.C:120
const Distribution * _var_prior
Storage for prior distribution object of the variance to be utilized.
Definition PMCMCBase.h:118
std::pair< unsigned int, unsigned int > randomIndexPair(const unsigned int &upper_bound, const unsigned int &exclude)
Sample two random indices without repitition excluding a specified index.
Definition PMCMCBase.C:157
const unsigned int _num_random_seeds
Initialize a certain number of random seeds. Change from the default only if you have to.
Definition PMCMCBase.h:148
std::vector< std::vector< Real > > _new_samples
Vectors of new proposed samples.
Definition PMCMCBase.h:133
std::size_t _rand_index
Running index for the random number generators.
Definition PMCMCBase.h:154
const std::vector< Real > & getRandomNumbers() const
Return the random numbers to facilitate decision making in reporters.
Definition PMCMCBase.C:185
PMCMCBase(const InputParameters &parameters)
Definition PMCMCBase.C:49
std::vector< std::vector< Real > > _confg_values
Configuration values.
Definition PMCMCBase.h:157
std::vector< Real > _new_var_samples
Vector of new proposed variance samples.
Definition PMCMCBase.h:136
std::vector< Real > _rnd_vec
Vector of random numbers for decision making.
Definition PMCMCBase.h:139
virtual Real computeSample(dof_id_type row_index, dof_id_type col_index) override
Definition PMCMCBase.C:215
const unsigned int _num_parallel_proposals
Number of parallel proposals to be made and subApps to be executed.
Definition PMCMCBase.h:112
std::vector< std::vector< Real > > _new_samples_confg
Vectors of new proposed samples combined with the experimental configuration values.
Definition PMCMCBase.h:160
unsigned int randomIndex(const unsigned int &upper_bound, const unsigned int &exclude)
Sample a random index excluding a specified index.
Definition PMCMCBase.C:148
const std::vector< Real > * _upper_bound
Upper bounds for making the next proposal.
Definition PMCMCBase.h:124
void setNumberOfCols(dof_id_type n_cols)
Real getRand(std::size_t n, unsigned int index=0) const
unsigned int getRandl(std::size_t n, unsigned int lower, unsigned int upper, unsigned int index=0) const
void setAutoAdvanceGenerators(const bool state)
static InputParameters validParams()
void setNumberOfRows(dof_id_type n_rows)
void setNumberOfRandomSeeds(std::size_t number)