polynomial.hpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Ifdefs
00010 *****************************************************************************/
00011 
00012 #ifndef ECL_GEOMETRY_POLYNOMIALS_HPP_
00013 #define ECL_GEOMETRY_POLYNOMIALS_HPP_
00014 
00015 /*****************************************************************************
00016 ** Includes
00017 *****************************************************************************/
00018 
00019 #include <cmath>
00020 #include "cartesian_point.hpp"
00021 #include "function_math.hpp"
00022 #include "pascals_triangle.hpp"
00023 #include <ecl/config/macros.hpp>
00024 #include <ecl/concepts/macros.hpp>
00025 #include <ecl/concepts/streams.hpp>
00026 #include <ecl/containers/array.hpp>
00027 #include <ecl/exceptions/standard_exception.hpp>
00028 #include <ecl/errors/compile_time_assert.hpp>
00029 #include <ecl/utilities/blueprints.hpp>
00030 #include <ecl/formatters/floats.hpp>
00031 #include <iostream>
00032 #include "macros.hpp"
00033 
00034 /*****************************************************************************
00035 ** Namespaces
00036 *****************************************************************************/
00037 
00038 namespace ecl {
00039 
00040 /*****************************************************************************
00041 ** Forward declarations
00042 *****************************************************************************/
00043 
00044 template <unsigned int N> class Polynomial;
00045 
00046 /*****************************************************************************
00047 ** BluePrintFactory
00048 *****************************************************************************/
00049 
00061 template<unsigned int N>
00062 class BluePrintFactory< Polynomial<N> > {
00063 public:
00064         BluePrintFactory() {};
00065         ~BluePrintFactory() {};
00066 };
00067 
00068 /*****************************************************************************
00069 ** Interface [Polynomial]
00070 *****************************************************************************/
00109 template <unsigned int N>
00110 class ecl_geometry_PUBLIC Polynomial : public BluePrintFactory< Polynomial<N> >, public FunctionMath< Polynomial<N> > {
00111     public:
00112         /*********************
00113         ** Convenience
00114         **********************/
00115         typedef Array<double,N+1> Coefficients; 
00117         /*********************
00118         ** C&D
00119         **********************/
00127         Polynomial() : coeff(Coefficients::Constant(0.0)) {};
00128 
00153         template<typename Derived>
00154         Polynomial(const BluePrint< Derived > &blueprint) {
00155             blueprint.implementApply(*this);
00156         }
00157         virtual ~Polynomial() {}
00158 
00159         /*********************
00160         ** Transform
00161         **********************/
00176         void shift_horizontal(const double &shift);
00177 //        void stretch_horizontal(double multiplier);
00178 
00179         /*********************
00180         ** Derivatives
00181         **********************/
00189         Polynomial<N-1> derivative() const {
00190             Polynomial<N-1> derivative_polynomial;
00191             typename Polynomial<N-1>::Coefficients &derivative_coefficients = derivative_polynomial.coefficients();
00192             for ( unsigned int i = 0; i < N; ++i ) {
00193                 derivative_coefficients[i] = (i+1)*coeff[i+1];
00194             }
00195             return derivative_polynomial;
00196         }
00205         double derivative(const double &x) const;
00214         double dderivative(const double &x) const;
00215 
00216         /*********************
00217         ** Accessors
00218         **********************/
00233         Coefficients& coefficients() { return coeff; };
00239         const Coefficients& coefficients() const { return coeff; };
00240 
00249         double operator ()(const double &x) const;
00250 
00263         template <typename OutputStream, unsigned int Degree>
00264         friend OutputStream& operator << (OutputStream &ostream, const Polynomial<Degree> &polynomial);
00265 
00266     private:
00267         Coefficients coeff;
00268 };
00269 
00278 template <>
00279 class ECL_PUBLIC Polynomial<0> {
00280     public:
00281         /*********************
00282         ** Convenience
00283         **********************/
00284         typedef Array<double,1> Coefficients; 
00286         /*********************
00287         ** C&D
00288         **********************/
00295         Polynomial() : coeff(Coefficients::Constant(0.0)) {};
00296         virtual ~Polynomial() {};
00297 
00298         /*********************
00299         ** Transform
00300         **********************/
00307         void shift_horizontal(const double& /* shift */) {}; // Does nothing.
00308 
00309         /*********************
00310         ** Derivatives
00311         **********************/
00319         Polynomial<0> derivative() const {
00320             return Polynomial<0>();
00321         }
00329         double derivative(const double& /* x */ ) const {
00330             return 0.0;
00331         };
00339         double dderivative(const double& /* x */) const {
00340             return 0.0;
00341         };
00342 
00343         /*********************
00344         ** Accessors
00345         **********************/
00360         Coefficients& coefficients() { return coeff; };
00366         const Coefficients& coefficients() const { return coeff; };
00367 
00375         double operator ()(const double& /* x */) const {
00376             return coeff[0];
00377         };
00378 
00379     private:
00380         Coefficients coeff;
00381 };
00382 
00383 /*****************************************************************************
00384 ** Typedefs
00385 *****************************************************************************/
00386 
00387 typedef Polynomial<1> LinearFunction;            
00388 typedef Polynomial<2> QuadraticPolynomial;   
00389 typedef Polynomial<3> CubicPolynomial;       
00390 typedef Polynomial<5> QuinticPolynomial;     
00392 /*****************************************************************************
00393  * Implementation [Polynomial - Transform]
00394  ****************************************************************************/
00395 template <unsigned int N>
00396 void Polynomial<N>::shift_horizontal(const double &shift)
00397 {
00398     PascalsTriangle<N> pascals_triangle;
00399     typename PascalsTriangle<N>::const_iterator iter;
00400     double tmp;
00401 
00402     for ( unsigned int i = 0; i < N; ++i ) {
00403         tmp = -1*shift;
00404         int j = i+1;
00405         for ( iter = (pascals_triangle.begin(i)+1); iter != pascals_triangle.end(i); ++iter ) { // skip the first one
00406             coeff[i] += (*iter)*tmp*coeff[j];
00407             tmp *= (-1*shift);
00408             ++j;
00409         }
00410     }
00411 }
00412 /*****************************************************************************
00413  * Implementation [Polynomial - Access]
00414  ****************************************************************************/
00415 template <unsigned int N>
00416 double Polynomial<N>::operator()(const double &x) const
00417 {
00418     double tmp = x;
00419     double value = coeff[0];
00420     for ( unsigned int i = 1; i <= N; ++i ) {
00421          value += coeff[i]*tmp;
00422          tmp *= x;
00423     }
00424     return value;
00425 }
00426 template <unsigned int N>
00427 double Polynomial<N>::derivative(const double &x) const {
00428 
00429     if ( N > 0 ) {
00430         return derivative()(x);
00431     } else {
00432         return 0.0;
00433     }
00434 }
00435 
00436 template <unsigned int N>
00437 double Polynomial<N>::dderivative(const double &x) const {
00438 
00439     if ( N > 1 ) {
00440         return derivative().derivative()(x);
00441     } else {
00442         return 0.0;
00443     }
00444 }
00445 
00446 /*****************************************************************************
00447 ** Streaming Operator [Polynomial]
00448 *****************************************************************************/
00449 
00450 template <typename OutputStream, unsigned int Degree>
00451 OutputStream& operator << (OutputStream &ostream, const Polynomial<Degree> &polynomial)
00452 {
00453         ecl_compile_time_concept_check(StreamConcept<OutputStream>);
00454 
00455         Format<double> format;
00456     format.precision(2);
00457 
00458     ostream << format(polynomial.coeff[0]);
00459     for (unsigned int i = 1; i <= Degree; ++i) {
00460         ostream << " + " << format(polynomial.coeff[i]) << "x^" << i;
00461     }
00462     ostream.flush();
00463 
00464     return ostream;
00465 }
00466 
00467 /*****************************************************************************
00468 ** BluePrints
00469 *****************************************************************************/
00470 
00471 namespace blueprints {
00472 
00473 /*****************************************************************************
00474 ** Interface [LinearInterpolation]
00475 *****************************************************************************/
00476 
00491 class ecl_geometry_PUBLIC LinearInterpolation : public ecl::BluePrint<LinearInterpolation> {
00492     public:
00496         typedef ecl::LinearFunction base_type;
00507         LinearInterpolation(const double x_i, const double y_i, const double x_f, const double y_f) :
00508                     x_initial(x_i),
00509                     y_initial(y_i),
00510                     x_final(x_f),
00511                     y_final(y_f)
00512         {}
00513 
00514         virtual ~LinearInterpolation() {}
00515 
00523         ecl::LinearFunction instantiate();
00524 
00531         void apply(ecl::LinearFunction& function) const;
00532 
00533     private:
00534         double x_initial, y_initial;
00535         double x_final, y_final;
00536 };
00537 
00538 /*****************************************************************************
00539 ** Interface [LinearPointSlope]
00540 *****************************************************************************/
00554 class ecl_geometry_PUBLIC LinearPointSlopeForm : public ecl::BluePrint<LinearPointSlopeForm> {
00555     public:
00559         typedef ecl::LinearFunction base_type;
00569         LinearPointSlopeForm(const double x_f, const double y_f, const double s) :
00570                     slope(s),
00571                     x_final(x_f),
00572                     y_final(y_f)
00573         {}
00574 
00575         virtual ~LinearPointSlopeForm() {}
00576 
00584         ecl::LinearFunction instantiate();
00585 
00592         void apply(ecl::LinearFunction& function) const;
00593 
00594     private:
00595         double slope;
00596         double x_final, y_final;
00597 };
00598 
00599 
00600 /*****************************************************************************
00601 ** Interface [CubicDerivativeInterpolation]
00602 *****************************************************************************/
00603 
00620 class ecl_geometry_PUBLIC CubicDerivativeInterpolation : public ecl::BluePrint<CubicDerivativeInterpolation> {
00621     public:
00625         typedef ecl::CubicPolynomial base_type;
00638         CubicDerivativeInterpolation(const double x_i, const double y_i, const double ydot_i,
00639                 const double x_f, const double y_f, const double ydot_f) :
00640                     x_initial(x_i),
00641                     y_initial(y_i),
00642                     ydot_initial(ydot_i),
00643                     x_final(x_f),
00644                     y_final(y_f),
00645                     ydot_final(ydot_f)
00646         {}
00647 
00648         virtual ~CubicDerivativeInterpolation() {}
00656         ecl::CubicPolynomial instantiate();
00657 
00664         void apply(ecl::CubicPolynomial& polynomial) const;
00665 
00666     private:
00667         double x_initial, y_initial, ydot_initial;
00668         double x_final, y_final, ydot_final;
00669 };
00670 /*****************************************************************************
00671 ** Interface [CubicSecondDerivativeInterpolation]
00672 *****************************************************************************/
00673 
00690 class ecl_geometry_PUBLIC CubicSecondDerivativeInterpolation : public ecl::BluePrint<CubicSecondDerivativeInterpolation>  {
00691     public:
00695         typedef ecl::CubicPolynomial base_type;
00708         CubicSecondDerivativeInterpolation(const double x_i, const double y_i, const double yddot_i,
00709                 const double x_f, const double y_f, const double yddot_f) :
00710                     x_initial(x_i),
00711                     y_initial(y_i),
00712                     yddot_initial(yddot_i),
00713                     x_final(x_f),
00714                     y_final(y_f),
00715                     yddot_final(yddot_f)
00716         {}
00717 
00718         virtual ~CubicSecondDerivativeInterpolation() {}
00719 
00727         base_type instantiate();
00728 
00735         void apply(base_type& polynomial) const;
00736 
00737     private:
00738         double x_initial, y_initial, yddot_initial;
00739         double x_final, y_final, yddot_final;
00740 };
00741 
00742 /*****************************************************************************
00743 ** Interface [QuinticInterpolation]
00744 *****************************************************************************/
00745 
00764 class ecl_geometry_PUBLIC QuinticInterpolation : public ecl::BluePrint<QuinticInterpolation> {
00765     public:
00769         typedef ecl::QuinticPolynomial base_type;
00784         QuinticInterpolation(const double x_i, const double y_i, const double ydot_i, const double yddot_i,
00785                 const double x_f, const double y_f, const double ydot_f, const double yddot_f) :
00786                     x_initial(x_i),
00787                     y_initial(y_i),
00788                     ydot_initial(ydot_i),
00789                     yddot_initial(yddot_i),
00790                     x_final(x_f),
00791                     y_final(y_f),
00792                     ydot_final(ydot_f),
00793                     yddot_final(yddot_f)
00794         {}
00795 
00796         virtual ~QuinticInterpolation() {}
00797 
00805         ecl::QuinticPolynomial instantiate();
00806 
00813         void apply(ecl::QuinticPolynomial& polynomial) const;
00814 
00815     private:
00816         double x_initial, y_initial, ydot_initial, yddot_initial;
00817         double x_final, y_final, ydot_final, yddot_final;
00818 };
00819 
00820 }; // namespace blueprints
00821 
00822 /*****************************************************************************
00823 ** BluePrintFactory
00824 *****************************************************************************/
00825 
00826 using blueprints::LinearInterpolation;
00827 using blueprints::LinearPointSlopeForm;
00828 using blueprints::CubicDerivativeInterpolation;
00829 using blueprints::CubicSecondDerivativeInterpolation;
00830 using blueprints::QuinticInterpolation;
00831 
00846 template<>
00847 class BluePrintFactory< LinearFunction > {
00848 public:
00861         static LinearInterpolation Interpolation(const double x_i, const double y_i, const double x_f, const double y_f);
00870         static LinearPointSlopeForm PointSlopeForm(const double x_f, const double y_f, const double slope);
00871         virtual ~BluePrintFactory() {}
00872 };
00873 
00889 template<>
00890 class BluePrintFactory< CubicPolynomial > {
00891 public:
00909         static CubicDerivativeInterpolation DerivativeInterpolation(const double x_i, const double y_i, const double ydot_i,
00910                         const double x_f, const double y_f, const double ydot_f);
00911 
00929         static CubicSecondDerivativeInterpolation SecondDerivativeInterpolation(const double x_i, const double y_i, const double yddot_i,
00930                         const double x_f, const double y_f, const double yddot_f);
00931 
00932         virtual ~BluePrintFactory() {}
00933 };
00934 
00949 template<>
00950 class BluePrintFactory< QuinticPolynomial > {
00951     public:
00971         static QuinticInterpolation Interpolation(const double x_i, const double y_i, const double ydot_i, const double yddot_i,
00972                 const double x_f, const double y_f, const double ydot_f, const double yddot_f);
00973 
00974         virtual ~BluePrintFactory() {}
00975 };
00976 
00977 
00978 /*****************************************************************************
00979 ** Interface [Maximum|Minimum][Polynomial]
00980 *****************************************************************************/
00989 template<>
00990 class ecl_geometry_PUBLIC Maximum< LinearFunction > {
00991 public:
01002         ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const LinearFunction &function);
01003         virtual ~Maximum() {}
01004 };
01005 
01013 template<>
01014 class ecl_geometry_PUBLIC Maximum<CubicPolynomial> {
01015 public:
01026         ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const CubicPolynomial& cubic);
01027         virtual ~Maximum() {}
01028 };
01029 
01038 template<>
01039 class ecl_geometry_PUBLIC Minimum< LinearFunction > {
01040 public:
01051         ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const LinearFunction &function);
01052         virtual ~Minimum() {}
01053 };
01054 
01062 template<>
01063 class ecl_geometry_PUBLIC Minimum<CubicPolynomial> {
01064 public:
01075         ECL_PUBLIC double operator()(const double& x_begin, const double& x_end, const CubicPolynomial& cubic);
01076         virtual ~Minimum() {}
01077 };
01078 
01079 /*****************************************************************************
01080 ** Interface [Intersection][LinearFunction]
01081 *****************************************************************************/
01087 template<>
01088 class ecl_geometry_PUBLIC Intersection< LinearFunction > {
01089 public:
01090         Intersection() : last_operation_failed(false) {}
01091         virtual ~Intersection() {}
01101         ECL_PUBLIC CartesianPoint2d operator()(const LinearFunction& f, const LinearFunction& g) ecl_throw_decl(StandardException);
01102 
01109         bool fail() const { return last_operation_failed; }
01110 
01111 private:
01112         bool last_operation_failed;
01113 };
01114 
01115 /*****************************************************************************
01116 ** Interface [Synthetic Division]
01117 *****************************************************************************/
01123 template<>
01124 class ecl_geometry_PUBLIC Division<QuadraticPolynomial> {
01125 public:
01126         Division() {};
01127         virtual ~Division() {};
01135         ECL_PUBLIC LinearFunction operator()(const QuadraticPolynomial &p, const double &factor, double &remainder);
01136 };
01137 
01143 template<>
01144 class ecl_geometry_PUBLIC Division<CubicPolynomial> {
01145 public:
01146         Division() {};
01147         virtual ~Division() {};
01155         ECL_PUBLIC QuadraticPolynomial operator()(const CubicPolynomial &p, const double &factor, double &remainder);
01156 };
01157 
01158 /*****************************************************************************
01159 ** Interface [Roots]
01160 *****************************************************************************/
01166 template<>
01167 class ecl_geometry_PUBLIC Roots<LinearFunction> {
01168 public:
01169         Roots() {}
01170         virtual ~Roots() {}
01177         ECL_PUBLIC Array<double> operator()(const LinearFunction& p);
01178 };
01179 
01185 template<>
01186 class ecl_geometry_PUBLIC Roots<QuadraticPolynomial> {
01187 public:
01188         Roots() {}
01189         virtual ~Roots() {}
01196         ECL_PUBLIC Array<double> operator()(const QuadraticPolynomial& p);
01197 };
01203 template<>
01204 class ecl_geometry_PUBLIC Roots<CubicPolynomial> {
01205 public:
01206         Roots() {}
01207         virtual ~Roots() {}
01214         ECL_PUBLIC Array<double> operator()(const CubicPolynomial& p);
01215 };
01216 
01217 /*****************************************************************************
01218 ** Interfaces [FunctionMath]
01219 *****************************************************************************/
01231 template <>
01232 class ECL_PUBLIC FunctionMath<LinearFunction> {
01233 public:
01234         FunctionMath() {}; 
01235         virtual ~FunctionMath() {};
01241         static CartesianPoint2d Intersection(const LinearFunction &f, const LinearFunction &g) ecl_throw_decl(StandardException) {
01242                 CartesianPoint2d point;
01243                 ecl_try {
01244                         ecl::Intersection< LinearFunction > intersection;
01245                         point = intersection(f,g);
01246                 } ecl_catch( const StandardException &e ) {
01247                         ecl_throw(StandardException(LOC,e));
01248                 }
01249                 return point;
01250         }
01256         static Array<double> Roots(const LinearFunction &function) {
01257                 return ecl::Roots<LinearFunction>()(function);
01258         }
01264         static double Minimum(const double& x_begin, const double& x_end, const LinearFunction &function) {
01265                 return ecl::Minimum<LinearFunction>()(x_begin, x_end, function);
01266         }
01272         static double Maximum(const double& x_begin, const double& x_end, const LinearFunction &function) {
01273                 return ecl::Maximum<LinearFunction>()(x_begin, x_end, function);
01274         }
01275 };
01283 template <>
01284 class ECL_PUBLIC FunctionMath<QuadraticPolynomial> {
01285 public:
01286         FunctionMath() {}; 
01287         virtual ~FunctionMath() {};
01293         static Array<double> Roots(const QuadraticPolynomial &p) {
01294                 return ecl::Roots<QuadraticPolynomial>()(p);
01295         }
01299         static LinearFunction Division(const QuadraticPolynomial &p, const double &factor, double &remainder) {
01300                 LinearFunction f(ecl::Division<QuadraticPolynomial>()(p,factor,remainder));
01301                 return f;
01302         }
01303 };
01304 
01312 template <>
01313 class ECL_PUBLIC FunctionMath<CubicPolynomial> {
01314 public:
01315         FunctionMath() {}; 
01316         virtual ~FunctionMath() {};
01322         static Array<double> Roots(const CubicPolynomial &p) {
01323                 return ecl::Roots<CubicPolynomial>()(p);
01324         }
01328         static QuadraticPolynomial Division(const CubicPolynomial &p, const double &factor, double &remainder) {
01329                 QuadraticPolynomial q(ecl::Division<CubicPolynomial>()(p,factor,remainder));
01330                 return q;
01331         }
01337         static double Minimum(const double& x_begin, const double& x_end, const CubicPolynomial &function) {
01338                 return ecl::Minimum<CubicPolynomial>()(x_begin, x_end, function);
01339         }
01345         static double Maximum(const double& x_begin, const double& x_end, const CubicPolynomial &function) {
01346                 return ecl::Maximum<CubicPolynomial>()(x_begin, x_end, function);
01347         }
01348 };
01349 
01350 }; // namespace ecl
01351 
01352 #endif /*ECL_GEOMETRY_POLYNOMIALS_HPP_*/


ecl_geometry
Author(s): Daniel Stonier
autogenerated on Wed Aug 26 2015 11:27:46