41 class GaussianProcess :
public MelonModel<T> {
44 std::shared_ptr<const GPData>
_data;
45 std::unique_ptr<kernel::StationaryKernel<double, T>>
_kernel;
62 void _set_kernel(std::shared_ptr<const GPData> data);
77 template <
typename RandomAccessIterator>
78 std::vector<T>
_calculate_covariance_vector(std::vector<T> input, RandomAccessIterator& internalVariables,
const bool fullSpace, std::vector<T>& constraints);
93 template <
typename RandomAccessIterator>
94 T
_calculate_prediction(std::vector<T> covarianceVector, RandomAccessIterator& internalVariables,
const bool fullSpace, std::vector<T>& constraints);
109 template <
typename RandomAccessIterator>
110 T
_calculate_variance(std::vector<T> covarianceVector, RandomAccessIterator& internalVariables,
const bool fullSpace, std::vector<T>& constraints);
265 void get_full_space_variables_variance(
unsigned int& variableNumber, std::vector<std::string>& variableNames, std::vector<std::pair<double, double>>& variableBounds);
310 _data = std::dynamic_pointer_cast<const GPData>(modelData);
311 if(_data ==
nullptr){
312 throw(
MelonException(
" Error while loading Gaussian process: Incorrect type of passed data object. The data object must be of type GPData."));
327 using namespace kernel;
330 switch(_data->matern) {
332 _kernel = std::make_unique<Matern12<double, T>>(_data->kernelData);
335 _kernel = std::make_unique<Matern32<double, T>>(_data->kernelData);
338 _kernel = std::make_unique<Matern52<double, T>>(_data->kernelData);
341 _kernel = std::make_unique<MaternInf<double, T>>(_data->kernelData);
344 throw(
MelonException(
" Encountered a fatal error while setting kernel: Unkown kernel."));
381 using std::min_element;
383 double minimum_scaled = *min_element(_data->Y.begin(), _data->Y.end());
385 double result = _parameterScaler->descale({ minimum_scaled }).front();
398 using std::max_element;
400 double maximum_scaled = *max_element(_data->Y.begin(), _data->Y.end());
402 double result = _parameterScaler->descale({maximum_scaled}).front();
416 std::vector<double> _Y;
417 for (
auto y : _data->Y) {
418 _Y.push_back(_parameterScaler->descale({ y }).front());
426 template <
typename T>
428 std::vector<T> dummyConstraints;
429 typename std::vector<T>::iterator dummyIterator;
432 throw MelonException(
" Error while calculating Gaussian process prediction: No model was loaded yet.");
435 std::vector<T> covarianceVector = _calculate_covariance_vector(input, dummyIterator,
false, dummyConstraints);
436 return _calculate_prediction(covarianceVector, dummyIterator,
false, dummyConstraints);
438 catch (
const std::exception& e) {
439 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process prediction. Terminating.", e));
442 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process prediction. Terminating."));
449 template <
typename T>
451 std::vector<T> dummyConstraints;
452 std::vector<T> dummInternalVariables;
453 typename std::vector<T>::iterator dummyIterator;
456 throw MelonException(
" Error while calculating Gaussian process variance: No model was loaded yet.");
459 std::vector<T> covarianceVector = _calculate_covariance_vector(input, dummyIterator,
false, dummyConstraints);
460 return _calculate_variance(covarianceVector, dummyIterator,
false, dummyConstraints);
462 catch (
const std::exception& e) {
463 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process variance. Terminating.", e));
466 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process variance. Terminating."));
473 template <
typename T>
477 throw MelonException(
" Error while calculating Gaussian process prediction: No model was loaded yet.");
480 auto internalVariablesIterator = internalVariables.begin();
481 std::vector<T> covarianceVector = _calculate_covariance_vector(input, internalVariablesIterator,
true, constraints);
482 return _calculate_prediction(covarianceVector, internalVariablesIterator,
true, constraints);
484 catch (
const std::exception& e) {
485 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process prediction. Terminating.", e));
488 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process prediction. Terminating."));
495 template <
typename T>
499 throw MelonException(
" Error while calculating Gaussian process variance: No model was loaded yet.");
502 auto internalVariablesIterator = internalVariables.begin();
503 std::vector<T> covarianceVector = _calculate_covariance_vector(input, internalVariablesIterator,
true, constraints);
504 return _calculate_variance(covarianceVector, internalVariablesIterator,
true, constraints);
506 catch (
const std::exception& e) {
507 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process variance. Terminating.", e));
510 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process variance. Terminating."));
517 template <
typename T>
521 throw MelonException(
" Error while calculating Gaussian process prediction and variance: No model was loaded yet.");
524 auto internalVariablesIterator = internalVariables.begin();
525 std::vector<T> covarianceVector = _calculate_covariance_vector(input, internalVariablesIterator,
true, constraints);
526 T prediction = _calculate_prediction(covarianceVector, internalVariablesIterator,
true, constraints);
527 T variance = _calculate_variance(covarianceVector, internalVariablesIterator,
true, constraints);
528 return std::make_pair(prediction, variance);
530 catch (
const std::exception& e) {
531 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process prediction and variance. Terminating.", e));
534 throw(
MelonException(
" Encountered a fatal error while calculating Gaussian process prediction and variance. Terminating."));
541 template <
typename T>
542 template <
typename RandomAccessIterator>
549 if (input.size() != _data->DX) {
550 throw MelonException(
" Error while calculating covariance vector: Incorrect input dimension. In reduced space mode evaluation the size of the variables vector must be equal to the input dimension of the gaussian process.");
557 std::vector<T> normalizedInput = _inputScaler->scale(input);
566 std::vector<T> covarianceVector(_data->nX, 0);
567 for (std::vector<int>::size_type h = 0; h != _data->nX; h++) {
568 T distance = _kernel->calculate_distance(_data->X[h], normalizedInput);
573 covarianceVector.at(h) = _kernel->evaluate_kernel(distance);
579 return covarianceVector;
585 template <
typename T>
586 template <
typename RandomAccessIterator>
590 std::vector<double> result_scaled;
591 std::vector<double> observationDeviations = _data->Y - _data->meanfunction;
592 result_scaled = _data->invK * observationDeviations;
593 T predictionDeviation =
dot_product(covarianceVector, result_scaled);
595 T result_scaled_t = predictionDeviation + _data->meanfunction;
601 T result = _predictionScaler->descale({ result_scaled_t }).front();
612 template <
typename T>
613 template <
typename RandomAccessIterator>
617 std::vector<T> ki_v = _data->invK * covarianceVector;
619 T normalizedResult = _data->K.at(0).at(0) - ki;
624 T result = normalizedResult * pow(_data->stdOfOutput, 2);
626 result = max(result, 1e-16);
637 template <
typename T>
643 unsigned int variableNumber;
644 std::vector<std::string> dummyVariableNames;
645 std::vector<std::pair<double, double>> dummyVariableBounds;
647 get_full_space_variables_prediction(variableNumber, dummyVariableNames, dummyVariableBounds);
649 return variableNumber;
655 template <
typename T>
661 const double MAX_BOUND = 10e6;
663 variableNames.clear();
664 variableBounds.clear();
666 variableNumber += _data->DX;
667 for (
size_t i = 0; i < _data->DX; i++) {
668 variableNames.push_back(
"normalized_input_" + std::to_string(i));
669 variableBounds.push_back(std::make_pair(-1, 1));
672 variableNumber += 2*_data->nX;
673 for (
size_t i = 0; i < _data->nX; i++) {
674 variableNames.push_back(
"squared_distance_" + std::to_string(i));
675 variableBounds.push_back(std::make_pair(0., MAX_BOUND));
677 variableNames.push_back(
"covariance_" + std::to_string(i));
678 variableBounds.push_back(std::make_pair(0., MAX_BOUND));
682 variableNames.push_back(
"normalized_prediction");
683 variableBounds.push_back(std::make_pair(-MAX_BOUND, MAX_BOUND));
686 variableNames.push_back(
"prediction");
687 variableBounds.push_back(std::make_pair(-MAX_BOUND, MAX_BOUND));
693 template <
typename T>
699 unsigned int variableNumber;
700 std::vector<std::string> dummyVariableNames;
701 std::vector<std::pair<double, double>> dummyVariableBounds;
703 get_full_space_variables_variance(variableNumber, dummyVariableNames, dummyVariableBounds);
705 return variableNumber;
711 template <
typename T>
717 const double MAX_BOUND = 10e6;
719 variableNames.clear();
720 variableBounds.clear();
722 variableNumber += _data->DX;
723 for (
size_t i = 0; i < _data->DX; i++) {
724 variableNames.push_back(
"normalized_input_" + std::to_string(i));
725 variableBounds.push_back(std::make_pair(-1, 1));
728 variableNumber += 2 * _data->nX;
729 for (
size_t i = 0; i < _data->nX; i++) {
730 variableNames.push_back(
"squared_distance_" + std::to_string(i));
731 variableBounds.push_back(std::make_pair(0., MAX_BOUND));
733 variableNames.push_back(
"covariance_" + std::to_string(i));
734 variableBounds.push_back(std::make_pair(0., MAX_BOUND));
738 variableNames.push_back(
"normalized_variance");
739 variableBounds.push_back(std::make_pair(0.0, MAX_BOUND));
742 variableNames.push_back(
"variance");
743 variableBounds.push_back(std::make_pair(1e-16, MAX_BOUND));
749 template <
typename T>
755 unsigned int variableNumber;
756 std::vector<std::string> dummyVariableNames;
757 std::vector<std::pair<double, double>> dummyVariableBounds;
759 get_full_space_variables_prediction_and_variance(variableNumber, dummyVariableNames, dummyVariableBounds);
761 return variableNumber;
767 template <
typename T>
772 const double MAX_BOUND = 10e6;
774 variableNames.clear();
775 variableBounds.clear();
777 variableNumber += _data->DX;
778 for (
size_t i = 0; i < _data->DX; i++) {
779 variableNames.push_back(
"normalized_input_" + std::to_string(i));
780 variableBounds.push_back(std::make_pair(-1, 1));
783 variableNumber += 2 * _data->nX;
784 for (
size_t i = 0; i < _data->nX; i++) {
785 variableNames.push_back(
"squared_distance_" + std::to_string(i));
786 variableBounds.push_back(std::make_pair(0., MAX_BOUND));
788 variableNames.push_back(
"covariance_" + std::to_string(i));
789 variableBounds.push_back(std::make_pair(0., MAX_BOUND));
793 variableNames.push_back(
"normalized_prediction");
794 variableBounds.push_back(std::make_pair(-MAX_BOUND, MAX_BOUND));
797 variableNames.push_back(
"prediction");
798 variableBounds.push_back(std::make_pair(-MAX_BOUND, MAX_BOUND));
801 variableNames.push_back(
"normalized_variance");
802 variableBounds.push_back(std::make_pair(0.0, MAX_BOUND));
805 variableNames.push_back(
"variance");
806 variableBounds.push_back(std::make_pair(1e-16, MAX_BOUND));