libcrn  3.9.5
A document image processing library
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CRNPolynomialRegression.cpp
Go to the documentation of this file.
1 /* Copyright 2011-2016 CoReNum, INSA-Lyon, ENS-Lyon
2  *
3  * This file is part of libcrn.
4  *
5  * libcrn is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * libcrn is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with libcrn. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * file: CRNPolynomialRegression.cpp
19  * \author Yann LEYDIER
20  */
21 
24 #include <CRNProtocols.h>
25 
26 using namespace crn;
27 
32 {
33  coefficients[0] += increment;
34  for (Point2DDouble &p : data)
35  {
36  p.Y += increment;
37  }
38 }
39 
41 void PolynomialRegression::computeCoeffs()
42 {
43  std::sort(data.begin(), data.end(), Point2DDouble::Comparer(Direction::LEFT));
44  // create matrices
45  MatrixDouble X(data.size(), dimension + 1);
46  MatrixDouble Y(data.size(), size_t(1));
47  for (size_t tmp = 0; tmp < data.size(); ++tmp)
48  {
49  X[tmp][0] = 1;
50  for (size_t d = 1; d <= dimension; ++d)
51  {
52  X[tmp][d] = X[tmp][d - 1] * data[tmp].X;
53  }
54  Y[tmp][0] = data[tmp].Y;
55  }
56  // Y = X ⋅ A + ε ⇒ Â = (tX ⋅ X)^-1 ⋅ tX ⋅ Y
57  SquareMatrixDouble tmpMat(X.MakeCovariance());
58  tmpMat *= (double)data.size(); // covariance is normalized, we don't want this
59  tmpMat = tmpMat.MakeGaussJordanInverse();
60  X.Transpose();
61  MatrixDouble res(tmpMat);
62  res *= X;
63  res *= Y;
64  for (size_t d = 0; d <= dimension; ++d)
65  {
66  coefficients[d] = res[d][0];
67  }
68 }
69 
70 double PolynomialRegression::operator[](double x) const
71 {
72  if (extrapolation == Extrapolation::LINEAR)
73  {
74  if (x < data.front().X)
75  {
76  double x0 = data[0].X;
77  double x1 = x0 + (data[1].X - x0) / 5;
78  double y0 = (*this)[x0];
79  double y1 = (*this)[x1];
80  double slope = (y1 - y0) / (x1 - x0);
81  return y0 + slope * (x - x0);
82  }
83  if (x > data.back().X)
84  {
85  double xn = data.back().X;
86  double xn1 = xn - (xn - data[data.size() - 2].X) / 5;
87  double yn = (*this)[xn];
88  double yn1 = (*this)[xn1];
89  double slope = (yn - yn1) / (xn - xn1);
90  return yn + slope * (x - xn);
91  }
92  }
93  double y = coefficients[0];
94  double xx = 1;
95  for (size_t d = 1; d <= dimension; ++d)
96  {
97  xx *= x;
98  y += coefficients[d] * xx;
99  }
100  return y;
101 }
102 
104  Cloner::Register<PolynomialRegression>();
105 CRN_END_CLASS_CONSTRUCTOR(PolynomialRegression)
106 
void TranslateY(int increment)
Translates the polynomial.
A 2D point class.
#define CRN_END_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:198
virtual double operator[](double x) const override
Gets ordinate at x (double)
double matrix class
Square double matrix class.
#define CRN_BEGIN_CLASS_CONSTRUCTOR(classname)
Defines a class constructor.
Definition: CRNObject.h:185