Object-oriented Scientific Computing Library: Version 0.910
poly.h
Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006-2012, Andrew W. Steiner
00005   
00006   This file is part of O2scl.
00007   
00008   O2scl is free software; you can redistribute it and/or modify
00009   it under the terms of the GNU General Public License as published by
00010   the Free Software Foundation; either version 3 of the License, or
00011   (at your option) any later version.
00012   
00013   O2scl 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
00016   GNU General Public License for more details.
00017   
00018   You should have received a copy of the GNU General Public License
00019   along with O2scl. If not, see <http://www.gnu.org/licenses/>.
00020 
00021   -------------------------------------------------------------------
00022 */
00023 #ifndef O2SCL_POLY_H
00024 #define O2SCL_POLY_H
00025 
00026 /** \file poly.h
00027     \brief Classes for solving polynomials
00028 
00029     \warning 
00030     One must be careful about using pow() in functions using
00031     complex<double> since pow(((complex<double>)0.0),3.0) returns
00032     (nan,nan). Instead, we should use pow(((complex<double>)0.0),3)
00033     which takes an integer for the second argument. The sqrt()
00034     function, always succeeds i.e. sqrt(((complex<double>)0.0))=0.0
00035 
00036     \future The quartics are tested only for a4=1, which should
00037     probably be generalized.
00038     
00039 */
00040 
00041 #include <iostream>
00042 #include <complex>
00043 #include <gsl/gsl_math.h>
00044 #include <gsl/gsl_complex_math.h>
00045 #include <gsl/gsl_complex.h>
00046 #include <gsl/gsl_poly.h>
00047 #include <o2scl/constants.h>
00048 #include <o2scl/err_hnd.h>
00049 
00050 #ifndef DOXYGENP
00051 namespace o2scl {
00052 #endif
00053 
00054   /** \brief Solve a quadratic polynomial with real coefficients and 
00055       real roots [abstract base]
00056   */
00057   class quadratic_real {
00058   public:
00059 
00060     virtual ~quadratic_real() {}
00061 
00062     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00063         giving the two solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ .
00064     */
00065     virtual int solve_r(const double a2, const double b2, const double c2, 
00066                         double &x1, double &x2)=0;
00067 
00068     /// Return a string denoting the type ("quadratic_real")
00069     const char *type() { return "quadratic_real"; }
00070   };
00071 
00072   /** \brief Solve a quadratic polynomial with real coefficients and 
00073       complex roots [abstract base]
00074   */
00075   class quadratic_real_coeff : public quadratic_real {
00076 
00077   public:
00078 
00079     virtual ~quadratic_real_coeff() {}
00080 
00081     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00082         giving the two solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ .
00083     */
00084     virtual int solve_r(const double a2, const double b2, const double c2, 
00085                         double &x1, double &x2);
00086 
00087     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00088         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00089     */
00090     virtual int solve_rc(const double a2, const double b2, const double c2, 
00091                          std::complex<double> &x1, 
00092                          std::complex<double> &x2)=0;
00093 
00094     /// Return a string denoting the type ("quadratic_real_coeff")
00095     const char *type() { return "quadratic_real_coeff"; }
00096   };
00097 
00098   /** \brief Solve a quadratic polynomial with complex coefficients and 
00099       complex roots [abstract base]
00100   */
00101   class quadratic_complex : public quadratic_real_coeff {
00102   public:
00103 
00104     virtual ~quadratic_complex() {}
00105 
00106     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00107         giving the two solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ .
00108     */
00109     virtual int solve_r(const double a2, const double b2, const double c2, 
00110                         double &x1, double &x2);
00111 
00112     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00113         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00114     */
00115     virtual int solve_rc(const double a2, const double b2, const double c2, 
00116                          std::complex<double> &x1, std::complex<double> &x2);
00117 
00118     /** \brief Solves the complex polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00119         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00120     */
00121     virtual int solve_c(const std::complex<double> a2, 
00122                         const std::complex<double> b2, 
00123                         const std::complex<double> c2, 
00124                         std::complex<double> &x1, std::complex<double> &x2)=0;
00125 
00126     /// Return a string denoting the type ("quadratic_complex")
00127     const char *type() { return "quadratic_complex"; }
00128   };  
00129 
00130   /** \brief Solve a cubic polynomial with real coefficients and real roots
00131       [abstract base]
00132   */
00133   class cubic_real {
00134   public:
00135 
00136     virtual ~cubic_real() {}
00137 
00138     /** \brief Solves the polynomial 
00139         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the three 
00140         solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00141     */
00142     virtual int solve_r(const double a3, const double b3, const double c3, 
00143                         const double d3, double &x1, double &x2, 
00144                         double &x3)=0;
00145 
00146     /// Return a string denoting the type ("cubic_real")
00147     const char *type() { return "cubic_real"; }
00148   };
00149 
00150   /** \brief Solve a cubic polynomial with real coefficients and 
00151       complex roots [abstract base]
00152   */
00153   class cubic_real_coeff : public cubic_real {
00154 
00155   public:
00156 
00157     virtual ~cubic_real_coeff() {}
00158 
00159     /** \brief Solves the polynomial 
00160         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the three 
00161         solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00162     */
00163     virtual int solve_r(const double a3, const double b3, const double c3, 
00164                         const double d3, double &x1, double &x2, double &x3);
00165 
00166     /** \brief Solves the polynomial 
00167         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ 
00168         giving the real solution \f$ x=x_1 \f$ and two complex solutions 
00169         \f$ x=x_2 \f$ and \f$ x=x_3 \f$ .
00170     */
00171     virtual int solve_rc(const double a3, const double b3, const double c3, 
00172                          const double d3, double &x1, std::complex<double> &x2,
00173                          std::complex<double> &x3)=0;
00174 
00175     /// Return a string denoting the type ("cubic_real_coeff")
00176     const char *type() { return "cubic_real_coeff"; }
00177   };
00178 
00179   /** \brief Solve a cubic polynomial with complex coefficients and 
00180       complex roots [abstract base]
00181   */
00182   class cubic_complex : public cubic_real_coeff {
00183 
00184   public:
00185 
00186     virtual ~cubic_complex() {}
00187 
00188     /** \brief Solves the polynomial 
00189         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the three 
00190         solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00191     */
00192     virtual int solve_r(const double a3, const double b3, const double c3, 
00193                         const double d3, double &x1, double &x2, double &x3);
00194 
00195     /** \brief Solves the polynomial 
00196         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the real 
00197         solution \f$ x=x_1 \f$ and two complex solutions 
00198         \f$ x=x_2 \f$ and \f$ x=x_3 \f$ .
00199     */
00200     virtual int solve_rc(const double a3, const double b3, const double c3, 
00201                          const double d3, double &x1, std::complex<double> &x2,
00202                          std::complex<double> &x3);
00203     
00204     /** \brief Solves the complex polynomial 
00205         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ 
00206         giving the three complex solutions \f$ x=x_1 \f$ , 
00207         \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00208     */
00209     virtual int solve_c(const std::complex<double> a3, 
00210                         const std::complex<double> b3, 
00211                         const std::complex<double> c3, 
00212                         const std::complex<double> d3, 
00213                         std::complex<double> &x1, std::complex<double> &x2, 
00214                         std::complex<double> &x3)=0;
00215 
00216     /// Return a string denoting the type ("cubic_complex")
00217     const char *type() { return "cubic_complex"; }
00218   };
00219 
00220   /** \brief Solve a quartic polynomial with real coefficients and 
00221       real roots [abstract base]
00222   */
00223   class quartic_real {
00224 
00225   public:
00226 
00227     virtual ~quartic_real() {}
00228     
00229     /** \brief Solves the polynomial 
00230         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00231         giving the four solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00232         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00233     */
00234     virtual int solve_r(const double a4, const double b4, const double c4, 
00235                         const double d4, const double e4, 
00236                         double &x1, double &x2, 
00237                         double &x3, double &x4)=0;
00238 
00239     /// Return a string denoting the type ("quartic_real")
00240     const char *type() { return "quartic_real"; }
00241   };
00242 
00243   /** \brief Solve a quartic polynomial with real coefficients and 
00244       complex roots [abstract base]
00245   */
00246   class quartic_real_coeff : public quartic_real {
00247 
00248   public:
00249 
00250     virtual ~quartic_real_coeff() {}
00251 
00252     /** \brief Solves the polynomial 
00253         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00254         giving the four solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00255         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00256     */
00257     virtual int solve_r(const double a4, const double b4, const double c4, 
00258                         const double d4, const double e4, double &x1, 
00259                         double &x2, double &x3, double &x4);
00260 
00261     /**  \brief Solves the polynomial 
00262          \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00263          giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00264          \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00265     */
00266     virtual int solve_rc(const double a4, const double b4, const double c4, 
00267                          const double d4, const double e4, 
00268                          std::complex<double> &x1, std::complex<double> &x2, 
00269                          std::complex<double> &x3, 
00270                          std::complex<double> &x4)=0;
00271 
00272     /// Return a string denoting the type ("quartic_real_coeff")
00273     const char *type() { return "quartic_real_coeff"; }
00274   };
00275 
00276   /** \brief Solve a quartic polynomial with complex coefficients and 
00277       complex roots [abstract base]
00278   */
00279   class quartic_complex : public quartic_real_coeff {
00280 
00281   public:
00282 
00283     virtual ~quartic_complex() {}
00284 
00285     /** \brief Solves the polynomial 
00286         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00287         giving the four solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00288         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00289     */
00290     virtual int solve_r(const double a4, const double b4, const double c4, 
00291                         const double d4, const double e4, double &x1, 
00292                         double &x2, 
00293                         double &x3, double &x4);
00294 
00295     /**  \brief Solves the polynomial 
00296          \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00297          giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00298          \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00299     */
00300     virtual int solve_rc(const double a4, const double b4, const double c4, 
00301                          const double d4, const double e4, 
00302                          std::complex<double> &x1, std::complex<double> &x2, 
00303                          std::complex<double> &x3, std::complex<double> &x4);
00304 
00305     /** \brief Solves the complex polynomial 
00306         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00307         giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00308         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00309     */
00310     virtual int solve_c(const std::complex<double> a4, 
00311                         const std::complex<double> b4, 
00312                         const std::complex<double> c4, 
00313                         const std::complex<double> d4, 
00314                         const std::complex<double> e4, 
00315                         std::complex<double> &x1, 
00316                         std::complex<double> &x2, std::complex<double> &x3,
00317                         std::complex<double> &x4)=0;
00318 
00319     /// Return a string denoting the type ("quartic_complex")
00320     const char *type() { return "quartic_complex"; }
00321   };
00322 
00323   /** \brief Solve a general polynomial with real
00324       coefficients and complex roots [abstract base]
00325   */
00326   class poly_real_coeff : public quadratic_real_coeff,
00327     public cubic_real_coeff, public quartic_real_coeff {
00328 
00329   public:
00330     
00331     virtual ~poly_real_coeff() {}
00332     
00333     /** \brief Solve the n-th order polynomial
00334         
00335         The coefficients are stored in co[], with the leading coefficient
00336         as co[0] and the constant term as co[n]. The roots are returned
00337         in ro[0],...,ro[n-1].
00338     */
00339     virtual int solve_rc(int n, const double co[], 
00340                          std::complex<double> ro[])=0;
00341 
00342     /// Return a string denoting the type ("poly_real_coeff")
00343     const char *type() { return "poly_real_coeff"; }
00344   };
00345 
00346   /** \brief Solve a general polynomial with complex
00347       coefficients [abstract base]
00348   */
00349   class poly_complex : public quadratic_complex,
00350     public cubic_complex, public quartic_complex {
00351 
00352   public:
00353 
00354     virtual ~poly_complex() {}
00355     
00356     /** \brief Solve the n-th order polynomial
00357         
00358         The coefficients are stored in co[], with the leading coefficient
00359         as co[0] and the constant term as co[n]. The roots are returned
00360         in ro[0],...,ro[n-1].
00361     */
00362     virtual int solve_c(int n, const std::complex<double> co[], 
00363                         std::complex<double> ro[])=0;
00364     
00365     /// Polish the roots 
00366     virtual int polish_c(int n, const std::complex<double> co[],
00367                          std::complex<double> *ro)=0;
00368 
00369     /// Return a string denoting the type ("poly_complex")
00370     const char *type() { return "poly_complex"; }
00371   };
00372 
00373   /** \brief Solve a cubic with real coefficients and complex roots 
00374       (CERNLIB)
00375 
00376       \note The function rrteq3() is based on the CERNLIB routine of
00377       the same name, but differs slightly. See the documtation of
00378       that function for details.
00379   */
00380   class cern_cubic_real_coeff : public cubic_real_coeff {
00381 
00382   public:
00383 
00384     cern_cubic_real_coeff() {
00385       eps=1.0e-6;
00386       delta=1.0e-15;
00387       improve_scale=true;
00388     }
00389 
00390     /// Numerical tolerance (default \f$ 10^{-6} \f$)
00391     double eps;
00392 
00393     /// Numerical tolerance (default \f$ 10^{-15} \f$)
00394     double delta;
00395 
00396     /// Improve algorithm for poorly-scaled roots (default true)
00397     bool improve_scale;
00398 
00399     virtual ~cern_cubic_real_coeff() {}
00400 
00401     /** \brief Solves the polynomial 
00402         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the real 
00403         solution \f$ x=x_1 \f$ and two complex solutions 
00404         \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00405     */
00406     virtual int solve_rc(const double a3, const double b3, const double c3, 
00407                          const double d3, double &x1, 
00408                          std::complex<double> &x2, std::complex<double> &x3);
00409 
00410     /** \brief The CERNLIB-like interface
00411 
00412         This function computes the roots of the cubic equation
00413         \f[
00414         x^3 + r x^2 + s x + t =0
00415         \f]
00416         returning the value of the discriminant in \c d and the roots
00417         in the array \c x. If the discriminant is negative, then all
00418         three real roots are stored in \c x. Otherwise, the real root
00419         is stored in <tt>x[0]</tt> and the real and imaginary parts of
00420         the complex conjugate roots are stored in <tt>x[1]</tt> and
00421         <tt>x[2]</tt>, respectively. This differs from the CERNLIB
00422         routine where the results were stored in <tt>x[1]</tt>,
00423         <tt>x[2]</tt>, and <tt>x[3]</tt> instead.
00424         
00425         Another small change is that the discriminant for the
00426         resolvent cubic is evaluated slightly differently in order to
00427         improve the properties in the case where the roots are not all
00428         of order unity. The default CERNLIB behavior can be restored
00429         by setting improve_scale to \c false.
00430     */  
00431     virtual int rrteq3(double r, double s, double t, double x[], double &d);
00432 
00433     /// Return a string denoting the type ("cern_cubic_real_coeff")
00434     const char *type() { return "cern_cubic_real_coeff"; }
00435   };
00436 
00437   /** \brief Solve a quartic with real coefficients and complex 
00438       roots (CERNLIB)
00439   */
00440   class cern_quartic_real_coeff : public quartic_real_coeff {
00441 
00442   public:
00443 
00444     virtual ~cern_quartic_real_coeff() {}
00445 
00446     /** \brief Solves the polynomial \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 +
00447         d_4 x + e_4= 0 \f$ giving the four complex solutions \f$ x=x_1
00448         \f$ , \f$ x=x_2 \f$ , \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00449     */
00450     virtual int solve_rc(const double a4, const double b4, const double c4, 
00451                          const double d4, const double e4, 
00452                          std::complex<double> &x1, std::complex<double> &x2, 
00453                          std::complex<double> &x3, std::complex<double> &x4);
00454 
00455     /// The CERNLIB-like interface
00456     virtual int rrteq4(double a, double b, double c, double d, 
00457                        std::complex<double> z[], double &dc, 
00458                        int &mt);
00459 
00460     /// Return a string denoting the type ("cern_quartic_real_coeff")
00461     const char *type() { return "cern_quartic_real_coeff"; }
00462 
00463 #ifndef DOXYGEN_INTERNAL
00464 
00465   protected:
00466 
00467     /// The object to solve for the associated cubic
00468     cern_cubic_real_coeff cub_obj;
00469 
00470 #endif
00471 
00472   };
00473 
00474   /** \brief Solve a quadratic with real coefficients and complex roots (GSL)
00475    */
00476   class gsl_quadratic_real_coeff : public quadratic_real_coeff {
00477 
00478   public:
00479 
00480     virtual ~gsl_quadratic_real_coeff() {}
00481 
00482     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00483         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00484     */
00485     virtual int solve_rc(const double a2, const double b2, const double c2, 
00486                          std::complex<double> &x1, std::complex<double> &x2);
00487 
00488     /// Return a string denoting the type ("gsl_quadratic_real_coeff")
00489     const char *type() { return "gsl_quadratic_real_coeff"; }
00490 
00491   };
00492 
00493   /** \brief Solve a cubic with real coefficients and complex roots (GSL)
00494    */
00495   class gsl_cubic_real_coeff : public cubic_real_coeff {
00496 
00497   public:
00498 
00499     virtual ~gsl_cubic_real_coeff() {}
00500 
00501     /** \brief Solves the polynomial 
00502         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ 
00503         giving the real solution \f$ x=x_1 \f$ and two complex solutions 
00504         \f$ x=x_2 \f$ and \f$ x=x_3 \f$ .
00505     */
00506     virtual int solve_rc(const double a3, const double b3, const double c3, 
00507                          const double d3, double &x1, 
00508                          std::complex<double> &x2, std::complex<double> &x3);
00509 
00510     /// Return a string denoting the type ("gsl_cubic_real_coeff")
00511     const char *type() { return "gsl_cubic_real_coeff"; }
00512 
00513     /** \brief An alternative to \c gsl_poly_complex_solve_cubic()
00514         
00515         This is an alternative to the function
00516         <tt>gsl_poly_complex_solve_cubic()</tt> with some small
00517         corrections to ensure finite values for some cubics. See
00518         <tt>src/other/poly_ts.cpp</tt> for more.
00519 
00520         \future I think the GSL function is now fixed, so we
00521         can fall back to the original GSL function here. 
00522     */
00523     int gsl_poly_complex_solve_cubic2(double a, double b, double c, 
00524                                       gsl_complex *z0, gsl_complex *z1, 
00525                                       gsl_complex *z2);
00526     
00527   };
00528 
00529   /** \brief Solve a quartic with real coefficients and real roots (GSL)
00530 
00531       This class internally uses the GSL functions to solve the
00532       resolvent cubic and associated quadratics, while
00533       \ref gsl_quartic_real2 contains explicit code to solve
00534       them instead.
00535 
00536       \future Optimize value of \c cube_root_tol and compare
00537       more clearly to \ref gsl_quartic_real2
00538   */
00539   class gsl_quartic_real : public quartic_real {
00540     
00541   public:
00542     
00543     gsl_quartic_real() {
00544       cube_root_tol=1.0e-7;
00545     }
00546 
00547     virtual ~gsl_quartic_real() {}
00548 
00549     /** \brief A tolerance for determining the proper cube root 
00550         (default \f$ 10^{-4} \f$ )
00551     */
00552     double cube_root_tol;
00553 
00554     /** \brief Solves the polynomial \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 +
00555         d_4 x + e_4= 0 \f$ giving the four real solutions \f$ x=x_1
00556         \f$ , \f$ x=x_2 \f$ , \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00557     */
00558     virtual int solve_r(const double a4, const double b4, const double c4, 
00559                         const double d4, const double e4, double &x1, 
00560                         double &x2, double &x3, double &x4);
00561 
00562     /// Return a string denoting the type ("gsl_quartic_real")
00563     const char *type() { return "gsl_quartic_real"; }
00564 
00565   };
00566 
00567   /** \brief Solve a quartic with real coefficients and real roots (GSL)
00568 
00569       This class directly solves 
00570       resolvent cubic and associated quadratics without using 
00571       the GSL functions (as done in \ref gsl_quartic_real).
00572       
00573       \future Optimize value of \c cube_root_tol and compare
00574       more clearly to \ref gsl_quartic_real
00575   */
00576   class gsl_quartic_real2 : public quartic_real {
00577 
00578   public:
00579 
00580     gsl_quartic_real2() {
00581       cube_root_tol=1.0e-7;
00582     }
00583 
00584     virtual ~gsl_quartic_real2() {}
00585 
00586     /** \brief A tolerance for determining the proper cube root 
00587         (default \f$ 10^{-7} \f$ )
00588     */
00589     double cube_root_tol;
00590 
00591     /** \brief Solves the polynomial \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 +
00592         d_4 x + e_4= 0 \f$ giving the four real solutions \f$ x=x_1
00593         \f$ , \f$ x=x_2 \f$ , \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00594     */
00595     virtual int solve_r(const double a4, const double b4, const double c4, 
00596                         const double d4, const double e4, double &x1, 
00597                         double &x2, 
00598                         double &x3, double &x4);
00599 
00600     /// Return a string denoting the type ("gsl_quartic_real2")
00601     const char *type() { return "gsl_quartic_real2"; }
00602   };
00603 
00604   /** \brief Solve a general polynomial with real coefficients (GSL)
00605    */
00606   class gsl_poly_real_coeff : public poly_real_coeff {
00607 
00608   public:
00609 
00610     gsl_poly_real_coeff();
00611 
00612     virtual ~gsl_poly_real_coeff();
00613 
00614     /** \brief Solve a generic polynomial given <tt>n+1</tt> coefficients
00615 
00616         \note In order to be consistent with the other solve_rc()
00617         functions, the ordering of the coefficients is reversed with
00618         respect to gsl_poly_complex_solve(). The leading coefficient
00619         is stored in <tt>co[0]</tt> and the constant term is stored in
00620         <tt>co[n]</tt>.
00621      */
00622     virtual int solve_rc(int n, const double co[], 
00623                          std::complex<double> ro[]);
00624 
00625     /** \brief Solve a cubic polynomial with real coefficients
00626      */
00627     virtual int solve_rc(const double a3, const double b3, const double c3, 
00628                          const double d3, double &x1, 
00629                          std::complex<double> &x2, 
00630                          std::complex<double> &x3);
00631 
00632     /** \brief Solve a quadratic polynomial with real coefficients
00633      */
00634     virtual int solve_rc(const double a2, const double b2, const double c2, 
00635                          std::complex<double> &x1, 
00636                          std::complex<double> &x2);
00637 
00638     /** \brief Solve a quartic polynomial with real coefficients
00639      */
00640     virtual int solve_rc(const double a4, const double b4, const double c4, 
00641                          const double d4, const double e4, 
00642                          std::complex<double> &x1, std::complex<double> &x2, 
00643                          std::complex<double> &x3, std::complex<double> &x4);
00644 
00645     /// Return a string denoting the type ("gsl_poly_real_coeff")
00646     const char *type() { return "gsl_poly_real_coeff"; }
00647 
00648   protected:
00649 
00650 #ifndef DOXYGEN_INTERNAL
00651 
00652     /// Workspace for quadratic polynomials
00653     gsl_poly_complex_workspace *w2;
00654 
00655     /// Workspace for cubic polynomials
00656     gsl_poly_complex_workspace *w3;
00657 
00658     /// Workspace for quartic polynomials
00659     gsl_poly_complex_workspace *w4;
00660 
00661     /// Workspace for general polynomials
00662     gsl_poly_complex_workspace *wgen;
00663 
00664     /// The size of the workspace \ref wgen
00665     int gen_size;
00666 
00667 #endif
00668 
00669   };
00670 
00671   /** \brief Solve a quadratic with complex coefficients and complex roots
00672    */
00673   class quadratic_std_complex : public quadratic_complex {
00674 
00675   public:
00676 
00677     virtual ~quadratic_std_complex() {}
00678 
00679     /** \brief Solves the complex polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00680         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00681     */
00682     virtual int solve_c(const std::complex<double> a2, 
00683                         const std::complex<double> b2, 
00684                         const std::complex<double> c2, 
00685                         std::complex<double> &x1, std::complex<double> &x2);
00686 
00687     /// Return a string denoting the type ("quadratic_std_complex")
00688     const char *type() { return "quadratic_std_complex"; }
00689   };
00690 
00691   /** \brief Solve a cubic with complex coefficients and complex roots
00692    */
00693   class cubic_std_complex : public cubic_complex {
00694 
00695   public:
00696 
00697     virtual ~cubic_std_complex() {}
00698 
00699     /** \brief Solves the complex polynomial 
00700         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ 
00701         giving the three complex solutions \f$ x=x_1 \f$ , 
00702         \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00703     */
00704     virtual int solve_c(const std::complex<double> a3, 
00705                         const std::complex<double> b3, 
00706                         const std::complex<double> c3, 
00707                         const std::complex<double> d3, 
00708                         std::complex<double> &x1, std::complex<double> &x2, 
00709                         std::complex<double> &x3);
00710 
00711     /// Return a string denoting the type ("cubic_std_complex")
00712     const char *type() { return "cubic_std_complex"; }
00713   };
00714 
00715   /** \brief Solve a quartic with real coefficients and real roots
00716    */
00717   class simple_quartic_real : public quartic_real {
00718 
00719   public:
00720 
00721     simple_quartic_real() {
00722       cube_root_tol=1.0e-6;
00723     }
00724 
00725     virtual ~simple_quartic_real() {}
00726 
00727     virtual int solve_r(const double a4, const double b4, const double c4, 
00728                         const double d4, const double e4, double &x1, 
00729                         double &x2, double &x3, double &x4);
00730 
00731     /// Return a string denoting the type ("simple_quartic_real")
00732     const char *type() { return "simple_quartic_real"; }
00733 
00734     /** \brief A tolerance for determining the proper cube root 
00735         (default \f$ 10^{-6} \f$ )
00736     */
00737     double cube_root_tol;
00738   };
00739   
00740   /** \brief Solve a quartic with complex coefficients and complex roots
00741    */
00742   class simple_quartic_complex : public quartic_complex {
00743 
00744   public:
00745 
00746     virtual ~simple_quartic_complex() {}
00747 
00748     /** \brief Solves the complex polynomial 
00749         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00750         giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00751         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00752     */
00753     virtual int solve_c(const std::complex<double> a4, 
00754                         const std::complex<double> b4, 
00755                         const std::complex<double> c4, 
00756                         const std::complex<double> d4, 
00757                         const std::complex<double> e4, 
00758                         std::complex<double> &x1, 
00759                         std::complex<double> &x2, 
00760                         std::complex<double> &x3,
00761                         std::complex<double> &x4);
00762 
00763     /// Return a string denoting the type ("simple_quartic_complex")
00764     const char *type() { return "simple_quartic_complex"; }
00765 
00766 #ifndef DOXYGENP
00767 
00768   protected:
00769 
00770     /// The object to solve for the associated cubic
00771     cubic_std_complex cub_obj;
00772     
00773 #endif
00774 
00775   };
00776 
00777 #ifndef DOXYGENP
00778 }
00779 #endif
00780 
00781 #endif
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.