MRPT  1.9.9
interp_fit.hpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+
9  */
10 #pragma once
11 
12 #include <mrpt/math/interp_fit.h>
13 
14 namespace mrpt::math
15 {
16 template <class T, class VECTOR>
17 T interpolate(const T& x, const VECTOR& ys, const T& x0, const T& x1)
18 {
20  ASSERT_(x1 > x0);
21  ASSERT_(!ys.empty());
22  const size_t N = ys.size();
23  if (x <= x0) return ys[0];
24  if (x >= x1) return ys[N - 1];
25  const T Ax = (x1 - x0) / T(N);
26  const size_t i = int((x - x0) / Ax);
27  if (i >= N - 1) return ys[N - 1];
28  const T Ay = ys[i + 1] - ys[i];
29  return ys[i] + (x - (x0 + i * Ax)) * Ay / Ax;
30  MRPT_END
31 }
32 
33 template <typename NUMTYPE, class VECTORLIKE>
34 NUMTYPE spline(
35  const NUMTYPE t, const VECTORLIKE& x, const VECTORLIKE& y, bool wrap2pi)
36 {
37  // Check input data
38  ASSERT_(x.size() == 4 && y.size() == 4);
39  ASSERT_(x[0] <= x[1] && x[1] <= x[2] && x[2] <= x[3]);
40  ASSERT_(t > x[0] && t < x[3]);
41 
42  NUMTYPE h[3];
43  for (unsigned int i = 0; i < 3; i++) h[i] = x[i + 1] - x[i];
44 
45  double k = 1 / (4 * h[0] * h[1] + 4 * h[0] * h[2] + 3 * h[1] * h[1] +
46  4 * h[1] * h[2]);
47  double a11 = 2 * (h[1] + h[2]) * k;
48  double a12 = -h[1] * k;
49  double a22 = 2 * (h[0] + h[1]) * k;
50 
51  double y0, y1, y2, y3;
52 
53  if (!wrap2pi)
54  {
55  y0 = y[0];
56  y1 = y[1];
57  y2 = y[2];
58  y3 = y[3];
59  }
60  else
61  {
62  // Assure the function is linear without jumps in the interval:
63  y0 = mrpt::math::wrapToPi(y[0]);
64  y1 = mrpt::math::wrapToPi(y[1]);
65  y2 = mrpt::math::wrapToPi(y[2]);
66  y3 = mrpt::math::wrapToPi(y[3]);
67 
68  double Ay;
69 
70  Ay = y1 - y0;
71  if (Ay > M_PI)
72  y1 -= M_2PI;
73  else if (Ay < -M_PI)
74  y1 += M_2PI;
75 
76  Ay = y2 - y1;
77  if (Ay > M_PI)
78  y2 -= M_2PI;
79  else if (Ay < -M_PI)
80  y2 += M_2PI;
81 
82  Ay = y3 - y2;
83  if (Ay > M_PI)
84  y3 -= M_2PI;
85  else if (Ay < -M_PI)
86  y3 += M_2PI;
87  }
88 
89  double b1 = (y2 - y1) / h[1] - (y1 - y0) / h[0];
90  double b2 = (y3 - y2) / h[2] - (y2 - y1) / h[1];
91 
92  double z0 = 0;
93  double z1 = 6 * (a11 * b1 + a12 * b2);
94  double z2 = 6 * (a12 * b1 + a22 * b2);
95  double z3 = 0;
96 
97  double res = 0;
98  if (t < x[1])
99  res = (z1 * pow((t - x[0]), 3) + z0 * pow((x[1] - t), 3)) / (6 * h[0]) +
100  (y1 / h[0] - h[0] / 6 * z1) * (t - x[0]) +
101  (y0 / h[0] - h[0] / 6 * z0) * (x[1] - t);
102  else
103  {
104  if (t < x[2])
105  res = (z2 * pow((t - x[1]), 3) + z1 * pow((x[2] - t), 3)) /
106  (6 * h[1]) +
107  (y2 / h[1] - h[1] / 6 * z2) * (t - x[1]) +
108  (y1 / h[1] - h[1] / 6 * z1) * (x[2] - t);
109  else if (t < x[3])
110  res = (z3 * pow((t - x[2]), 3) + z2 * pow((x[3] - t), 3)) /
111  (6 * h[2]) +
112  (y3 / h[2] - h[2] / 6 * z3) * (t - x[2]) +
113  (y2 / h[2] - h[2] / 6 * z2) * (x[3] - t);
114  }
115  return wrap2pi ? mrpt::math::wrapToPi(res) : res;
116 }
117 
118 template <typename NUMTYPE, class VECTORLIKE, int NUM_POINTS>
120  const NUMTYPE t, const VECTORLIKE& x, const VECTORLIKE& y, bool wrap2pi)
121 {
122  MRPT_START
123 
124  // http://en.wikipedia.org/wiki/Linear_least_squares
125  ASSERT_(x.size() == y.size());
126  ASSERT_(x.size() > 1);
127 
128  const size_t N = x.size();
129 
130  // X= [1 columns of ones, x' ]
131  const NUMTYPE x_min = x.minimum();
132  Eigen::Matrix<NUMTYPE, 2, NUM_POINTS> Xt;
133  Xt.resize(2, N);
134  for (size_t i = 0; i < N; i++)
135  {
136  Xt.set_unsafe(0, i, 1);
137  Xt.set_unsafe(1, i, x[i] - x_min);
138  }
139 
140  const auto B = ((Xt * Xt.transpose()).inv().eval() * Xt * y).eval();
141  ASSERT_(B.size() == 2);
142 
143  NUMTYPE ret = B[0] + B[1] * (t - x_min);
144 
145  // wrap?
146  if (!wrap2pi)
147  return ret;
148  else
149  return mrpt::math::wrapToPi(ret);
150 
151  MRPT_END
152 }
153 
154 template <
155  class VECTORLIKE1, class VECTORLIKE2, class VECTORLIKE3, int NUM_POINTS>
157  const VECTORLIKE1& ts, VECTORLIKE2& outs, const VECTORLIKE3& x,
158  const VECTORLIKE3& y, bool wrap2pi)
159 {
160  MRPT_START
161 
162  // http://en.wikipedia.org/wiki/Linear_least_squares
163  ASSERT_(x.size() == y.size());
164  ASSERT_(x.size() > 1);
165 
166  const size_t N = x.size();
167 
168  // X= [1 columns of ones, x' ]
169  using NUM = typename VECTORLIKE3::value_type;
170  const NUM x_min = x.minimum();
171  Eigen::Matrix<NUM, 2, NUM_POINTS> Xt;
172  Xt.resize(2, N);
173  for (size_t i = 0; i < N; i++)
174  {
175  Xt.set_unsafe(0, i, 1);
176  Xt.set_unsafe(1, i, x[i] - x_min);
177  }
178 
179  const auto B = ((Xt * Xt.transpose()).inv().eval() * Xt * y).eval();
180  ASSERT_(B.size() == 2);
181 
182  const size_t tsN = size_t(ts.size());
183  outs.resize(tsN);
184  if (!wrap2pi)
185  for (size_t k = 0; k < tsN; k++)
186  outs[k] = B[0] + B[1] * (ts[k] - x_min);
187  else
188  for (size_t k = 0; k < tsN; k++)
189  outs[k] = mrpt::math::wrapToPi(B[0] + B[1] * (ts[k] - x_min));
190  MRPT_END
191 }
192 } // namespace mrpt
193 
194 
NUMTYPE leastSquareLinearFit(const NUMTYPE t, const VECTORLIKE &x, const VECTORLIKE &y, bool wrap2pi=false)
Interpolates or extrapolates using a least-square linear fit of the set of values "x" and "y"...
Definition: interp_fit.hpp:119
#define MRPT_START
Definition: exceptions.h:262
GLdouble GLdouble t
Definition: glext.h:3689
#define M_2PI
Definition: common.h:58
T interpolate(const T &x, const VECTOR &ys, const T &x0, const T &x1)
Interpolate a data sequence "ys" ranging from "x0" to "x1" (equally spaced), to obtain the approximat...
Definition: interp_fit.hpp:17
#define ASSERT_(f)
Defines an assertion mechanism.
Definition: exceptions.h:113
This base provides a set of functions for maths stuff.
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
Definition: wrap2pi.h:51
#define MRPT_END
Definition: exceptions.h:266
NUMTYPE spline(const NUMTYPE t, const VECTORLIKE &x, const VECTORLIKE &y, bool wrap2pi=false)
Interpolates the value of a function in a point "t" given 4 SORTED points where "t" is between the tw...
Definition: interp_fit.hpp:34
GLenum GLint GLint y
Definition: glext.h:3538
GLuint res
Definition: glext.h:7268
GLenum GLint x
Definition: glext.h:3538
EIGEN_STRONG_INLINE PlainObject inv() const



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020