Galaxis Codebase  1.0.0
Team Galaxis software stack for the Carolo Cup 2023 - ROS2 based software
PolyFit< T > Class Template Reference

#include <polyfit.h>

Collaboration diagram for PolyFit< T >:

Classes

struct  Options
 

Public Types

enum  SolverType { EIGEN_COL_PIV_HOUSEHOLDER, EIGEN_FULL_PIV_HOUSEHOLDER, EIGEN_JACOBI_SVD }
 

Public Member Functions

int getDegree () const
 
SolverType getSolverType () const
 
const VecType getCoefficients () const
 
 PolyFit (std::vector< T > &x, std::vector< T > &y, Options &options)
 
std::vector< T > evalPoly (const std::vector< T > &at)
 
void setSamplePoints (std::vector< T > &v)
 
void setSignalPoints (std::vector< T > &v)
 
T solveLS (void)
 
T getMSE (void)
 
void randsample (int N, int s, std::set< int > &ind)
 
void solveRLS (void)
 

Private Types

typedef boost::uniform_int< int > DistributionType
 
typedef Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > MatType
 
typedef Eigen::Matrix< T, Eigen::Dynamic, 1 > VecType
 

Private Member Functions

void dataToEigenSubset (std::set< int > &indexSet)
 
int getInliers (std::vector< int > &inliers)
 
void dataToEigen (void)
 
void buildV (void)
 

Private Attributes

boost::mt19937 gen
 
VecType pCoef
 
std::vector< T > & x
 
std::vector< T > & y
 
VecType xM
 
VecType yM
 
MatType V
 
Options & options
 

Detailed Description

template<typename T>
class PolyFit< T >

Definition at line 38 of file polyfit.h.

Member Typedef Documentation

◆ DistributionType

template<typename T >
typedef boost::uniform_int<int> PolyFit< T >::DistributionType
private

Definition at line 69 of file polyfit.h.

◆ MatType

template<typename T >
typedef Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> PolyFit< T >::MatType
private

Definition at line 73 of file polyfit.h.

◆ VecType

template<typename T >
typedef Eigen::Matrix<T, Eigen::Dynamic, 1> PolyFit< T >::VecType
private

Definition at line 76 of file polyfit.h.

Member Enumeration Documentation

◆ SolverType

template<typename T >
enum PolyFit::SolverType
Enumerator
EIGEN_COL_PIV_HOUSEHOLDER 
EIGEN_FULL_PIV_HOUSEHOLDER 
EIGEN_JACOBI_SVD 

Definition at line 40 of file polyfit.h.

Constructor & Destructor Documentation

◆ PolyFit()

template<typename T >
PolyFit< T >::PolyFit ( std::vector< T > &  x,
std::vector< T > &  y,
Options &  options 
)
inline

Definition at line 109 of file polyfit.h.

109  :
110  x(x), y(y), options(options) {
111  if(!x.size() || !y.size() || (x.size() != y.size())) {
112  throw std::exception();
113  }
114 
115  if(options.polyDeg < 1) {
116  throw std::exception();
117  }
118  dataToEigen();
119  }

References PolyFit< T >::dataToEigen(), PolyFit< T >::options, PolyFit< T >::Options::polyDeg, PolyFit< T >::x, and PolyFit< T >::y.

Here is the call graph for this function:

Member Function Documentation

◆ buildV()

template<typename T >
void PolyFit< T >::buildV ( void  )
inlineprivate

Definition at line 321 of file polyfit.h.

321  {
322  V.resize(xM.rows(), options.polyDeg + 1);
323 
324  for(int i = 0; i < xM.rows(); ++i)
325  V(i, options.polyDeg) = 1;
326 
327  for(int d = 0; d < options.polyDeg; ++d)
328  for(int i = 0; i < xM.rows(); ++i)
329  V(i, d) = pow(xM(i, 0), options.polyDeg - d);
330  }

References PolyFit< T >::options, PolyFit< T >::Options::polyDeg, PolyFit< T >::V, and PolyFit< T >::xM.

Referenced by PolyFit< T >::getInliers(), PolyFit< T >::solveLS(), and PolyFit< T >::solveRLS().

Here is the caller graph for this function:

◆ dataToEigen()

template<typename T >
void PolyFit< T >::dataToEigen ( void  )
inlineprivate

Definition at line 309 of file polyfit.h.

