11 #ifndef TLX_MATH_POLYNOMIAL_REGRESSION_HEADER 12 #define TLX_MATH_POLYNOMIAL_REGRESSION_HEADER 32 template <
typename Type =
double,
bool WithStore = false>
58 for (
size_t i = 3; i < 2 *
order_ + 1; ++i)
59 X_[i] += Type(std::pow(x, i));
66 for (
size_t i = 3; i < order_ + 1; ++i)
67 Y_[i] += Type(std::pow(x, i)) *
y;
88 for (
size_t i = this->
size(); i != 0; ) {
89 result = result * x + this->operator [] (--i);
97 if (
size_ == 0 || !WithStore)
112 ss_total += (p.y - y_mean) * (p.y - y_mean);
114 ss_error += (p.y -
y) * (p.y - y);
118 return 1.0 - ss_error / ss_total;
145 std::vector<Type>
X_;
148 std::vector<Type>
Y_;
156 coefficients_.clear();
161 size_t np1 = order_ + 1, np2 = order_ + 2;
164 std::vector<Type> B(np1 * np2, 0);
166 for (
size_t i = 0; i <=
order_; ++i) {
167 for (
size_t j = 0; j <=
order_; ++j) {
168 B[i * np2 + j] = X_[i + j];
173 for (
size_t i = 0; i <=
order_; ++i) {
174 B[i * np2 + np1] = Y_[i];
178 for (
size_t i = 0; i < order_ + 1; ++i) {
179 for (
size_t k = i + 1; k < order_ + 1; ++k) {
180 if (B[i * np2 + i] < B[k * np2 + i]) {
181 for (
size_t j = 0; j <= order_ + 1; ++j) {
182 std::swap(B[i * np2 + j], B[k * np2 + j]);
189 for (
size_t i = 0; i <
order_; ++i) {
190 for (
size_t k = i + 1; k < order_ + 1; ++k) {
191 Type t = B[k * np2 + i] / B[i * np2 + i];
192 for (
size_t j = 0; j <= order_ + 1; ++j) {
193 B[k * np2 + j] -= t * B[i * np2 + j];
199 coefficients_.resize(np1);
200 for (
size_t i = order_ + 1; i != 0; ) {
202 coefficients_[i] = B[i * np2 + order_ + 1];
203 for (
size_t j = 0; j < order_ + 1; ++j) {
205 coefficients_[i] -= B[i * np2 + j] * coefficients_[j];
207 coefficients_[i] /= B[i * np2 + i];
216 #endif // !TLX_MATH_POLYNOMIAL_REGRESSION_HEADER Calculate the regression polynomial from a list of 2D points.
size_t size() const
number of points
polynomial stored as the coefficients of
const Point & point(size_t i)
return a point. Only available if WithStore is true.
Type evaluate(const Type &x)
returns value of y predicted by the polynomial for a given value of x
size_t size_
number of points added
size_t order_
polynomial order
Type evaluate(const Type &x) const
evaluate polynomial at x using Horner schema
Coefficients coefficients_
cached coefficients
std::vector< Point > points_
list of stored points if WithStore, else empty.
void swap(CountingPtr< A, D > &a1, CountingPtr< A, D > &a2) noexcept
swap enclosed object with another counting pointer (no reference counts need change) ...
const Coefficients & coefficients()
return coefficients vector
std::vector< Type > Y_
Y_ = vector to store values of sigma(x_i^order * y_i)
std::vector< Type > X_
X_ = vector that stores values of sigma(x_i^2n)
void fit_coefficients()
polynomial regression by inverting a Vandermonde matrix.
PolynomialRegression(size_t order)
start new polynomial regression calculation
Type r_square()
get r^2. Only available if WithStore is true.
PolynomialRegression & add(const Type &x, const Type &y)
add point. this invalidates cached coefficients until next evaluate()