https://mooseframework.inl.gov
Loading...
Searching...
No Matches
PMCMCDecision.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 "PMCMCDecision.h"
11#include "Sampler.h"
12#include "DenseMatrix.h"
13
14registerMooseObject("StochasticToolsApp", PMCMCDecision);
15
18{
21 params.addClassDescription("Generic reporter which decides whether or not to accept a proposed "
22 "sample in parallel Markov chain Monte Carlo type of algorithms.");
23 params.addParam<ReporterName>("output_value", "Value of the model output from the SubApp.");
24 params.addParam<ReporterValueName>(
25 "outputs_required",
26 "outputs_required",
27 "Modified value of the model output from this reporter class.");
28 params.addParam<ReporterValueName>("inputs", "inputs", "Uncertain inputs to the model.");
29 params.addParam<ReporterValueName>("tpm", "tpm", "The transition probability matrix.");
30 params.addParam<ReporterValueName>("variance", "variance", "Model variance term.");
31 params.addParam<ReporterValueName>(
32 "noise", "noise", "Model noise term to pass to Likelihoods object.");
33 params.addRequiredParam<SamplerName>("sampler", "The sampler object.");
34 params.addRequiredParam<std::vector<UserObjectName>>("likelihoods", "Names of likelihoods.");
35 return params;
36}
37
39 : GeneralReporter(parameters),
40 LikelihoodInterface(parameters),
41 _inputs(declareValue<std::vector<std::vector<Real>>>("inputs")),
42 _tpm(declareValue<std::vector<Real>>("tpm")),
43 _variance(declareValue<std::vector<Real>>("variance")),
44 _noise(declareValue<Real>("noise")),
45 _sampler(getSampler("sampler")),
46 _pmcmc(dynamic_cast<const PMCMCBase *>(&_sampler)),
47 _rnd_vec(_pmcmc->getRandomNumbers()),
48 _new_var_samples(_pmcmc->getVarSamples()),
49 _priors(_pmcmc->getPriors()),
50 _var_prior(_pmcmc->getVarPrior()),
51 _outputs_required(
52 isParamValid("output_value")
53 ? &declareValue<std::vector<Real>>("outputs_required", REPORTER_MODE_DISTRIBUTED)
54 : nullptr),
55 _data_prev(declareRestartableData<DenseMatrix<Real>>("data_prev")),
56 _var_prev(declareRestartableData<std::vector<Real>>("var_prev")),
57 _outputs_prev(declareRestartableData<std::vector<Real>>("outputs_prev")),
58 _output_value(isParamValid("output_value") ? &getReporterValue<std::vector<Real>>(
59 "output_value", REPORTER_MODE_DISTRIBUTED)
60 : nullptr),
61 _check_step(declareRestartableData<int>("check_step", std::numeric_limits<int>::max()))
62{
63 // Filling the `likelihoods` vector with the user-provided distributions.
64 for (const UserObjectName & name : getParam<std::vector<UserObjectName>>("likelihoods"))
66
67 // Check whether the selected sampler is an MCMC sampler or not
68 if (!_pmcmc)
69 paramError("sampler", "The selected sampler is not of type MCMC.");
70
71 // Fetching the sampler characteristics
75
76 // Resizing the data arrays to transmit to the output file
77 _inputs.resize(_props);
78 for (unsigned int i = 0; i < _props; ++i)
82 _tpm.resize(_props);
83 _variance.resize(_props);
84}
85
86void
88{
89 if (!isParamValid("output_value") && !usingGP())
90 paramError("output_value", "Value of the model output from the SubApp should be specified.");
91}
92
93void
94PMCMCDecision::computeEvidence(std::vector<Real> & evidence, const DenseMatrix<Real> & input_matrix)
95{
96 std::vector<Real> out1(_num_confg_values);
97 std::vector<Real> out2(_num_confg_values);
98 for (unsigned int i = 0; i < evidence.size(); ++i)
99 {
100 evidence[i] = 0.0;
101 for (unsigned int j = 0; j < _priors.size(); ++j)
102 evidence[i] += (std::log(_priors[j]->pdf(input_matrix(i, j))) -
103 std::log(_priors[j]->pdf(_data_prev(i, j))));
104 for (unsigned int j = 0; j < _num_confg_values; ++j)
105 {
106 out1[j] = (*_outputs_required)[j * _props + i];
107 out2[j] = _outputs_prev[j * _props + i];
108 }
109 if (_var_prior)
110 {
111 evidence[i] += (std::log(_var_prior->pdf(_new_var_samples[i])) -
112 std::log(_var_prior->pdf(_var_prev[i])));
113 _noise = std::sqrt(_new_var_samples[i]);
114 for (unsigned int j = 0; j < _likelihoods.size(); ++j)
115 evidence[i] += _likelihoods[j]->function(out1);
116 _noise = std::sqrt(_var_prev[i]);
117 for (unsigned int j = 0; j < _likelihoods.size(); ++j)
118 evidence[i] -= _likelihoods[j]->function(out2);
119 }
120 else
121 for (unsigned int j = 0; j < _likelihoods.size(); ++j)
122 evidence[i] += (_likelihoods[j]->function(out1) - _likelihoods[j]->function(out2));
123 }
124}
125
126void
128 const std::vector<Real> & /*evidence*/)
129{
130 tv.assign(_props, 1.0);
131}
132
133void
134PMCMCDecision::nextSamples(std::vector<Real> & req_inputs,
135 DenseMatrix<Real> & input_matrix,
136 const std::vector<Real> & tv,
137 const unsigned int & parallel_index)
138{
139 if (tv[parallel_index] >= _rnd_vec[parallel_index])
140 {
141 for (unsigned int k = 0; k < _sampler.getNumberOfCols() - _num_confg_params; ++k)
142 req_inputs[k] = input_matrix(parallel_index, k);
143 _variance[parallel_index] = _new_var_samples[parallel_index];
144 }
145 else
146 {
147 for (unsigned int k = 0; k < _sampler.getNumberOfCols() - _num_confg_params; ++k)
148 {
149 req_inputs[k] = _data_prev(parallel_index, k);
150 input_matrix(parallel_index, k) = _data_prev(parallel_index, k);
151 }
152 if (_var_prior)
153 _variance[parallel_index] = _var_prev[parallel_index];
154 for (unsigned int k = 0; k < _num_confg_values; ++k)
155 (*_outputs_required)[k * _props + parallel_index] =
156 _outputs_prev[k * _props + parallel_index];
157 }
158}
159
160void
162{
164 {
166 return;
167 }
168
169 // Gather inputs and outputs from the sampler and subApps
170 DenseMatrix<Real> data_in = _sampler.getGlobalSamples();
171 if (!usingGP())
172 {
173 mooseAssert(_output_value->size() >= _sampler.getNumberOfLocalRows(),
174 "Incorrectly sized outputs.");
175 _outputs_required->assign(_output_value->begin(),
178 }
179
180 // Compute the evidence and transitimkon vectors
181 std::vector<Real> evidence(_props);
182 if (_t_step > _pmcmc->decisionStep())
183 {
184 computeEvidence(evidence, data_in);
185 computeTransitionVector(_tpm, evidence);
186 }
187 else
188 _tpm.assign(_props, 1.0);
189
190 // Accept/reject the proposed samples and assign the correct outputs
191 std::vector<Real> req_inputs(_sampler.getNumberOfCols() - _num_confg_params);
192 for (unsigned int i = 0; i < _props; ++i)
193 {
194 nextSamples(req_inputs, data_in, _tpm, i);
195 _inputs[i] = req_inputs;
196 }
197
198 // Compute the next seeds to facilitate proposals (not always required)
199 nextSeeds();
200
201 // Store data from previous step
202 _data_prev = data_in;
204 if (!usingGP())
205 _outputs_prev = (*_outputs_required);
206
207 // Track the current step
209}
registerMooseObject("StochasticToolsApp", PMCMCDecision)
const ReporterMode REPORTER_MODE_DISTRIBUTED
void ErrorVector unsigned int
virtual Real pdf(const Real &x) const=0
static InputParameters validParams()
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)
static InputParameters validParams()
LikelihoodFunctionBase * getLikelihoodFunctionByName(const UserObjectName &name) const
Lookup a LikelihoodFunction object by name and return pointer.
const std::string & name() const
void paramError(const std::string &param, Args... args) const
bool isParamValid(const std::string &name) const
A base class used to perform Parallel Markov Chain Monte Carlo (MCMC) sampling.
Definition PMCMCBase.h:20
dof_id_type getNumberOfConfigParams() const
Return the number of configuration parameters.
Definition PMCMCBase.h:34
virtual int decisionStep() const
Return the step after which decision making can begin.
Definition PMCMCBase.h:73
dof_id_type getNumberOfConfigValues() const
Return the number of configuration parameters.
Definition PMCMCBase.h:29
dof_id_type getNumParallelProposals() const
Return the number of parallel proposals.
Definition PMCMCBase.h:39
PMCMCDecision will help making sample accept/reject decisions in MCMC schemes (for e....
const std::vector< Real > & _rnd_vec
Storage for the random numbers for decision making.
std::vector< Real > & _tpm
Transition probability matrix.
dof_id_type _num_confg_values
Storage for the number of experimental configuration values.
std::vector< const LikelihoodFunctionBase * > _likelihoods
Storage for the likelihood objects to be utilized.
std::vector< Real > & _variance
Model variance term.
virtual void execute() override
std::vector< Real > & _var_prev
Storage for previous variances.
virtual void nextSeeds()
Compute the next set of seeds to facilitate proposals.
std::vector< std::vector< Real > > & _inputs
Model input data that is uncertain.
const std::vector< const Distribution * > _priors
Storage for the priors.
virtual void initialize() override
dof_id_type _num_confg_params
Storage for the number of experimental configuration parameters.
Sampler & _sampler
The MCMC sampler.
virtual bool usingGP() const
Flag to specify if a pre-trained Gaussian process model is used.
static InputParameters validParams()
virtual void nextSamples(std::vector< Real > &req_inputs, DenseMatrix< Real > &input_matrix, const std::vector< Real > &tv, const unsigned int &parallel_index)
Resample inputs given the transition vector (after transition vector computed)
const std::vector< Real > * _output_value
Current output values.
const PMCMCBase *const _pmcmc
MCMC sampler base.
const Distribution * _var_prior
Storage for the prior over the variance.
PMCMCDecision(const InputParameters &parameters)
Real & _noise
Model noise term to pass to Likelihoods object.
const std::vector< Real > & _new_var_samples
Storage for new proposed variance samples.
virtual void computeTransitionVector(std::vector< Real > &tv, const std::vector< Real > &evidence)
Compute the transition probability vector (after the computation of evidence)
int & _check_step
Ensure that the MCMC algorithm proceeds in a sequential fashion.
dof_id_type _props
Storage for the number of parallel proposals.
DenseMatrix< Real > & _data_prev
Storage for previous inputs.
std::vector< Real > & _outputs_prev
Storage for previous outputs.
virtual void computeEvidence(std::vector< Real > &evidence, const DenseMatrix< Real > &input_matrix)
Compute the evidence (aka, betterness of the proposed sample vs the previous)
std::vector< Real > * _outputs_required
Transfer the right outputs to the file.
dof_id_type getNumberOfLocalRows() const
dof_id_type getNumberOfRows() const
dof_id_type getNumberOfCols() const
DenseMatrix< Real > getGlobalSamples()
void allgather(const T &send_data, std::vector< T, A > &recv_data) const
const Parallel::Communicator & _communicator