309  {
310  xM.resize(static_cast<int>(x.size()), 1);
311  yM.resize(static_cast<int>(y.size()), 1);
312 
313  for(int i = 0; i < static_cast<int>(x.size()); ++i)
314  xM(i, 0) = x[i];
315 
316  for(int i = 0; i < static_cast<int>(y.size()); ++i)
317  yM(i, 0) = y[i];
318  }

References PolyFit< T >::x, PolyFit< T >::xM, PolyFit< T >::y, and PolyFit< T >::yM.

Referenced by PolyFit< T >::getInliers(), PolyFit< T >::PolyFit(), PolyFit< T >::setSamplePoints(), and PolyFit< T >::setSignalPoints().

Here is the caller graph for this function:

◆ dataToEigenSubset()

template<typename T >
void PolyFit< T >::dataToEigenSubset ( std::set< int > &  indexSet)
inlineprivate

Definition at line 278 of file polyfit.h.

278  {
279  int nVal = static_cast<int>(indexSet.size());
280  xM.resize(nVal, 1);
281  yM.resize(nVal, 1);
282 
283  int cnt = 0;
284  std::set<int>::iterator it = indexSet.begin();
285  while(it != indexSet.end()) {
286  xM(cnt, 0) = x[*it];
287  yM(cnt, 0) = y[*it];
288  ++cnt;
289  ++it;
290  }
291  }

References PolyFit< T >::x, PolyFit< T >::xM, PolyFit< T >::y, and PolyFit< T >::yM.

Referenced by PolyFit< T >::solveRLS().

Here is the caller graph for this function:

◆ evalPoly()

template<typename T >
std::vector<T> PolyFit< T >::evalPoly ( const std::vector< T > &  at)
inline

Definition at line 122 of file polyfit.h.

122  {
123  VecType x;
124  VecType y;
125 
126  x.resize(at.size());
127  y.resize(at.size());
128 
129  for(int i = 0; i < at.size(); ++i)
130  x(i, 0) = at[i];
131 
132  // Horner method
133  if(pCoef.rows() > 0)
134  y.setConstant(pCoef(0, 0));
135 
136  int nc = pCoef.rows();
137  for(int i = 1; i < nc; ++i)
138  y = (x.cwiseProduct(y)).array() + pCoef(i, 0);
139 
140  // Copy data over to output vector
141  std::vector<T> out(y.rows());
142  for(int i = 0; i < y.rows(); ++i)
143  out[i] = y(i, 0);
144 
145  return out;
146  }

References PolyFit< T >::pCoef, PolyFit< T >::x, and PolyFit< T >::y.

◆ getCoefficients()

template<typename T >
const VecType PolyFit< T >::getCoefficients ( ) const
inline

Definition at line 104 of file polyfit.h.

104  {
105  return pCoef;
106  }

References PolyFit< T >::pCoef.

Referenced by operator<<().

Here is the caller graph for this function:

◆ getDegree()

template<typename T >
int PolyFit< T >::getDegree ( ) const
inline

Definition at line 96 of file polyfit.h.

96  {
97  return options.polyDeg;
98  }

References PolyFit< T >::options, and PolyFit< T >::Options::polyDeg.

Referenced by operator<<().

Here is the caller graph for this function:

◆ getInliers()

template<typename T >
int PolyFit< T >::getInliers ( std::vector< int > &  inliers)
inlineprivate

Definition at line 295 of file polyfit.h.

295  {
296  // Full data to Eigen
297  dataToEigen();
298  buildV();
299 
300  Eigen::VectorXd diff = ((V * pCoef).array() - yM.col(0).array());
301  for(int i = 0; i < diff.rows(); ++i) {
302  if(pow(diff(i), 2) < options.tolerance)
303  inliers.push_back(i);
304  }
305  return static_cast<int>(inliers.size());
306  }

References PolyFit< T >::buildV(), PolyFit< T >::dataToEigen(), PolyFit< T >::options, PolyFit< T >::pCoef, PolyFit< T >::Options::tolerance, PolyFit< T >::V, and PolyFit< T >::yM.

Referenced by PolyFit< T >::solveRLS().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMSE()

template<typename T >
T PolyFit< T >::getMSE ( void  )
inline

Definition at line 199 of file polyfit.h.

199  {
200  if(V.cols() != pCoef.rows() && yM.rows() != V.rows()) {
201  throw std::logic_error("Assert Polyfit l220");
202  }
203 
204  T mse = 0.0;
205  Eigen::VectorXd diff = ((V * pCoef).array() - yM.col(0).array());
206  for(int i = 0; i < diff.rows(); ++i)
207  mse += pow(diff(i), 2);
208  return mse;
209  }

