pulsatrix
Loading...
Searching...
No Matches
gaussian_process.hpp
Go to the documentation of this file.
1
13#pragma once
14
15#include <cmath>
16#include <stdexcept>
17#include <vector>
18
20
21namespace pulsatrix {
22
32public:
41 GaussianProcessRegressor(float sigma_f, float length_scale, float noise_variance)
42 : sigma_f_(sigma_f), length_scale_(length_scale), noise_variance_(noise_variance) {
43 if (sigma_f <= 0.0f) {
44 throw std::invalid_argument("GaussianProcessRegressor: sigma_f must be positive");
45 }
46 if (length_scale <= 0.0f) {
47 throw std::invalid_argument("GaussianProcessRegressor: length_scale must be positive");
48 }
49 if (noise_variance < 0.0f) {
50 throw std::invalid_argument("GaussianProcessRegressor: noise_variance must be non-negative");
51 }
52 }
53
62 void Fit(std::vector<std::vector<float>> inputs, std::vector<float> targets) {
63 if (inputs.empty()) {
64 throw std::invalid_argument("GaussianProcessRegressor::Fit: inputs must not be empty");
65 }
66 if (inputs.size() != targets.size()) {
67 throw std::invalid_argument("GaussianProcessRegressor::Fit: inputs and targets must be the same size");
68 }
69 const size_t dim = inputs[0].size();
70 for (const auto& row : inputs) {
71 if (row.size() != dim) {
72 throw std::invalid_argument("GaussianProcessRegressor::Fit: every input row must be the same dimension");
73 }
74 }
75
76 const size_t n = inputs.size();
77 std::vector<std::vector<float>> k(n, std::vector<float>(n, 0.0f));
78 for (size_t i = 0; i < n; ++i) {
79 for (size_t j = 0; j < n; ++j) {
80 k[i][j] = Kernel(inputs[i], inputs[j]);
81 }
82 k[i][i] += noise_variance_;
83 }
84
85 alpha_ = SolveLinearSystem(k, targets);
86 training_kernel_ = std::move(k);
87 inputs_ = std::move(inputs);
88 targets_ = std::move(targets);
89 }
90
92 struct Posterior {
93 double mean;
94 double variance;
95 };
96
107 [[nodiscard]] Posterior Predict(const std::vector<float>& x) const {
108 if (inputs_.empty()) {
109 throw std::runtime_error("GaussianProcessRegressor::Predict: called before Fit");
110 }
111 if (x.size() != inputs_[0].size()) {
112 throw std::invalid_argument("GaussianProcessRegressor::Predict: x dimension must match training inputs");
113 }
114
115 const size_t n = inputs_.size();
116 std::vector<float> k_star(n);
117 for (size_t i = 0; i < n; ++i) {
118 k_star[i] = Kernel(x, inputs_[i]);
119 }
120
121 double mean = 0.0;
122 for (size_t i = 0; i < n; ++i) {
123 mean += static_cast<double>(k_star[i]) * static_cast<double>(alpha_[i]);
124 }
125
126 auto v = SolveLinearSystem(training_kernel_, k_star);
127 double explained_variance = 0.0;
128 for (size_t i = 0; i < n; ++i) {
129 explained_variance += static_cast<double>(k_star[i]) * static_cast<double>(v[i]);
130 }
131 double variance = static_cast<double>(Kernel(x, x)) - explained_variance;
132 if (variance < 0.0) {
133 variance = 0.0;
134 }
135
136 return Posterior{mean, variance};
137 }
138
139private:
140 [[nodiscard]] float Kernel(const std::vector<float>& a, const std::vector<float>& b) const {
141 float squared_distance = 0.0f;
142 for (size_t i = 0; i < a.size(); ++i) {
143 float d = a[i] - b[i];
144 squared_distance += d * d;
145 }
146 return sigma_f_ * sigma_f_ *
147 std::exp(-squared_distance / (2.0f * length_scale_ * length_scale_));
148 }
149
150 float sigma_f_;
151 float length_scale_;
152 float noise_variance_;
153 std::vector<std::vector<float>> inputs_;
154 std::vector<float> targets_;
155 std::vector<std::vector<float>> training_kernel_;
156 std::vector<float> alpha_;
157};
158
159} // namespace pulsatrix
A fitted (or queryable-before-fitting-throws) Gaussian Process regressor with a squared-exponential k...
Definition gaussian_process.hpp:31
void Fit(std::vector< std::vector< float > > inputs, std::vector< float > targets)
Fits the GP to (inputs[i], targets[i]) observation pairs – computes and solves the training kernel ma...
Definition gaussian_process.hpp:62
Posterior Predict(const std::vector< float > &x) const
Predicts the posterior mean/variance at x, given the data passed to Fit.
Definition gaussian_process.hpp:107
GaussianProcessRegressor(float sigma_f, float length_scale, float noise_variance)
Definition gaussian_process.hpp:41
Small, dense linear-system solve – shared by weighted_linear_regression.hpp (Phase 3's LIME/KernelSHA...
Definition acquisition_functions.hpp:16
std::vector< float > SolveLinearSystem(std::vector< std::vector< float > > a, std::vector< float > b)
Solves A*x = b via Gaussian elimination with partial pivoting.
Definition linear_algebra.hpp:36
A posterior prediction: mean and variance at one query point.
Definition gaussian_process.hpp:92
double variance
Definition gaussian_process.hpp:94
double mean
Definition gaussian_process.hpp:93