philsupertramp/game-math
Loading...
Searching...
No Matches
SupportValues.h
Go to the documentation of this file.
1
12#pragma once
13
14#include "../../Matrix.h"
15#include "../lin_alg/gaussSeidel.h"
16
17
25{
26public:
32 PolynomialBase([[maybe_unused]] const Matrix<double>& X, [[maybe_unused]] const Matrix<double>& Y) { }
33
39 virtual Matrix<double> Evaluate(const Matrix<double>&) const = 0;
40
48 virtual std::string Function() const = 0;
49
56 friend std::ostream& operator<<(std::ostream& ostr, const PolynomialBase& base) {
57 ostr << base.Function() << std::flush;
58 return ostr;
59 }
60};
61
69{
70public:
73
80 : PolynomialBase(X, Y) {
81 auto x = X;
82 // ensure required orientation
83 if(x.columns() > x.rows()) { x = x.Transpose(); }
84 Matrix<double> out(0, x.rows(), x.rows());
85 for(size_t i = 0; i < out.rows(); ++i) {
86 for(size_t j = 0; j < out.rows(); ++j) { out(i, j) = pow(x(i, 0), j); }
87 }
93 if(out.Determinant() == 0.0) {
94 std::cerr << "Error computing Vandermonde-Matrix! Most likely passed equal support values" << std::endl;
95 return;
96 }
97 A = gaussSeidel(out, Y);
98 }
104 virtual Matrix<double> Evaluate(const Matrix<double>& X) const {
105 Matrix<double> Y(A(0, 0), X.rows(), 1);
106 for(size_t i = 0; i < A.rows(); ++i) {
107 Y += A(i, 0) * X.Apply([i](const double& in) { return pow(in, i); });
108 }
109 return Y;
110 };
115 virtual std::string Function() const {
116 std::string out;
117 for(size_t row = 0; row < A.rows(); ++row) {
118 if(row != 0) { out += " + "; }
119 out += format("%d", int(A(row, 0)));
120 if(row > 0) { out += format("x^%d", row); }
121 }
122 return out;
123 }
124};
125
133{
138
139public:
146 : PolynomialBase(X, Y)
147 , x(X)
148 , y(Y) { }
149
158 [[nodiscard]] double GetCoefficient(const double& xk, const size_t i) const {
159 double out = 1.0;
160 for(size_t j = 0; j < x.rows(); ++j) {
161 if(i == j) continue;
162
163 out *= (xk - x(j, 0)) / (x(i, 0) - x(j, 0));
164 }
165 return out;
166 }
167
173 virtual Matrix<double> Evaluate(const Matrix<double>& in) const {
174 Matrix<double> out(0, in.rows(), 1);
175 for(size_t k = 0; k < in.rows(); ++k) {
176 for(size_t i = 0; i < y.rows(); ++i) { out(k, 0) += y(i, 0) * GetCoefficient(in(k, 0), i); }
177 }
178 return out;
179 }
185 [[nodiscard]] std::string buildLx(size_t i) const {
186 std::string Lx;
187
188 bool needsOperator = false;
189 for(size_t j = 0; j < x.rows(); ++j) {
190 if(i == j) {
191 needsOperator = false;
192 continue;
193 }
194
195 // we need to exit, if one element of the product is 0
196 if(x(i, 0) - x(j, 0) == 0) return "";
197
198 if(needsOperator) { Lx += " * "; }
199 if(x(i, 0) - x(j, 0) < 0) { Lx += "-"; }
200
201 // Dividend
202 if(x(j, 0) != 0) {
203 if(x(j, 0) < 0) {
204 Lx += format("(x + %.3f)", std::abs(x(j, 0)));
205 } else {
206 Lx += format("(x - %.3f)", x(j, 0));
207 }
208 } else {
209 Lx += "x";
210 }
211
212 // Divisor
213 Lx += format("/%.3f", std::abs(x(i, 0) - x(j, 0)));
214 needsOperator = true;
215 }
216 return Lx;
217 }
222 virtual std::string Function() const {
223 std::string out;
224 for(size_t i = 0; i < y.rows(); ++i) {
225 if(y(i, 0) == 0) continue;
226
227 if(i > 0) { out += " + "; }
228 out += format("%d * (", int(y(i, 0)));
229 out += buildLx(i);
230 out += ")";
231 }
232 return out;
233 }
234};
235
259{
262
263public:
266
273 : PolynomialBase(x, y)
274 , X(x) {
275 auto m = x.rows();
276 Matrix<double> F(0, m, m);
277 F.SetColumn(0, y);
278 for(size_t j = 1; j < m; ++j) {
279 for(size_t i = j; i < m; ++i) { F(i, j) = (F(i, j - 1) - F(i - 1, j - 1)) / (x(i, 0) - x(i - j, 0)); }
280 }
281 b = diag_elements(F);
282 }
287 virtual std::string Function() const {
288 std::string out;
289 for(size_t i = 0; i < b.rows(); ++i) {
290 if(i > 0) { out += " + "; }
291 out += format("%.3f", b(i, 0));
292 if(i > 0) {
293 for(size_t j = 0; j < i; ++j) {
294 if(X(j, 0) != 0) {
295 if(X(j, 0) > 0) out += format("* (x - %.3f)", X(j, 0));
296 else
297 out += format("* (x + %.3f)", std::abs(X(j, 0)));
298 } else
299 out += "* x";
300 }
301 }
302 }
303 return out;
304 }
305
312 double GetCoefficient(size_t index, const double& x) const {
313 double out = 1;
314 for(size_t i = 0; i < index - 1; ++i) { out *= (x - X(i, 0)); }
315 return out;
316 }
322 virtual Matrix<double> Evaluate(const Matrix<double>& xIn) const {
323 Matrix<double> y(b(b.rows() - 1, 0), xIn.rows(), 1);
324 for(int j = b.rows() - 2; j >= 0; --j) {
325 auto bAct = b(j, 0);
326 auto xAct = X(j, 0);
327 y = xIn
328 .Apply([xAct](const double& in) { return in - xAct; }) // (xIn - X[j])
329 .HadamardMulti(y) // (xIn - X[j]) * y
330 .Apply([bAct](const double& in) { return bAct + in; }); // y = b[j] + (xIn - X[j]) * y
331 }
332 return y;
333 }
334};
double pow(double x, int exponent)
Definition: SupportValues.h:133
double GetCoefficient(const double &xk, const size_t i) const
Definition: SupportValues.h:158
virtual std::string Function() const
Definition: SupportValues.h:222
Matrix< double > x
$$x_i$$ Support values
Definition: SupportValues.h:135
Matrix< double > y
$$y_i$$ Support values evaluated with the function
Definition: SupportValues.h:137
std::string buildLx(size_t i) const
Definition: SupportValues.h:185
virtual Matrix< double > Evaluate(const Matrix< double > &in) const
Definition: SupportValues.h:173
LagrangeBase(const Matrix< double > &X, const Matrix< double > &Y)
Definition: SupportValues.h:145
Definition: Matrix.h:42
constexpr Matrix< T > Transpose() const
Definition: Matrix.h:256
size_t rows() const
Definition: Matrix.h:193
T Determinant() const
Definition: Matrix.h:216
Matrix< T > Apply(const std::function< T(T)> &fun) const
Definition: Matrix.h:375
void SetColumn(size_t index, const Matrix< T > &other)
Definition: Matrix.h:524
Definition: SupportValues.h:69
MonomBase(const Matrix< double > &X, const Matrix< double > &Y)
Definition: SupportValues.h:79
virtual std::string Function() const
Definition: SupportValues.h:115
Matrix< double > A
Coefficient matrix.
Definition: SupportValues.h:72
virtual Matrix< double > Evaluate(const Matrix< double > &X) const
Definition: SupportValues.h:104
Definition: SupportValues.h:259
Matrix< double > X
support values $$x_i$$
Definition: SupportValues.h:261
double GetCoefficient(size_t index, const double &x) const
Definition: SupportValues.h:312
NewtonBase(const Matrix< double > &x, const Matrix< double > &y)
Definition: SupportValues.h:272
Matrix< double > b
newton base coefficients $$b_i$$
Definition: SupportValues.h:265
virtual Matrix< double > Evaluate(const Matrix< double > &xIn) const
Definition: SupportValues.h:322
virtual std::string Function() const
Definition: SupportValues.h:287
Definition: SupportValues.h:25
friend std::ostream & operator<<(std::ostream &ostr, const PolynomialBase &base)
Definition: SupportValues.h:56
PolynomialBase(const Matrix< double > &X, const Matrix< double > &Y)
Definition: SupportValues.h:32
virtual Matrix< double > Evaluate(const Matrix< double > &) const =0
virtual std::string Function() const =0
std::string format(const char *fmt,...)
Definition: format.h:22
Matrix< double > gaussSeidel(const Matrix< double > &A, const Matrix< double > &b)
Definition: gaussSeidel.h:29
Matrix< T > diag_elements(const Matrix< T > &in)
Definition: matrix_utils.h:451
Matrix< T > HadamardMulti(const Matrix< T > &lhs, const Matrix< T > &rhs)
Definition: matrix_utils.h:17