References PolyFit< T >::pCoef, PolyFit< T >::V, and PolyFit< T >::yM.

Referenced by PolyFit< T >::solveLS().

Here is the caller graph for this function:

◆ getSolverType()

template<typename T >
SolverType PolyFit< T >::getSolverType ( ) const
inline

Definition at line 100 of file polyfit.h.

100  {
101  return options.solver;
102  }

References PolyFit< T >::options, and PolyFit< T >::Options::solver.

Referenced by operator<<().

Here is the caller graph for this function:

◆ randsample()

template<typename T >
void PolyFit< T >::randsample ( int  N,
int  s,
std::set< int > &  ind 
)
inline

Definition at line 212 of file polyfit.h.

212  {
213  if(N < 0 && s < 0 && (N <= s)) {
214  throw std::logic_error("Assert Polyfit l230");
215  }
216 
217  DistributionType dist(1, N);
218  while(static_cast<int>(ind.size()) < s) {
219  ind.insert(dist(gen));
220  }
221  }

References PolyFit< T >::gen.

Referenced by PolyFit< T >::solveRLS().

Here is the caller graph for this function:

◆ setSamplePoints()

template<typename T >
void PolyFit< T >::setSamplePoints ( std::vector< T > &  v)
inline

Definition at line 149 of file polyfit.h.

149  {
150  if(!v.size()) {
151  throw std::exception();
152  }
153 
154  if(x.size()) {
155  }
156  x = v;
157  dataToEigen();
158  }

References PolyFit< T >::dataToEigen(), and PolyFit< T >::x.

Here is the call graph for this function:

◆ setSignalPoints()

template<typename T >
void PolyFit< T >::setSignalPoints ( std::vector< T > &  v)
inline

Definition at line 161 of file polyfit.h.

161  {
162  if(!v.size()) {
163  throw std::exception();
164  }
165 
166  if(y.size()) {
167  }
168  y = v;
169  dataToEigen();
170  }

References PolyFit< T >::dataToEigen(), and PolyFit< T >::y.

Here is the call graph for this function:

◆ solveLS()

template<typename T >
T PolyFit< T >::solveLS ( void  )
inline

Definition at line 173 of file polyfit.h.

173  {
174 
175  // Size check
176  if(xM.rows() != yM.rows()) {
177  throw std::exception();
178  }
179 
180  buildV();
181 
182  switch(options.solver) {
184  pCoef = V.colPivHouseholderQr().solve(yM.col(0));
185  break;
187  pCoef = V.fullPivHouseholderQr().solve(yM.col(0));
188  break;
189  case EIGEN_JACOBI_SVD:
190  pCoef = V.jacobiSvd(Eigen::ComputeThinU |
191  Eigen::ComputeThinV)
192  .solve(yM.col(0));
193  break;
194  }
195  return getMSE();
196  }

References PolyFit< T >::buildV(), PolyFit< T >::EIGEN_COL_PIV_HOUSEHOLDER, PolyFit< T >::EIGEN_FULL_PIV_HOUSEHOLDER, PolyFit< T >::EIGEN_JACOBI_SVD, PolyFit< T >::getMSE(), PolyFit< T >::options, PolyFit< T >::pCoef, PolyFit< T >::Options::solver, PolyFit< T >::V, PolyFit< T >::xM, and PolyFit< T >::yM.

Referenced by PolyFit< T >::solveRLS().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ solveRLS()

template<typename T >
void PolyFit< T >::solveRLS ( void  )
inline

Definition at line 224 of file polyfit.h.

