41 #include <pcl/common/polynomial_calculations.h>
47 template <
typename real>
56 template <
typename real>
64 roots.push_back (0.0);
68 roots.push_back (-b/a);
72 std::cout << __PRETTY_FUNCTION__ <<
": Found "<<roots.size ()<<
" roots.\n";
73 for (
unsigned int i=0; i<roots.size (); i++)
76 real result = a*x + b;
79 std::cout <<
"Something went wrong during solving of polynomial "<<a<<
"x + "<<b<<
" = 0\n";
82 std::cout <<
"Root "<<i<<
" = "<<roots[i]<<
". ("<<a<<
"x^ + "<<b<<
" = "<<result<<
")\n";
88 template <
typename real>
103 roots.push_back (0.0);
105 std::vector<real> tmpRoots;
107 for (
const auto& tmpRoot: tmpRoots)
109 roots.push_back (tmpRoot);
113 real tmp = b*b - 4*a*c;
117 real tmp2 = 1.0/ (2*a);
118 roots.push_back ( (-b + tmp)*tmp2);
119 roots.push_back ( (-b - tmp)*tmp2);
123 roots.push_back (-b/ (2*a));
127 std::cout << __PRETTY_FUNCTION__ <<
": Found "<<roots.size ()<<
" roots.\n";
128 for (
unsigned int i=0; i<roots.size (); i++)
130 real x=roots[i], x2=x*x;
131 real result = a*x2 + b*x + c;
134 std::cout <<
"Something went wrong during solving of polynomial "<<a<<
"x^2 + "<<b<<
"x + "<<c<<
" = 0\n";
143 template<
typename real>
158 roots.push_back (0.0);
160 std::vector<real> tmpRoots;
162 for (
const auto& tmpRoot: tmpRoots)
164 roots.push_back (tmpRoot);
172 alpha = ( (3.0*a*c-b2)/ (3.0*a2)),
173 beta = (2*b3/ (27.0*a3)) - ( (b*c)/ (3.0*a2)) + (d/a),
174 alpha2 = alpha*alpha,
175 alpha3 = alpha2*alpha,
179 double resubValue = b/ (3*a);
183 double discriminant = (alpha3/27.0) + 0.25*beta2;
191 roots.push_back ( (-3.0*beta)/ (2.0*alpha) - resubValue);
192 roots.push_back ( (3.0*beta)/alpha - resubValue);
196 roots.push_back (-resubValue);
199 else if (discriminant > 0)
201 double sqrtDiscriminant = sqrt (discriminant);
202 double d1 = -0.5*beta + sqrtDiscriminant,
203 d2 = -0.5*beta - sqrtDiscriminant;
205 d1 = -pow (-d1, 1.0/3.0);
207 d1 = pow (d1, 1.0/3.0);
210 d2 = -pow (-d2, 1.0/3.0);
212 d2 = pow (d2, 1.0/3.0);
215 roots.push_back (d1 + d2 - resubValue);
219 double tmp1 = sqrt (- (4.0/3.0)*alpha),
220 tmp2 = std::acos (-sqrt (-27.0/alpha3)*0.5*beta)/3.0;
221 roots.push_back (tmp1*std::cos (tmp2) - resubValue);
222 roots.push_back (-tmp1*std::cos (tmp2 +
M_PI/3.0) - resubValue);
223 roots.push_back (-tmp1*std::cos (tmp2 -
M_PI/3.0) - resubValue);
227 std::cout << __PRETTY_FUNCTION__ <<
": Found "<<roots.size ()<<
" roots.\n";
228 for (
unsigned int i=0; i<roots.size (); i++)
230 real x=roots[i], x2=x*x, x3=x2*x;
231 real result = a*x3 + b*x2 + c*x + d;
232 if (std::abs (result) > 1e-4)
234 std::cout <<
"Something went wrong:\n";
237 std::cout <<
"Root "<<i<<
" = "<<roots[i]<<
". ("<<a<<
"x^3 + "<<b<<
"x^2 + "<<c<<
"x + "<<d<<
" = "<<result<<
")\n";
244 template<
typename real>
247 std::vector<real>& roots)
const
260 roots.push_back (0.0);
262 std::vector<real> tmpRoots;
264 for (
const auto& tmpRoot: tmpRoots)
266 roots.push_back (tmpRoot);
276 alpha = ( (-3.0*b2)/ (8.0*a2)) + (c/a),
277 beta = (b3/ (8.0*a3)) - ( (b*c)/ (2.0*a2)) + (d/a),
278 gamma = ( (-3.0*b4)/ (256.0*a4)) + ( (c*b2)/ (16.0*a3)) - ( (b*d)/ (4.0*a2)) + (e/a),
279 alpha2 = alpha*alpha;
282 double resubValue = b/ (4*a);
289 std::vector<real> tmpRoots;
291 for (
const auto& quadraticRoot: tmpRoots)
295 roots.push_back (-resubValue);
297 else if (quadraticRoot > 0.0)
299 double root1 = sqrt (quadraticRoot);
300 roots.push_back (root1 - resubValue);
301 roots.push_back (-root1 - resubValue);
308 double alpha3 = alpha2*alpha,
310 p = (-alpha2/12.0)-gamma,
311 q = (-alpha3/108.0)+ ( (alpha*gamma)/3.0)- (beta2/8.0),
314 u = (0.5*q) + sqrt ( (0.25*q2)+ (p3/27.0));
316 u = pow (u, 1.0/3.0);
320 u = -pow (-u, 1.0/3.0);
322 double y = (-5.0/6.0)*alpha - u;
326 double w = alpha + 2.0*y;
342 double tmp1 = - (3.0*alpha + 2.0*y + 2.0* (beta/w)),
343 tmp2 = - (3.0*alpha + 2.0*y - 2.0* (beta/w));
348 double root1 = - (b/ (4.0*a)) + 0.5* (w+tmp1);
349 double root2 = - (b/ (4.0*a)) + 0.5* (w-tmp1);
350 roots.push_back (root1);
351 roots.push_back (root2);
355 double root1 = - (b/ (4.0*a)) + 0.5*w;
356 roots.push_back (root1);
362 double root3 = - (b/ (4.0*a)) + 0.5* (-w+tmp2);
363 double root4 = - (b/ (4.0*a)) + 0.5* (-w-tmp2);
364 roots.push_back (root3);
365 roots.push_back (root4);
369 double root3 = - (b/ (4.0*a)) - 0.5*w;
370 roots.push_back (root3);
377 std::cout << __PRETTY_FUNCTION__ <<
": Found "<<roots.size ()<<
" roots.\n";
378 for (
unsigned int i=0; i<roots.size (); i++)
380 real x=roots[i], x2=x*x, x3=x2*x, x4=x2*x2;
381 real result = a*x4 + b*x3 + c*x2 + d*x + e;
382 if (std::abs (result) > 1e-4)
384 std::cout <<
"Something went wrong:\n";
387 std::cout <<
"Root "<<i<<
" = "<<roots[i]
388 <<
". ("<<a<<
"x^4 + "<<b<<
"x^3 + "<<c<<
"x^2 + "<<d<<
"x + "<<e<<
" = "<<result<<
")\n";
395 template<
typename real>
398 std::vector<Eigen::Matrix<real, 3, 1>, Eigen::aligned_allocator<Eigen::Matrix<real, 3, 1> > >& samplePoints,
unsigned int polynomial_degree,
bool& error)
const
406 template<
typename real>
409 std::vector<Eigen::Matrix<real, 3, 1>, Eigen::aligned_allocator<Eigen::Matrix<real, 3, 1> > >& samplePoints,
unsigned int polynomial_degree,
415 if (parameters_size > samplePoints.size ())
428 Eigen::Matrix<real, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> A (parameters_size, parameters_size);
430 Eigen::Matrix<real, Eigen::Dynamic, 1> b (parameters_size);
434 std::vector<real> C (parameters_size);
435 for (
const auto& point: samplePoints)
437 real currentX = point[0], currentY = point[1], currentZ = point[2];
440 auto CRevPtr = C.rbegin ();
442 for (
unsigned int xDegree=0; xDegree<=polynomial_degree; ++xDegree)
445 for (
unsigned int yDegree=0; yDegree<=polynomial_degree-xDegree; ++yDegree, ++CRevPtr)
447 *CRevPtr = tmpX*tmpY;
454 for (std::size_t i=0; i<parameters_size; ++i)
456 b[i] += currentZ * C[i];
458 for (std::size_t j=i; j<parameters_size; ++j)
460 A (i, j) += C[i] * C[j];
471 for (std::size_t i = 0; i < parameters_size; ++i)
473 for (std::size_t j = 0; j < i; ++j)
479 Eigen::Matrix<real, Eigen::Dynamic, 1> parameters;
485 parameters = A.inverse () * b;
490 real inversionCheckResult = (A*parameters - b).norm ();
491 if (inversionCheckResult > 1e-5)
497 std::copy_n(parameters.data(), parameters_size, ret.
parameters);
This represents a bivariate polynomial and provides some functionality for it.
void setDegree(int new_degree)
Initialize members to default values.
static unsigned int getNoOfParametersFromDegree(int n)
How many parameters has a bivariate polynomial of the given degree.
void solveCubicEquation(real a, real b, real c, real d, std::vector< real > &roots) const
Solves an equation of the form ax^3 + bx^2 + cx + d = 0 See https://en.wikipedia.org/wiki/Cubic_equat...
bool isNearlyZero(real d) const
check if std::abs(d)<zeroValue
BivariatePolynomialT< real > bivariatePolynomialApproximation(std::vector< Eigen::Matrix< real, 3, 1 >, Eigen::aligned_allocator< Eigen::Matrix< real, 3, 1 > > > &samplePoints, unsigned int polynomial_degree, bool &error) const
Get the bivariate polynomial approximation for Z(X,Y) from the given sample points.
bool sqrtIsNearlyZero(real d) const
check if sqrt(std::abs(d))<zeroValue
void solveQuarticEquation(real a, real b, real c, real d, real e, std::vector< real > &roots) const
Solves an equation of the form ax^4 + bx^3 + cx^2 +dx + e = 0 See https://en.wikipedia....
void solveQuadraticEquation(real a, real b, real c, std::vector< real > &roots) const
Solves an equation of the form ax^2 + bx + c = 0 See https://en.wikipedia.org/wiki/Quadratic_equation...
void solveLinearEquation(real a, real b, std::vector< real > &roots) const
Solves an equation of the form ax + b = 0.
void setZeroValue(real new_zero_value)
Set zero_value.
real sqr_zero_value
sqr of the above
real zero_value
Every value below this is considered to be zero.