00001 // @(#)root/mathmore:$Id: Polynomial.h 37160 2010-12-01 21:52:04Z moneta $ 00002 // Authors: L. Moneta, A. Zsenei 08/2005 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT * 00007 * * 00008 * This library is free software; you can redistribute it and/or * 00009 * modify it under the terms of the GNU General Public License * 00010 * as published by the Free Software Foundation; either version 2 * 00011 * of the License, or (at your option) any later version. * 00012 * * 00013 * This library is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00016 * General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this library (see file COPYING); if not, write * 00020 * to the Free Software Foundation, Inc., 59 Temple Place, Suite * 00021 * 330, Boston, MA 02111-1307 USA, or contact the author. * 00022 * * 00023 **********************************************************************/ 00024 00025 // Header file for class Polynomial 00026 // 00027 // Created by: Lorenzo Moneta at Wed Nov 10 17:46:19 2004 00028 // 00029 // Last update: Wed Nov 10 17:46:19 2004 00030 // 00031 #ifndef ROOT_Math_Polynomial 00032 #define ROOT_Math_Polynomial 00033 00034 #include <complex> 00035 00036 #include "Math/ParamFunction.h" 00037 00038 // #ifdef _WIN32 00039 // #pragma warning(disable : 4250) 00040 // #endif 00041 00042 namespace ROOT { 00043 namespace Math { 00044 00045 //_____________________________________________________________________________________ 00046 /** 00047 Parametric Function class describing polynomials of order n. 00048 00049 <em>P(x) = p[0] + p[1]*x + p[2]*x**2 + ....... + p[n]*x**n</em> 00050 00051 The class implements also the derivatives, \a dP(x)/dx and the \a dP(x)/dp[i]. 00052 00053 The class provides also the method to find the roots of the polynomial. 00054 It uses analytical methods up to quartic polynomials. 00055 00056 Implements both the Parameteric function interface and the gradient interface 00057 since it provides the analytical gradient with respect to x 00058 00059 00060 @ingroup ParamFunc 00061 */ 00062 00063 class Polynomial : public ParamFunction<IParamGradFunction>, 00064 public IGradientOneDim 00065 { 00066 00067 00068 public: 00069 00070 typedef ParamFunction<IParamGradFunction> ParFunc; 00071 /** 00072 Construct a Polynomial function of order n. 00073 The number of Parameters is n+1. 00074 */ 00075 00076 Polynomial(unsigned int n = 0); 00077 00078 /** 00079 Construct a Polynomial of degree 1 : a*x + b 00080 */ 00081 Polynomial(double a, double b); 00082 00083 /** 00084 Construct a Polynomial of degree 2 : a*x**2 + b*x + c 00085 */ 00086 Polynomial(double a, double b, double c); 00087 00088 /** 00089 Construct a Polynomial of degree 3 : a*x**3 + b*x**2 + c*x + d 00090 */ 00091 Polynomial(double a, double b, double c, double d); 00092 00093 /** 00094 Construct a Polynomial of degree 4 : a*x**4 + b*x**3 + c*x**2 + dx + e 00095 */ 00096 Polynomial(double a, double b, double c, double d, double e); 00097 00098 00099 virtual ~Polynomial() {} 00100 00101 // use default copy-ctor and assignment operators 00102 00103 00104 00105 // using ParamFunction::operator(); 00106 00107 00108 /** 00109 Find the polynomial roots. 00110 For n <= 4, the roots are found analytically while for larger order an iterative numerical method is used 00111 The numerical method used is from GSL (see <A HREF="http://www.gnu.org/software/gsl/manual/gsl-ref_6.html#SEC53" ) 00112 */ 00113 const std::vector<std::complex <double> > & FindRoots(); 00114 00115 00116 /** 00117 Find the only the real polynomial roots. 00118 For n <= 4, the roots are found analytically while for larger order an iterative numerical method is used 00119 The numerical method used is from GSL (see <A HREF="http://www.gnu.org/software/gsl/manual/gsl-ref_6.html#SEC53" ) 00120 */ 00121 std::vector<double > FindRealRoots(); 00122 00123 00124 /** 00125 Find the polynomial roots using always an iterative numerical methods 00126 The numerical method used is from GSL (see <A HREF="http://www.gnu.org/software/gsl/manual/gsl-ref_6.html#SEC53" ) 00127 */ 00128 const std::vector<std::complex <double> > & FindNumRoots(); 00129 00130 /** 00131 Order of Polynomial 00132 */ 00133 unsigned int Order() const { return fOrder; } 00134 00135 00136 IGenFunction * Clone() const; 00137 00138 /** 00139 Optimized method to evaluate at the same time the function value and derivative at a point x. 00140 Implement the interface specified bby ROOT::Math::IGradientOneDim. 00141 In the case of polynomial there is no advantage to compute both at the same time 00142 */ 00143 void FdF (double x, double & f, double & df) const { 00144 f = (*this)(x); 00145 df = Derivative(x); 00146 } 00147 00148 00149 private: 00150 00151 double DoEvalPar ( double x, const double * p ) const ; 00152 00153 double DoDerivative (double x) const ; 00154 00155 double DoParameterDerivative(double x, const double * p, unsigned int ipar) const; 00156 00157 00158 // cache order = number of params - 1) 00159 unsigned int fOrder; 00160 00161 // cache Parameters for Gradient 00162 mutable std::vector<double> fDerived_params; 00163 00164 // roots 00165 00166 std::vector< std::complex < double > > fRoots; 00167 00168 }; 00169 00170 } // namespace Math 00171 } // namespace ROOT 00172 00173 00174 #endif /* ROOT_Math_Polynomial */