polynomial.hpp
Go to the documentation of this file.
1 
8 /*****************************************************************************
9 ** Ifdefs
10 *****************************************************************************/
11 
12 #ifndef ECL_GEOMETRY_POLYNOMIALS_HPP_
13 #define ECL_GEOMETRY_POLYNOMIALS_HPP_
14 
15 /*****************************************************************************
16 ** Includes
17 *****************************************************************************/
18 
19 #include <cmath>
20 #include "cartesian_point.hpp"
21 #include "function_math.hpp"
22 #include "pascals_triangle.hpp"
23 #include <ecl/config/macros.hpp>
24 #include <ecl/concepts/macros.hpp>
25 #include <ecl/concepts/streams.hpp>
26 #include <ecl/containers/array.hpp>
27 #include <ecl/exceptions/standard_exception.hpp>
28 #include <ecl/errors/compile_time_assert.hpp>
29 #include <ecl/utilities/blueprints.hpp>
30 #include <ecl/formatters/floats.hpp>
31 #include <iostream>
32 #include "macros.hpp"
33 
34 /*****************************************************************************
35 ** Namespaces
36 *****************************************************************************/
37 
38 namespace ecl {
39 
40 /*****************************************************************************
41 ** Forward declarations
42 *****************************************************************************/
43 
44 template <unsigned int N> class Polynomial;
45 
46 /*****************************************************************************
47 ** BluePrintFactory
48 *****************************************************************************/
49 
61 template<unsigned int N>
62 class BluePrintFactory< Polynomial<N> > {
63 public:
64  BluePrintFactory() {};
65  ~BluePrintFactory() {};
66 };
67 
68 /*****************************************************************************
69 ** Interface [Polynomial]
70 *****************************************************************************/
109 template <unsigned int N>
110 class ecl_geometry_PUBLIC Polynomial : public BluePrintFactory< Polynomial<N> >, public FunctionMath< Polynomial<N> > {
111  public:
112  /*********************
113  ** Convenience
114  **********************/
115  typedef Array<double,N+1> Coefficients;
117  /*********************
118  ** C&D
119  **********************/
127  Polynomial() : coeff(Coefficients::Constant(0.0)) {};
128 
153  template<typename Derived>
154  Polynomial(const BluePrint< Derived > &blueprint) {
155  blueprint.implementApply(*this);
156  }
157  virtual ~Polynomial() {}
158 
159  /*********************
160  ** Transform
161  **********************/
176  void shift_horizontal(const double &shift);
177 // void stretch_horizontal(double multiplier);
178 
179  /*********************
180  ** Derivatives
181  **********************/
189  Polynomial<N-1> derivative() const {
190  Polynomial<N-1> derivative_polynomial;
191  typename Polynomial<N-1>::Coefficients &derivative_coefficients = derivative_polynomial.coefficients();
192  for ( unsigned int i = 0; i < N; ++i ) {
193  derivative_coefficients[i] = (i+1)*coeff[i+1];
194  }
195  return derivative_polynomial;
196  }
205  double derivative(const double &x) const;
214  double dderivative(const double &x) const;
215 
216  /*********************
217  ** Accessors
218  **********************/
233  Coefficients& coefficients() { return coeff; };
239  const Coefficients& coefficients() const { return coeff; };
240 
249  double operator ()(const double &x) const;
250 
263  template <typename OutputStream, unsigned int Degree>
264  friend OutputStream& operator << (OutputStream &ostream, const Polynomial<Degree> &polynomial);
265 
266  private:
267  Coefficients coeff;
268 };
269 
278 template <>
279 class ECL_PUBLIC Polynomial<0> {
280  public:
281  /*********************
282  ** Convenience
283  **********************/
284  typedef Array<double,1> Coefficients;
286  /*********************
287  ** C&D
288  **********************/
295  Polynomial() : coeff(Coefficients::Constant(0.0)) {};
296  virtual ~Polynomial() {};
297 
298  /*********************
299  ** Transform
300  **********************/
307  void shift_horizontal(const double& /* shift */) {}; // Does nothing.
308 
309  /*********************
310  ** Derivatives
311  **********************/
319  Polynomial<0> derivative() const {
320  return Polynomial<0>();
321  }
329  double derivative(const double& /* x */ ) const {
330  return 0.0;
331  };
339  double dderivative(const double& /* x */) const {
340  return 0.0;
341  };
342 
343  /*********************
344  ** Accessors
345  **********************/
360  Coefficients& coefficients() { return coeff; };
366  const Coefficients& coefficients() const { return coeff; };
367 
375  double operator ()(const double& /* x */) const {
376  return coeff[0];
377  };
378 
379  private:
380  Coefficients coeff;
381 };
382 
383 /*****************************************************************************
384 ** Typedefs
385 *****************************************************************************/
386 
392 /*****************************************************************************
393  * Implementation [Polynomial - Transform]
394  ****************************************************************************/
395 template <unsigned int N>
396 void Polynomial<N>::shift_horizontal(const double &shift)
397 {
398  PascalsTriangle<N> pascals_triangle;
400  double tmp;
401 
402  for ( unsigned int i = 0; i < N; ++i ) {
403  tmp = -1*shift;
404  int j = i+1;
405  for ( iter = (pascals_triangle.begin(i)+1); iter != pascals_triangle.end(i); ++iter ) { // skip the first one
406  coeff[i] += (*iter)*tmp*coeff[j];
407  tmp *= (-1*shift);
408  ++j;
409  }
410  }
411 }
412 /*****************************************************************************
413  * Implementation [Polynomial - Access]
414  ****************************************************************************/
415 template <unsigned int N>
416 double Polynomial<N>::operator()(const double &x) const
417 {
418  double tmp = x;
419  double value = coeff[0];
420  for ( unsigned int i = 1; i <= N; ++i ) {
421  value += coeff[i]*tmp;
422  tmp *= x;
423  }
424  return value;
425 }
426 template <unsigned int N>
427 double Polynomial<N>::derivative(const double &x) const {
428 
429  if ( N > 0 ) {
430  return derivative()(x);
431  } else {
432  return 0.0;
433  }
434 }
435 
436 template <unsigned int N>
437 double Polynomial<N>::dderivative(const double &x) const {
438 
439  if ( N > 1 ) {
440  return derivative().derivative()(x);
441  } else {
442  return 0.0;
443  }
444 }
445 
446 /*****************************************************************************
447 ** Streaming Operator [Polynomial]
448 *****************************************************************************/
449 
450 template <typename OutputStream, unsigned int Degree>
451 OutputStream& operator << (OutputStream &ostream, const Polynomial<Degree> &polynomial)
452 {
454 
455  Format<double> format;
456  format.precision(2);
457 
458  ostream << format(polynomial.coeff[0]);
459  for (unsigned int i = 1; i <= Degree; ++i) {
460  ostream << " + " << format(polynomial.coeff[i]) << "x^" << i;
461  }
462  ostream.flush();
463 
464  return ostream;
465 }
466 
467 /*****************************************************************************
468 ** BluePrints
469 *****************************************************************************/
470 
471 namespace blueprints {
472 
473 /*****************************************************************************
474 ** Interface [LinearInterpolation]
475 *****************************************************************************/
476 
491 class ecl_geometry_PUBLIC LinearInterpolation : public ecl::BluePrint<LinearInterpolation> {
492  public:
496  typedef ecl::LinearFunction base_type;
507  LinearInterpolation(const double x_i, const double y_i, const double x_f, const double y_f) :
508  x_initial(x_i),
509  y_initial(y_i),
510  x_final(x_f),
511  y_final(y_f)
512  {}
513 
514  virtual ~LinearInterpolation() {}
515 
523  ecl::LinearFunction instantiate();
524 
531  void apply(ecl::LinearFunction& function) const;
532 
533  private:
534  double x_initial, y_initial;
535  double x_final, y_final;
536 };
537 
538 /*****************************************************************************
539 ** Interface [LinearPointSlope]
540 *****************************************************************************/
554 class ecl_geometry_PUBLIC LinearPointSlopeForm : public ecl::BluePrint<LinearPointSlopeForm> {
555  public:
559  typedef ecl::LinearFunction base_type;
569  LinearPointSlopeForm(const double x_f, const double y_f, const double s) :
570  slope(s),
571  x_final(x_f),
572  y_final(y_f)
573  {}
574 
575  virtual ~LinearPointSlopeForm() {}
576 
584  ecl::LinearFunction instantiate();
585 
592  void apply(ecl::LinearFunction& function) const;
593 
594  private:
595  double slope;
596  double x_final, y_final;
597 };
598 
599 
600 /*****************************************************************************
601 ** Interface [CubicDerivativeInterpolation]
602 *****************************************************************************/
603 
620 class ecl_geometry_PUBLIC CubicDerivativeInterpolation : public ecl::BluePrint<CubicDerivativeInterpolation> {
621  public:
625  typedef ecl::CubicPolynomial base_type;
638  CubicDerivativeInterpolation(const double x_i, const double y_i, const double ydot_i,
639  const double x_f, const double y_f, const double ydot_f) :
640  x_initial(x_i),
641  y_initial(y_i),
642  ydot_initial(ydot_i),
643  x_final(x_f),
644  y_final(y_f),
645  ydot_final(ydot_f)
646  {}
647 
648  virtual ~CubicDerivativeInterpolation() {}
656  ecl::CubicPolynomial instantiate();
657 
664  void apply(ecl::CubicPolynomial& polynomial) const;
665 
666  private:
667  double x_initial, y_initial, ydot_initial;
668  double x_final, y_final, ydot_final;
669 };
670 /*****************************************************************************
671 ** Interface [CubicSecondDerivativeInterpolation]
672 *****************************************************************************/
673 
690 class ecl_geometry_PUBLIC CubicSecondDerivativeInterpolation : public ecl::BluePrint<CubicSecondDerivativeInterpolation> {
691  public:
695  typedef ecl::CubicPolynomial base_type;
708  CubicSecondDerivativeInterpolation(const double x_i, const double y_i, const double yddot_i,
709  const double x_f, const double y_f, const double yddot_f) :
710  x_initial(x_i),
711  y_initial(y_i),
712  yddot_initial(yddot_i),
713  x_final(x_f),
714  y_final(y_f),
715  yddot_final(yddot_f)
716  {}
717 
718  virtual ~CubicSecondDerivativeInterpolation() {}
719 
727  base_type instantiate();
728 
735  void apply(base_type& polynomial) const;
736 
737  private:
738  double x_initial, y_initial, yddot_initial;
739  double x_final, y_final, yddot_final;
740 };
741 
742 /*****************************************************************************
743 ** Interface [QuinticInterpolation]
744 *****************************************************************************/
745 
764 class ecl_geometry_PUBLIC QuinticInterpolation : public ecl::BluePrint<QuinticInterpolation> {
765  public:
769  typedef ecl::QuinticPolynomial base_type;
784  QuinticInterpolation(const double x_i, const double y_i, const double ydot_i, const double yddot_i,
785  const double x_f, const double y_f, const double ydot_f, const double yddot_f) :
786  x_initial(x_i),
787  y_initial(y_i),
788  ydot_initial(ydot_i),
789  yddot_initial(yddot_i),
790  x_final(x_f),
791  y_final(y_f),
792  ydot_final(ydot_f),
793  yddot_final(yddot_f)
794  {}
795 
796  virtual ~QuinticInterpolation() {}
797 
805  ecl::QuinticPolynomial instantiate();
806 
813  void apply(ecl::QuinticPolynomial& polynomial) const;
814 
815  private:
816  double x_initial, y_initial, ydot_initial, yddot_initial;
817  double x_final, y_final, ydot_final, yddot_final;
818 };
819 
820 }; // namespace blueprints
821 
822 /*****************************************************************************
823 ** BluePrintFactory
824 *****************************************************************************/
825 
831 
846 template<>
847 class BluePrintFactory< LinearFunction > {
848 public:
861  static LinearInterpolation Interpolation(const double x_i, const double y_i, const double x_f, const double y_f);
870  static LinearPointSlopeForm PointSlopeForm(const double x_f, const double y_f, const double slope);
871  virtual ~BluePrintFactory() {}
872 };
873 
889 template<>
890 class BluePrintFactory< CubicPolynomial > {
891 public:
909  static CubicDerivativeInterpolation DerivativeInterpolation(const double x_i, const double y_i, const double ydot_i,
910  const double x_f, const double y_f, const double ydot_f);
911 
929  static CubicSecondDerivativeInterpolation SecondDerivativeInterpolation(const double x_i, const double y_i, const double yddot_i,
930  const double x_f, const double y_f, const double yddot_f);
931 
932  virtual ~BluePrintFactory() {}
933 };
934 
949 template<>
950 class BluePrintFactory< QuinticPolynomial > {
951  public:
971  static QuinticInterpolation Interpolation(const double x_i, const double y_i, const double ydot_i, const double yddot_i,
972  const double x_f, const double y_f, const double ydot_f, const double yddot_f);
973 
974  virtual ~BluePrintFactory() {}
975 };
976 
977 
978 /*****************************************************************************
979 ** Interface [Maximum|Minimum][Polynomial]
980 *****************************************************************************/
989 template<>
990 class ecl_geometry_PUBLIC Maximum< LinearFunction > {
991 public:
1002  ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const LinearFunction &function);
1003  virtual ~Maximum() {}
1004 };
1005 
1013 template<>
1014 class ecl_geometry_PUBLIC Maximum<CubicPolynomial> {
1015 public:
1026  ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const CubicPolynomial& cubic);
1027  virtual ~Maximum() {}
1028 };
1029 
1038 template<>
1039 class ecl_geometry_PUBLIC Minimum< LinearFunction > {
1040 public:
1051  ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const LinearFunction &function);
1052  virtual ~Minimum() {}
1053 };
1054 
1062 template<>
1063 class ecl_geometry_PUBLIC Minimum<CubicPolynomial> {
1064 public:
1075  ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const CubicPolynomial& cubic);
1076  virtual ~Minimum() {}
1077 };
1078 
1079 /*****************************************************************************
1080 ** Interface [Intersection][LinearFunction]
1081 *****************************************************************************/
1087 template<>
1088 class ecl_geometry_PUBLIC Intersection< LinearFunction > {
1089 public:
1090  Intersection() : last_operation_failed(false) {}
1091  virtual ~Intersection() {}
1101  ECL_PUBLIC CartesianPoint2d operator()(const LinearFunction& f, const LinearFunction& g) ecl_throw_decl(StandardException);
1102 
1109  bool fail() const { return last_operation_failed; }
1110 
1111 private:
1112  bool last_operation_failed;
1113 };
1114 
1115 /*****************************************************************************
1116 ** Interface [Synthetic Division]
1117 *****************************************************************************/
1123 template<>
1124 class ecl_geometry_PUBLIC Division<QuadraticPolynomial> {
1125 public:
1126  Division() {};
1127  virtual ~Division() {};
1135  ECL_PUBLIC LinearFunction operator()(const QuadraticPolynomial &p, const double &factor, double &remainder);
1136 };
1137 
1143 template<>
1144 class ecl_geometry_PUBLIC Division<CubicPolynomial> {
1145 public:
1146  Division() {};
1147  virtual ~Division() {};
1155  ECL_PUBLIC QuadraticPolynomial operator()(const CubicPolynomial &p, const double &factor, double &remainder);
1156 };
1157 
1158 /*****************************************************************************
1159 ** Interface [Roots]
1160 *****************************************************************************/
1166 template<>
1167 class ecl_geometry_PUBLIC Roots<LinearFunction> {
1168 public:
1169  Roots() {}
1170  virtual ~Roots() {}
1177  ECL_PUBLIC Array<double> operator()(const LinearFunction& p);
1178 };
1179 
1185 template<>
1186 class ecl_geometry_PUBLIC Roots<QuadraticPolynomial> {
1187 public:
1188  Roots() {}
1189  virtual ~Roots() {}
1196  ECL_PUBLIC Array<double> operator()(const QuadraticPolynomial& p);
1197 };
1203 template<>
1204 class ecl_geometry_PUBLIC Roots<CubicPolynomial> {
1205 public:
1206  Roots() {}
1207  virtual ~Roots() {}
1214  ECL_PUBLIC Array<double> operator()(const CubicPolynomial& p);
1215 };
1216 
1217 /*****************************************************************************
1218 ** Interfaces [FunctionMath]
1219 *****************************************************************************/
1231 template <>
1232 class ECL_PUBLIC FunctionMath<LinearFunction> {
1233 public:
1234  FunctionMath() {};
1235  virtual ~FunctionMath() {};
1241  static CartesianPoint2d Intersection(const LinearFunction &f, const LinearFunction &g) ecl_throw_decl(StandardException) {
1242  CartesianPoint2d point;
1243  ecl_try {
1245  point = intersection(f,g);
1246  } ecl_catch( const StandardException &e ) {
1248  }
1249  return point;
1250  }
1256  static Array<double> Roots(const LinearFunction &function) {
1257  return ecl::Roots<LinearFunction>()(function);
1258  }
1264  static double Minimum(const double& x_begin, const double& x_end, const LinearFunction &function) {
1265  return ecl::Minimum<LinearFunction>()(x_begin, x_end, function);
1266  }
1272  static double Maximum(const double& x_begin, const double& x_end, const LinearFunction &function) {
1273  return ecl::Maximum<LinearFunction>()(x_begin, x_end, function);
1274  }
1275 };
1283 template <>
1284 class ECL_PUBLIC FunctionMath<QuadraticPolynomial> {
1285 public:
1286  FunctionMath() {};
1287  virtual ~FunctionMath() {};
1293  static Array<double> Roots(const QuadraticPolynomial &p) {
1294  return ecl::Roots<QuadraticPolynomial>()(p);
1295  }
1299  static LinearFunction Division(const QuadraticPolynomial &p, const double &factor, double &remainder) {
1300  LinearFunction f(ecl::Division<QuadraticPolynomial>()(p,factor,remainder));
1301  return f;
1302  }
1303 };
1304 
1312 template <>
1313 class ECL_PUBLIC FunctionMath<CubicPolynomial> {
1314 public:
1315  FunctionMath() {};
1316  virtual ~FunctionMath() {};
1322  static Array<double> Roots(const CubicPolynomial &p) {
1323  return ecl::Roots<CubicPolynomial>()(p);
1324  }
1328  static QuadraticPolynomial Division(const CubicPolynomial &p, const double &factor, double &remainder) {
1329  QuadraticPolynomial q(ecl::Division<CubicPolynomial>()(p,factor,remainder));
1330  return q;
1331  }
1337  static double Minimum(const double& x_begin, const double& x_end, const CubicPolynomial &function) {
1338  return ecl::Minimum<CubicPolynomial>()(x_begin, x_end, function);
1339  }
1345  static double Maximum(const double& x_begin, const double& x_end, const CubicPolynomial &function) {
1346  return ecl::Maximum<CubicPolynomial>()(x_begin, x_end, function);
1347  }
1348 };
1349 
1350 }; // namespace ecl
1351 
1352 #endif /*ECL_GEOMETRY_POLYNOMIALS_HPP_*/
Blueprint for interpolating a cubic polynomial between end point conditions.
Definition: polynomial.hpp:620
#define ecl_throw(exception)
Standard ecl throw exception throw.
const_iterator end(unsigned int index=0) const
Iterator generator for diagonals of pascals triangle [end].
Formatter for double types.
Definition: floats.hpp:519
void g(const int &i)
Blueprint for interpolating a cubic polynomial between end point conditions.
Definition: polynomial.hpp:690
#define ecl_throw_decl(exception)
Standard ecl throw exception declaration.
Mathematical minimum on a compact interval for cubic polynomials.
Defines validating functionality for the streams concept.
#define LOC
Stringify the line of code you are at.
#define ecl_geometry_PUBLIC
Blueprint for interpolating a linear function connecting end point conditions.
Definition: polynomial.hpp:491
X axis intercepts for linear functions.
virtual ~BluePrintFactory()
Blueprint for generating a linear function from slope and point pair.
Definition: polynomial.hpp:554
Synthetic division between cubic and a factor.
#define ECL_PUBLIC
double operator()(const double &x) const
Definition: polynomial.hpp:416
Primary template for blueprint factories.
Standard exception type, provides code location and error string.
Polynomial< 1 > LinearFunction
X axis intercepts for quadratics.
Mathematical maximum on a compact interval for linear functions.
Definition: polynomial.hpp:990
X axis intercepts for cubic polynomials.
Polynomial< 2 > QuadraticPolynomial
FormatFloat< Number > & precision(const unsigned int p)
Intersection of two linear functions.
Mathematical minimum on a compact interval for linear functions.
void shift_horizontal(const double &shift)
Definition: polynomial.hpp:396
const_iterator begin(unsigned int index=0) const
Iterator generator for diagonals of pascals triangle [begin].
Synthetic division between quadratic and a factor.
Blueprint for interpolating a quintic polynomial between end point conditions.
Definition: polynomial.hpp:764
Mathematical maximum on a compact interval for cubic polynomials.
#define ecl_compile_time_concept_check(Model)
Compile time concept checking assertion.
This is a parent template for blueprints using crtp.
Array< int,(N+2)*(N+1)/2 >::const_iterator const_iterator
Holds the coefficients for pascal&#39;s triangle up to row N.
Generic container storing a cartesian point of dimension N.
void f(int i) ecl_debug_throw_decl(StandardException)
#define ecl_catch(exception)
The catch part of a try-catch macro matching ecl_throw calls.
double dderivative(const double &x) const
Definition: polynomial.hpp:437
Polynomial< 3 > CubicPolynomial
Representation of a polynomial function of n-th degree.
Definition: polynomial.hpp:44
Polynomial< 5 > QuinticPolynomial
#define ecl_try
The try part of a try-catch macro matching ecl_throw calls.
Polynomial< N-1 > derivative() const


xbot_driver
Author(s): Roc, wangpeng@droid.ac.cn
autogenerated on Sat Oct 10 2020 03:27:37