poly.h

Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, 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     We should 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() function,
00034     always succeeds i.e. sqrt(((complex<double>)0.0))=0.0
00035     
00036     \warning
00037     One has to be careful about using e.g. pow(a,1.0/3.0)
00038     for complex a since if Re(a)<0 and Im(a)==0 then the function 
00039     returns NaN.
00040 */
00041 
00042 #include <iostream>
00043 #include <complex>
00044 #include <gsl/gsl_math.h>
00045 #include <gsl/gsl_complex_math.h>
00046 #include <gsl/gsl_complex.h>
00047 #include <gsl/gsl_poly.h>
00048 #include <o2scl/constants.h>
00049 #include <o2scl/err_hnd.h>
00050 
00051 #ifndef DOXYGENP
00052 namespace o2scl {
00053 #endif
00054 
00055   /** 
00056       \brief Solve a quadratic polynomial with real coefficients and 
00057       real roots
00058   */
00059   class quadratic_real {
00060   public:
00061 
00062     virtual ~quadratic_real() {}
00063 
00064     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00065         giving the two solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ .
00066     */
00067     virtual int solve_r(const double a2, const double b2, const double c2, 
00068                         double &x1, double &x2) {return gsl_nobase;};
00069 
00070     /// Return a string denoting the type ("quadratic_real")
00071     const char *type() { return "quadratic_real"; }
00072   };
00073 
00074   /** 
00075       \brief Solve a quadratic polynomial with real coefficients and 
00076       complex roots
00077   */
00078   class quadratic_real_coeff : public quadratic_real {
00079 
00080   public:
00081 
00082     virtual ~quadratic_real_coeff() {}
00083 
00084     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00085         giving the two solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ .
00086     */
00087     virtual int solve_r(const double a2, const double b2, const double c2, 
00088                         double &x1, double &x2);
00089 
00090     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00091         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00092     */
00093     virtual int solve_rc(const double a2, const double b2, const double c2, 
00094                          std::complex<double> &x1, std::complex<double> &x2) 
00095       { return gsl_nobase; }
00096 
00097     /// Return a string denoting the type ("quadratic_real_coeff")
00098     const char *type() { return "quadratic_real_coeff"; }
00099   };
00100 
00101   /** 
00102       \brief Solve a quadratic polynomial with complex coefficients and 
00103       complex roots
00104   */
00105   class quadratic_complex : public quadratic_real_coeff {
00106   public:
00107 
00108     virtual ~quadratic_complex() {}
00109 
00110     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00111         giving the two solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ .
00112     */
00113     virtual int solve_r(const double a2, const double b2, const double c2, 
00114                         double &x1, double &x2);
00115 
00116     /** \brief Solves the polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00117         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00118     */
00119     virtual int solve_rc(const double a2, const double b2, const double c2, 
00120                          std::complex<double> &x1, std::complex<double> &x2);
00121 
00122     /** \brief Solves the complex polynomial \f$ a_2 x^2 + b_2 x + c_2 = 0 \f$ 
00123         giving the two complex solutions \f$ x=x_1 \f$ and \f$ x=x_2 \f$ 
00124     */
00125     virtual int solve_c(const std::complex<double> a2, 
00126                         const std::complex<double> b2, 
00127                         const std::complex<double> c2, 
00128                         std::complex<double> &x1, 
00129                         std::complex<double> &x2) { return gsl_nobase; }
00130 
00131     /// Return a string denoting the type ("quadratic_complex")
00132     const char *type() { return "quadratic_complex"; }
00133   };  
00134 
00135   /** 
00136       \brief Solve a cubic polynomial with real coefficients and real roots
00137   */
00138   class cubic_real {
00139   public:
00140 
00141     virtual ~cubic_real() {}
00142 
00143     /** \brief Solves the polynomial 
00144         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the three 
00145         solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00146     */
00147     virtual int solve_r(const double a3, const double b3, const double c3, 
00148                         const double d3, double &x1, double &x2, double &x3) 
00149       { return gsl_nobase; }
00150 
00151     /// Return a string denoting the type ("cubic_real")
00152     const char *type() { return "cubic_real"; }
00153   };
00154 
00155   /** 
00156       \brief Solve a cubic polynomial with real coefficients and complex roots
00157   */
00158   class cubic_real_coeff : public cubic_real {
00159 
00160   public:
00161 
00162     virtual ~cubic_real_coeff() {}
00163 
00164     /** \brief Solves the polynomial 
00165         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the three 
00166         solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00167     */
00168     virtual int solve_r(const double a3, const double b3, const double c3, 
00169                         const double d3, double &x1, double &x2, double &x3);
00170 
00171     /** \brief Solves the polynomial 
00172          \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ 
00173         giving the real solution \f$ x=x_1 \f$ and two complex solutions 
00174          \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00175     */
00176     virtual int solve_rc(const double a3, const double b3, const double c3, 
00177                          const double d3, double &x1, std::complex<double> &x2,
00178                          std::complex<double> &x3) { return gsl_nobase; }
00179 
00180     /// Return a string denoting the type ("cubic_real_coeff")
00181     const char *type() { return "cubic_real_coeff"; }
00182   };
00183 
00184   /** 
00185       \brief Solve a cubic polynomial with complex coefficients and 
00186       complex roots
00187   */
00188   class cubic_complex : public cubic_real_coeff {
00189 
00190   public:
00191 
00192     virtual ~cubic_complex() {}
00193 
00194     /** \brief Solves the polynomial 
00195         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the three 
00196         solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00197     */
00198     virtual int solve_r(const double a3, const double b3, const double c3, 
00199                         const double d3, double &x1, double &x2, double &x3);
00200 
00201     /** \brief Solves the polynomial 
00202         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ giving the real 
00203         solution \f$ x=x_1 \f$ and two complex solutions 
00204         \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and \f$ x=x_3 \f$ .
00205     */
00206     virtual int solve_rc(const double a3, const double b3, const double c3, 
00207                          const double d3, double &x1, std::complex<double> &x2,
00208                          std::complex<double> &x3);
00209 
00210     /** Solves the complex polynomial 
00211         \f$ a_3 x^3 + b_3 x^2 + c_3 x + d_3= 0 \f$ 
00212         giving the three complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ , and 
00213         \f$ x=x_3 \f$ .
00214     */
00215     virtual int solve_c(const std::complex<double> a3, 
00216                         const std::complex<double> b3, 
00217                         const std::complex<double> c3, 
00218                         const std::complex<double> d3, 
00219                         std::complex<double> &x1, std::complex<double> &x2, 
00220                         std::complex<double> &x3) { return gsl_nobase; }
00221 
00222     /// Return a string denoting the type ("cubic_complex")
00223     const char *type() { return "cubic_complex"; }
00224   };
00225 
00226   /** 
00227       \brief Solve a quartic polynomial with real coefficients and real roots
00228   */
00229   class quartic_real {
00230 
00231   public:
00232 
00233     virtual ~quartic_real() {}
00234     
00235     /** Solves the polynomial 
00236         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00237         giving the four solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00238         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00239     */
00240     virtual int solve_r(const double a4, const double b4, const double c4, 
00241                         const double d4, const double e4, 
00242                         double &x1, double &x2, 
00243                         double &x3, double &x4) { return gsl_nobase; }
00244 
00245     /// Return a string denoting the type ("quartic_real")
00246     const char *type() { return "quartic_real"; }
00247   };
00248 
00249   /** 
00250       \brief Solve a quartic polynomial with real coefficients and 
00251       complex roots
00252   */
00253   class quartic_real_coeff : public quartic_real {
00254 
00255   public:
00256 
00257     virtual ~quartic_real_coeff() {}
00258 
00259     /** Solves the polynomial 
00260         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00261         giving the four solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00262         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00263     */
00264     virtual int solve_r(const double a4, const double b4, const double c4, 
00265                         const double d4, const double e4, double &x1, 
00266                         double &x2, double &x3, double &x4);
00267 
00268     /**  Solves the polynomial 
00269          \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00270          giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00271          \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00272     */
00273     virtual int solve_rc(const double a4, const double b4, const double c4, 
00274                          const double d4, const double e4, 
00275                          std::complex<double> &x1, std::complex<double> &x2, 
00276                          std::complex<double> &x3, std::complex<double> &x4) 
00277       { return gsl_nobase; }
00278 
00279     /// Return a string denoting the type ("quartic_real_coeff")
00280     const char *type() { return "quartic_real_coeff"; }
00281   };
00282 
00283   /** 
00284       \brief Solve a quartic polynomial with complex coefficients and 
00285       complex roots
00286   */
00287   class quartic_complex : public quartic_real_coeff {
00288 
00289   public:
00290 
00291     virtual ~quartic_complex() {}
00292 
00293     /** Solves the polynomial 
00294         \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00295         giving the four solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00296         \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00297     */
00298     virtual int solve_r(const double a4, const double b4, const double c4, 
00299                         const double d4, const double e4, double &x1, 
00300                         double &x2, 
00301                         double &x3, double &x4);
00302 
00303     /**  Solves the polynomial 
00304          \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00305          giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00306          \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00307     */
00308     virtual int solve_rc(const double a4, const double b4, const double c4, 
00309                          const double d4, const double e4, 
00310                          std::complex<double> &x1, std::complex<double> &x2, 
00311                          std::complex<double> &x3, std::complex<double> &x4);
00312 
00313     /** Solves the complex polynomial 
00314          \f$ a_4 x^4 + b_4 x^3 + c_4 x^2 + d_4 x + e_4 = 0 \f$ 
00315         giving the four complex solutions \f$ x=x_1 \f$ , \f$ x=x_2 \f$ ,
00316          \f$ x=x_3 \f$ , and \f$ x=x_4 \f$ .
00317     */
00318     virtual int solve_c(const std::complex<double> a4, 
00319                         const std::complex<double> b4, 
00320                         const std::complex<double> c4, 
00321                         const std::complex<double> d4, 
00322                         const std::complex<double> e4, 
00323                         std::complex<double> &x1, 
00324                         std::complex<double> &x2, std::complex<double> &x3,
00325                         std::complex<double> &x4) { return gsl_nobase; }
00326 
00327     /// Return a string denoting the type ("quartic_complex")
00328     const char *type() { return "quartic_complex"; }
00329   };
00330 
00331   /** \brief Base class for solving a general polynomial with real
00332       coefficients and complex roots
00333   */
00334   class poly_real_coeff : public quadratic_real_coeff,
00335     public cubic_real_coeff, public quartic_real_coeff {
00336 
00337   public:
00338     
00339     virtual ~poly_real_coeff() {}
00340     
00341     /** 
00342         \brief Solve the n-th order polynomial
00343         
00344         The coefficients are stored in co[], with the leading coefficient
00345         as co[0] and the constant term as co[n]. The roots are returned
00346         in ro[0],...,ro[n-1].
00347     */
00348     virtual int solve_rc(int n, const double co[], 
00349                          std::complex<double> ro[]) { return gsl_nobase; }
00350 
00351     /// Polish the roots 
00352     virtual int polish_rc(int n, const double co[],
00353                           std::complex<double> *ro) { return gsl_nobase; }
00354 
00355     /// Return a string denoting the type ("poly_real_coeff")
00356     const char *type() { return "poly_real_coeff"; }
00357   };
00358 
00359   /** \brief Base class for solving a general polynomial with complex
00360       coefficients
00361   */
00362   class poly_complex : public quadratic_complex,
00363     public cubic_complex, public quartic_complex {
00364 
00365     public:
00366 
00367     virtual ~poly_complex() {}
00368     
00369     /** 
00370         \brief Solve the n-th order polynomial
00371         
00372         The coefficients are stored in co[], with the leading coefficient
00373         as co[0] and the constant term as co[n]. The roots are returned
00374         in ro[0],...,ro[n-1].
00375     */
00376     virtual int solve_c(int n, const std::complex<double> co[], 
00377                         std::complex<double> ro[]) { return gsl_nobase; }
00378     
00379     /// Polish the roots 
00380     virtual int polish_c(int n, const std::complex<double> co[],
00381                          std::complex<double> *ro) { return gsl_nobase; }
00382 
00383     /// Return a string denoting the type ("poly_complex")
00384     const char *type() { return "poly_complex"; }
00385   };
00386 
00387   /** 
00388       \brief Solve a cubic with real coefficients and complex roots (CERNLIB)
00389   */
00390   class cern_cubic_real_coeff : public cubic_real_coeff {
00391 
00392   public:
00393 
00394     virtual ~cern_cubic_real_coeff() {}
00395 
00396     virtual int solve_rc(const double a3, const double b3, const double c3, 
00397                          const double d3, double &x1, 
00398                          std::complex<double> &x2, std::complex<double> &x3);
00399 
00400     /// The original CERNLIB interface
00401     virtual int rrteq3(double r, double s, double t, double x[], double &d);
00402 
00403     /// Return a string denoting the type ("cern_cubic_real_coeff")
00404     const char *type() { return "cern_cubic_real_coeff"; }
00405   };
00406 
00407   /** 
00408       \brief Solve a quartic with real coefficients and complex roots (CERNLIB)
00409   */
00410   class cern_quartic_real_coeff : public quartic_real_coeff {
00411 
00412   public:
00413 
00414     virtual ~cern_quartic_real_coeff() {}
00415 
00416     virtual int solve_rc(const double a4, const double b4, const double c4, 
00417                          const double d4, const double e4, 
00418                          std::complex<double> &x1, std::complex<double> &x2, 
00419                          std::complex<double> &x3, std::complex<double> &x4);
00420 
00421     /// The original CERNLIB interface
00422     virtual int rrteq4(double a, double b, double c, double d, 
00423                        std::complex<double> z[], double &dc, 
00424                        int &mt);
00425 
00426     /// Return a string denoting the type ("cern_quartic_real_coeff")
00427     const char *type() { return "cern_quartic_real_coeff"; }
00428 
00429 #ifndef DOXYGEN_INTERNAL
00430 
00431   protected:
00432 
00433     /// The object to solve for the associated cubic
00434     cern_cubic_real_coeff cub_obj;
00435 
00436 #endif
00437 
00438   };
00439 
00440   /** 
00441       \brief Solve a quadratic with real coefficients and complex roots (GSL)
00442   */
00443   class gsl_quadratic_real_coeff : public quadratic_real_coeff {
00444 
00445   public:
00446 
00447     virtual ~gsl_quadratic_real_coeff() {}
00448 
00449     virtual int solve_rc(const double a2, const double b2, const double c2, 
00450                          std::complex<double> &x1, std::complex<double> &x2);
00451 
00452     /// Return a string denoting the type ("gsl_quadratic_real_coeff")
00453     const char *type() { return "gsl_quadratic_real_coeff"; }
00454 
00455   };
00456 
00457   /** 
00458       \brief Solve a cubic with real coefficients and complex roots (GSL)
00459   */
00460   class gsl_cubic_real_coeff : public cubic_real_coeff {
00461 
00462   public:
00463 
00464     virtual ~gsl_cubic_real_coeff() {}
00465 
00466     virtual int solve_rc(const double a3, const double b3, const double c3, 
00467                          const double d3, double &x1, 
00468                          std::complex<double> &x2, 
00469                          std::complex<double> &x3);
00470 
00471     /// Return a string denoting the type ("gsl_cubic_real_coeff")
00472     const char *type() { return "gsl_cubic_real_coeff"; }
00473 
00474 #ifndef DOXYGEN_INTERNAL
00475 
00476   protected:
00477 
00478   /** 
00479       \brief An alternative to \c gsl_poly_complex_solve_cubic()
00480 
00481       This is an alternative to the function \c
00482       gsl_poly_complex_solve_cubic() with some small corrections.
00483       
00484       \todo Demonstrate that this works 
00485       better than the original GSL version.
00486    */
00487   int gsl_poly_complex_solve_cubic2(double a, double b, double c, 
00488                                     gsl_complex *z0, gsl_complex *z1, 
00489                                     gsl_complex *z2);
00490 
00491 #endif
00492   
00493   };
00494 
00495   /** 
00496       \brief Solve a quartic with real coefficients and real roots (GSL)
00497   */
00498   class gsl_quartic_real : public quartic_real {
00499     
00500   public:
00501     
00502     virtual ~gsl_quartic_real() {}
00503 
00504     virtual int solve_r(const double a4, const double b4, const double c4, 
00505                         const double d4, const double e4, double &x1, 
00506                         double &x2, 
00507                         double &x3, double &x4);
00508 
00509     /// Return a string denoting the type ("gsl_quartic_real")
00510     const char *type() { return "gsl_quartic_real"; }
00511 
00512   };
00513 
00514   /** 
00515       \brief Solve a quartic with real coefficients and real roots (GSL)
00516 
00517       \todo Document the distinction between this class and
00518       \ref gsl_quartic_real
00519   */
00520   class gsl_quartic_real2 : public quartic_real {
00521 
00522   public:
00523 
00524     virtual ~gsl_quartic_real2() {}
00525 
00526     virtual int solve_r(const double a4, const double b4, const double c4, 
00527                         const double d4, const double e4, double &x1, 
00528                         double &x2, 
00529                         double &x3, double &x4);
00530 
00531     /// Return a string denoting the type ("gsl_quartic_real2")
00532     const char *type() { return "gsl_quartic_real2"; }
00533   };
00534 
00535   /** 
00536       \brief Solve a general polynomial with real coefficients (GSL)
00537   */
00538   class gsl_poly_real_coeff : public poly_real_coeff {
00539 
00540   public:
00541 
00542     gsl_poly_real_coeff();
00543 
00544     virtual ~gsl_poly_real_coeff();
00545 
00546     virtual int solve_rc(int n, const double co[], 
00547                          std::complex<double> ro[]);
00548 
00549     virtual int solve_rc(const double a3, const double b3, const double c3, 
00550                          const double d3, double &x1, 
00551                          std::complex<double> &x2, 
00552                          std::complex<double> &x3);
00553 
00554     virtual int solve_rc(const double a2, const double b2, const double c2, 
00555                          std::complex<double> &x1, 
00556                          std::complex<double> &x2);
00557 
00558     virtual int solve_rc(const double a4, const double b4, const double c4, 
00559                          const double d4, const double e4, 
00560                          std::complex<double> &x1, std::complex<double> &x2, 
00561                          std::complex<double> &x3, std::complex<double> &x4);
00562 
00563     /// Return a string denoting the type ("gsl_poly_real_coeff")
00564     const char *type() { return "gsl_poly_real_coeff"; }
00565 
00566   protected:
00567 
00568 #ifndef DOXYGEN_INTERNAL
00569 
00570     // Workspace for quadratic polynomials
00571     gsl_poly_complex_workspace *w2;
00572 
00573     // Workspace for cubic polynomials
00574     gsl_poly_complex_workspace *w3;
00575 
00576     // Workspace for quartic polynomials
00577     gsl_poly_complex_workspace *w4;
00578 
00579     // Workspace for general polynomials
00580     gsl_poly_complex_workspace *wgen;
00581 
00582     /// The size of the workspace \ref wgen
00583     int gen_size;
00584 
00585 #endif
00586 
00587   };
00588 
00589   /** 
00590       \brief Solve a quadratic with complex coefficients and complex roots
00591   */
00592   class quadratic_std_complex : public quadratic_complex {
00593 
00594   public:
00595 
00596     virtual ~quadratic_std_complex() {}
00597 
00598     virtual int solve_c(const std::complex<double> a2, 
00599                         const std::complex<double> b2, 
00600                         const std::complex<double> c2, 
00601                         std::complex<double> &x1, std::complex<double> &x2);
00602 
00603     /// Return a string denoting the type ("quadratic_std_complex")
00604     const char *type() { return "quadratic_std_complex"; }
00605   };
00606 
00607   /** 
00608       \brief Solve a cubic with complex coefficients and complex roots
00609   */
00610   class cubic_std_complex : public cubic_complex {
00611 
00612   public:
00613 
00614     virtual ~cubic_std_complex() {}
00615 
00616     virtual int solve_c(const std::complex<double> a3, 
00617                         const std::complex<double> b3, 
00618                         const std::complex<double> c3, 
00619                         const std::complex<double> d3, 
00620                         std::complex<double> &x1, std::complex<double> &x2, 
00621                         std::complex<double> &x3);
00622 
00623     /// Return a string denoting the type ("cubic_std_complex")
00624     const char *type() { return "cubic_std_complex"; }
00625   };
00626 
00627   /** 
00628       \brief Solve a quartic with real coefficients and real roots
00629       
00630       \todo 3/8/07 - Compilation at the NSCL produced non-finite values
00631       in solve_r() for some values of the coefficients. This should
00632       be checked.
00633       \todo It looks like this code is tested only for a4=1, and if 
00634       so, the tests should be generalized.
00635       \todo Also, there is a hard-coded number in here (\f$ 10^{-6} \f$),
00636       which might be moved to a data member?
00637   */
00638   class naive_quartic_real : public quartic_real {
00639 
00640   public:
00641 
00642     virtual ~naive_quartic_real() {}
00643 
00644     virtual int solve_r(const double a4, const double b4, const double c4, 
00645                         const double d4, const double e4, double &x1, 
00646                         double &x2, double &x3, double &x4);
00647 
00648     /// Return a string denoting the type ("naive_quartic_real")
00649     const char *type() { return "naive_quartic_real"; }
00650   };
00651 
00652   /** 
00653       \brief Solve a quartic with complex coefficients and complex roots
00654   */
00655   class naive_quartic_complex : public quartic_complex {
00656 
00657   public:
00658 
00659     virtual ~naive_quartic_complex() {}
00660 
00661     virtual int solve_c(const std::complex<double> a4, 
00662                         const std::complex<double> b4, 
00663                         const std::complex<double> c4, 
00664                         const std::complex<double> d4, 
00665                         const std::complex<double> e4, 
00666                         std::complex<double> &x1, 
00667                         std::complex<double> &x2, std::complex<double> &x3,
00668                         std::complex<double> &x4);
00669 
00670     /// Return a string denoting the type ("naive_quartic_complex")
00671     const char *type() { return "naive_quartic_complex"; }
00672 
00673 #ifndef DOXYGENP
00674 
00675   protected:
00676 
00677     /// The object to solve for the associated cubic
00678     cubic_std_complex cub_obj;
00679     
00680 #endif
00681 
00682   };
00683 
00684 #ifndef DOXYGENP
00685 }
00686 #endif
00687 
00688 #endif

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.