Sparse Grids Example 5: adaptive surrogate modeling.
Example 4 demonstrates how to build a surrogate model in a direct "one-shot" process. However, it is seldom the case that all model inputs have equal effect on the model outputs, adaptive methods can construct much more reliable surrogates with much fewer model evaluations.
#endif
cout << "\n---------------------------------------------------------------------------------------------------\n";
cout << std::scientific; cout.precision(4);
cout << "Example 5: interpolate f(x,y) = exp(-x^2) * cos(y), using leja rule\n"
<< " employ adaptive refinement to increase accuracy per samples\n";
int const num_inputs = 2;
int const num_outputs = 1;
auto model = [](double const x[], double y[], size_t)->
void{
y[0] = std::exp(-x[0] * x[0]) * std::cos(x[1]);
};
int const num_test_points = 1000;
std::vector<double> test_points(num_test_points * num_inputs);
std::minstd_rand park_miller(42);
std::uniform_real_distribution<double> domain(-1.0, 1.0);
for(auto &t : test_points) t = domain(park_miller);
std::vector<double> reference_values(num_test_points * num_outputs);
for(int i=0; i<num_test_points; i++)
model(&test_points[num_inputs * i], &reference_values[num_outputs * i], 0);
double{
std::vector<double> result;
grid.evaluateBatch(test_points, result);
double diff = 0.0;
for(int i=0; i<num_test_points; i++)
diff = std::max(diff, std::abs(result[i] - reference_values[i]));
return diff;
};
int initial_level = 4;
auto grid_iptotal = grid_isotropic;
auto grid_icurved = grid_isotropic;
auto grid_surplus = grid_isotropic;
int budget = 100;
cout << setw(22) << "isotropic" << setw(22) << "iptotal"
<< setw(22) << "ipcurved" << setw(22) << "surplus\n";
cout << setw(8) << "points" << setw(14) << "error"
<< setw(8) << "points" << setw(14) << "error"
<< setw(8) << "points" << setw(14) << "error"
<< setw(8) << "points" << setw(14) << "error\n";
do{
if (grid_isotropic.getNumLoaded() < budget){
cout << setw(8) << grid_isotropic.getNumLoaded()
<< setw(14) << test_grid(grid_isotropic);
int level = 0;
while(grid_isotropic.getNumNeeded() == 0)
}else{
cout << setw(22) << " ";
}
if (grid_iptotal.getNumLoaded() < budget){
cout << setw(8) << grid_iptotal.getNumLoaded() << setw(14) << test_grid(grid_iptotal);
}else{
cout << setw(22) << " ";
}
if (grid_icurved.getNumLoaded() < budget){
cout << setw(8) << grid_icurved.getNumLoaded() << setw(14) << test_grid(grid_icurved);
}else{
cout << setw(22) << " ";
}
if (grid_surplus.getNumLoaded() < budget){
cout << setw(8) << grid_surplus.getNumLoaded() << setw(14) << test_grid(grid_surplus);
grid_surplus.setSurplusRefinement(1.E-8, 0);
}else{
cout << setw(22) << " ";
}
cout << "\n";
}while((grid_isotropic.getNumLoaded() < budget) ||
(grid_iptotal.getNumLoaded() < budget) ||
(grid_icurved.getNumLoaded() < budget) ||
(grid_surplus.getNumLoaded() < budget));
cout << "\nNote: the surplus refinement is sensitive to the non-monotonic coefficient decay\n"
<< " and the choice of the tolerance.\n";
#ifndef __TASMANIAN_DOXYGEN_SKIP
The master-class that represents an instance of a Tasmanian sparse grid.
Definition: TasmanianSparseGrid.hpp:293
@ rule_leja
Classic sequence rule, moderate Lebesgue constant growth (empirical result only).
Definition: tsgEnumerates.hpp:299
@ type_level
Ignoring the polynomial space, use rules with index .
Definition: tsgEnumerates.hpp:209
@ type_iptotal
Total degree polynomial space for interpolation, i.e., the span of .
Definition: tsgEnumerates.hpp:221
@ type_ipcurved
Curved polynomial space for interpolation, i.e., the span of .
Definition: tsgEnumerates.hpp:228
void loadNeededValues(std::function< void(double const x[], double y[], size_t thread_id)> model, TasmanianSparseGrid &grid, size_t num_threads)
Loads the current grid with model values, does not perform any refinement.
Definition: tsgLoadNeededValues.hpp:104
TasmanianSparseGrid makeGlobalGrid(int dimensions, int outputs, int depth, TypeDepth type, TypeOneDRule rule, std::vector< int > const &anisotropic_weights=std::vector< int >(), double alpha=0.0, double beta=0.0, const char *custom_filename=nullptr, std::vector< int > const &level_limits=std::vector< int >())
Factory method, creates a new grid and calls TasmanianSparseGrid::makeGlobalGrid().
Definition: TasmanianSparseGrid.hpp:2272