224  {
225  std::vector<int> bestSubset;
226  Eigen::Matrix<T, Eigen::Dynamic, 1> bestCoef;
227 
228  // Probability that we can at least choose
229  // one sample with options.maxMPts free of
230  // outliers (sugg. by Peter Kovesi's code)
231  double p = 0.99;
232 
233  int trialCount = 0;
234  int N = 1;
235  while(N > trialCount) {
236 
237  std::set<int> indexSet;
238  randsample(static_cast<int>(y.size() - 1),
239  options.maxMPts, indexSet);
240 
241  if(static_cast<int>(indexSet.size()) != options.maxMPts) {
242  throw std::logic_error("Assert Polyfit l265");
243  }
244 
245  // Build (sample,signal) for current subset
246  dataToEigenSubset(indexSet);
247  buildV();
248 
249  // Solve the LS-fitting problem
250  double mse = solveLS();
251 
252  // Compute inlier indices
253  std::vector<int> inliers;
254  int nInliers = getInliers(inliers);
255 
256  if(inliers.size() > bestSubset.size()) {
257  // Store settings
258  bestSubset = inliers;
259  bestCoef = pCoef;
260 
261  // Refine estimate of N (based on Peter Kovesi's MATLAB impl. of RANSAC)
262  double fracInliers = static_cast<double>(inliers.size()) / double(yM.rows());
263  double pNoOutliers = 1 - pow(fracInliers, options.maxMPts);
264  pNoOutliers = std::max(1e-9, pNoOutliers);
265  pNoOutliers = std::min(1 - 1e-9, pNoOutliers);
266  N = log(1 - p) / log(pNoOutliers);
267  }
268 
269  ++trialCount;
270  if(trialCount > options.maxTrial) {
271  break;
272  }
273  }
274  pCoef = bestCoef;
275  }

References PolyFit< T >::buildV(), PolyFit< T >::dataToEigenSubset(), PolyFit< T >::getInliers(), galaxis::utils::log(), PolyFit< T >::Options::maxMPts, PolyFit< T >::Options::maxTrial, PolyFit< T >::options, PolyFit< T >::pCoef, PolyFit< T >::randsample(), PolyFit< T >::solveLS(), PolyFit< T >::y, and PolyFit< T >::yM.

Here is the call graph for this function:

Member Data Documentation

◆ gen

template<typename T >
boost::mt19937 PolyFit< T >::gen
private

Definition at line 68 of file polyfit.h.

Referenced by PolyFit< T >::randsample().

◆ options

◆ pCoef

◆ V

template<typename T >
MatType PolyFit< T >::V
private

◆ x

template<typename T >
std::vector<T>& PolyFit< T >::x
private

◆ xM

template<typename T >
VecType PolyFit< T >::xM
private

◆ y

◆ yM


The documentation for this class was generated from the following file:
PolyFit::pCoef
VecType pCoef
Definition: polyfit.h:79
PolyFit::gen
boost::mt19937 gen
Definition: polyfit.h:68
PolyFit::randsample
void randsample(int N, int s, std::set< int > &ind)
Definition: polyfit.h:212
PolyFit::VecType
Eigen::Matrix< T, Eigen::Dynamic, 1 > VecType
Definition: polyfit.h:76
PolyFit::yM
VecType yM
Definition: polyfit.h:86
PolyFit::y
std::vector< T > & y
Definition: polyfit.h:82
PolyFit::dataToEigen
void dataToEigen(void)
Definition: polyfit.h:309
PolyFit::Options::maxMPts
int maxMPts
Definition: polyfit.h:57
PolyFit::buildV
void buildV(void)
Definition: polyfit.h:321
PolyFit::Options::tolerance
double tolerance
Definition: polyfit.h:58
PolyFit::Options::solver
SolverType solver
Definition: polyfit.h:54
PolyFit::getMSE
T getMSE(void)
Definition: polyfit.h:199
PolyFit::xM
VecType xM
Definition: polyfit.h:85
PolyFit::solveLS
T solveLS(void)
Definition: polyfit.h:173
PolyFit::options
Options & options
Definition: polyfit.h:92
PolyFit::dataToEigenSubset
void dataToEigenSubset(std::set< int > &indexSet)
Definition: polyfit.h:278
PolyFit::getInliers
int getInliers(std::vector< int > &inliers)
Definition: polyfit.h:295
PolyFit::EIGEN_FULL_PIV_HOUSEHOLDER
@ EIGEN_FULL_PIV_HOUSEHOLDER
Definition: polyfit.h:42
PolyFit::Options::polyDeg
int polyDeg
Definition: polyfit.h:55
PolyFit::EIGEN_COL_PIV_HOUSEHOLDER
@ EIGEN_COL_PIV_HOUSEHOLDER
Definition: polyfit.h:41
PolyFit::V
MatType V
Definition: polyfit.h:89
PolyFit::Options::maxTrial
int maxTrial
Definition: polyfit.h:56
galaxis::utils::log
void log(const Args &... args)
Definition: logger.hpp:33
PolyFit::x
std::vector< T > & x
Definition: polyfit.h:81
PolyFit::DistributionType
boost::uniform_int< int > DistributionType
Definition: polyfit.h:69
PolyFit::EIGEN_JACOBI_SVD
@ EIGEN_JACOBI_SVD
Definition: polyfit.h:43