DREAM Example 2: perform parameter calibration using likelihood that is approximated with a sparse grid.
#endif
srand((int) time(nullptr));
cout << "\n" << "---------------------------------------------------------------------------------------------------\n";
cout << std::scientific; cout.precision(5);
cout << "EXAMPLE 2: set the inference problem: identify model parameters x_0 and x_1\n"
<< " from data (noise free example)\n"
<< " model: f(x) = sin(x_0*M_PI*t + x_1), data: d = sin(M_PI*t + 0.3*M_PI)\n"
<< " t in [0,1], t is discretized with 32 equidistant nodes\n"
<< " the likelihood is exp(- 16 * (f(x) - d)^2)\n"
<< " using a sparse grid to interpolate the likelihood\n"
<< " NOTE: 16 = 32/2 corresponds to the discretization error in t\n\n";
constexpr double pi = 3.14159265358979323846;
int num_dimensions = 2;
int num_chains = 100;
int num_burnup_iterations = 3000;
int num_sample_iterations = 100;
int num_discrete_nodes = 32;
auto model = [&](double x0, double x1, std::vector<double> &data)->
void{
double dt = 1.0 / ((double) data.size());
double t = 0.5 * dt;
for(auto &d : data){
d = std::sin(x0 * pi * t + x1);
t += dt;
}
};
auto likelihood = [&](double scale,
std::vector<double> &model_values,
std::vector<double> &data)->
double{
double likelihood_value = 0.0;
for(size_t j=0; j<model_values.size(); j++){
likelihood_value += (model_values[j] - data[j]) * (model_values[j] - data[j]);
}
return - 0.5 * scale * likelihood_value;
};
std::vector<double> data(num_discrete_nodes);
model(1.0, 0.3 * pi, data);
std::vector<double> domain_a = {0.5, -0.1}, domain_b = {8.0, 1.7};
grid.setDomainTransform(domain_a, domain_b);
[&](std::vector<double> const &x, std::vector<double> &y, size_t)->void{
std::vector<double> model_at_point(num_discrete_nodes);
model(x[0], x[1], model_at_point);
y[0] = likelihood((double) num_discrete_nodes, model_at_point, data);
},
grid, 1);
state.setState(init_chains);
(num_burnup_iterations, num_sample_iterations,
grid.getDomainInside(),
state,
);
std::vector<double> expectation, variance;
state.getHistoryMeanVariance(expectation, variance);
cout << "Inferred values (using 10th order polynomial sparse grid):\n";
cout << " frequency:" << setw(12) << std::fixed << expectation[0]
<< " error:" << setw(12) << std::scientific << std::abs(expectation[0] - 1.0) << "\n";
cout << " correction:" << setw(12) << std::fixed << expectation[1]
<< " error:" << setw(12) << std::scientific << std::abs(expectation[1] - 0.3 * pi)
<< "\n\n";
grid.setDomainTransform(domain_a, domain_b);
[&](std::vector<double> const &x, std::vector<double> &y, size_t)->
void{
std::vector<double> model_at_point(num_discrete_nodes);
model(x[0], x[1], model_at_point);
y[0] = likelihood((double) num_discrete_nodes, model_at_point, data);
},
grid, 1);
state.clearPDFvalues();
state.setState(init_chains);
(num_burnup_iterations, num_sample_iterations,
grid.getDomainInside(),
state,
);
state.getHistoryMeanVariance(expectation, variance);
cout << "Inferred values (using 30th order polynomial sparse grid):\n";
cout << " frequency:" << setw(12) << std::fixed << expectation[0]
<< " error:" << setw(12) << std::scientific << std::abs(expectation[0] - 1.0) << "\n";
cout << " correction:" << setw(12) << std::fixed << expectation[1]
<< " error:" << setw(12) << std::scientific << std::abs(expectation[1] - 0.3 * pi)
<< "\n\n";
cout << "\n" << "---------------------------------------------------------------------------------------------------\n";
#ifndef __TASMANIAN_DOXYGEN_SKIP