Skip to content

Instantly share code, notes, and snippets.

@deshaion
Last active March 5, 2021 11:57
Show Gist options
  • Save deshaion/eb357552154938ce1e37b5af190cf790 to your computer and use it in GitHub Desktop.
Save deshaion/eb357552154938ce1e37b5af190cf790 to your computer and use it in GitHub Desktop.
Simple Implementation of Polynomial Regression based on Eigen library
template <class T>
class Regression {
private:
Matrix b_eq;
public:
std::vector<double> predict(std::vector<T> &x) {
std::vector<double> y(x.size());
for (int i = 0; i < (int)x.size(); ++i) {
double value = 1;
for (int j = 0; j < b_eq.rows(); ++j) {
y[i] += b_eq(j, 0) * value;
value *= x[i];
}
}
return y;
}
void fit(const std::vector<T> &x_type, const std::vector<T> &y_type, int degree) {
std::vector<double> raw_data_x(x_type.begin(), x_type.end());
std::vector<double> raw_data_y(y_type.begin(), y_type.end());
size_t rows = raw_data_x.size();
const auto x = Eigen::Map<Matrix>(raw_data_x.data(), rows, 1);
const auto y = Eigen::Map<Matrix>(raw_data_y.data(), rows, 1);
Matrix poly_x = Matrix::Zero(rows, degree + 1);
// fill additional column for simpler vectorization
{
auto xv = poly_x.block(0, 0, rows, 1);
xv.setOnes();
}
// copy initial data
{
auto xv = poly_x.block(0, 1, rows, 1);
xv = x;
}
// generate additional terms
for (size_t i = 2; i <= degree; ++i) {
auto xv = poly_x.block(0, i, rows, 1);
xv = x.array().pow(static_cast<double>(i));
}
b_eq = (poly_x.transpose() * poly_x).inverse() * poly_x.transpose() * y;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment