You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.4 KiB
52 lines
1.4 KiB
#include <iostream>
|
|
#include <cmath>
|
|
|
|
#include <eigen3/Eigen/Dense>
|
|
|
|
#include "data.h"
|
|
|
|
Eigen::Matrix<float, MODEL_PATH_DISTANCE, POLYFIT_DEGREE> vander;
|
|
|
|
void poly_init() {
|
|
// Build Vandermonde matrix
|
|
for(int i = 0; i < MODEL_PATH_DISTANCE; i++) {
|
|
for(int j = 0; j < POLYFIT_DEGREE; j++) {
|
|
vander(i, j) = pow(i, POLYFIT_DEGREE-j-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void poly_fit(float *in_pts, float *in_stds, float *out) {
|
|
// References to inputs
|
|
Eigen::Map<Eigen::Matrix<float, MODEL_PATH_DISTANCE, 1> > pts(in_pts, MODEL_PATH_DISTANCE);
|
|
Eigen::Map<Eigen::Matrix<float, MODEL_PATH_DISTANCE, 1> > std(in_stds, MODEL_PATH_DISTANCE);
|
|
Eigen::Map<Eigen::Matrix<float, POLYFIT_DEGREE, 1> > p(out, POLYFIT_DEGREE);
|
|
|
|
// Build Least Squares equations
|
|
Eigen::Matrix<float, MODEL_PATH_DISTANCE, POLYFIT_DEGREE> lhs = vander.array().colwise() / std.array();
|
|
Eigen::Matrix<float, MODEL_PATH_DISTANCE, 1> rhs = pts.array() / std.array();
|
|
|
|
Eigen::Matrix<float, POLYFIT_DEGREE, 1> scale = 1. / (lhs.array()*lhs.array()).sqrt().colwise().sum();
|
|
lhs = lhs * scale.asDiagonal();
|
|
|
|
// Solve inplace
|
|
Eigen::ColPivHouseholderQR<Eigen::Ref<Eigen::MatrixXf> > qr(lhs);
|
|
p = qr.solve(rhs);
|
|
|
|
p = p.transpose() * scale.asDiagonal();
|
|
}
|
|
|
|
int main(void) {
|
|
poly_init();
|
|
|
|
|
|
float poly[4];
|
|
poly_fit(pts, stds, poly);
|
|
|
|
std::cout << "[";
|
|
std::cout << poly[0] << ",";
|
|
std::cout << poly[1] << ",";
|
|
std::cout << poly[2] << ",";
|
|
std::cout << poly[3];
|
|
std::cout << "]" << std::endl;
|
|
}
|
|
|