poly.h

Go to the documentation of this file.
00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, 2008, 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     /** 
00475         \brief An alternative to \c gsl_poly_complex_solve_cubic()
00476         
00477         This is an alternative to the function
00478         <tt>gsl_poly_complex_solve_cubic()</tt> with some small
00479         corrections to ensure finite values for some cubics. See
00480         <tt>src/other/poly_ts.cpp</tt> for more.
00481     */
00482     int gsl_poly_complex_solve_cubic2(double a, double b, double c, 
00483                                       gsl_complex *z0, gsl_complex *z1, 
00484                                       gsl_complex *z2);
00485     
00486   };
00487 
00488   /** 
00489       \brief Solve a quartic with real coefficients and real roots (GSL)
00490   */
00491   class gsl_quartic_real : public quartic_real {
00492     
00493   public:
00494     
00495     virtual ~gsl_quartic_real() {}
00496 
00497     virtual int solve_r(const double a4, const double b4, const double c4, 
00498                         const double d4, const double e4, double &x1, 
00499                         double &x2, 
00500                         double &x3, double &x4);
00501 
00502     /// Return a string denoting the type ("gsl_quartic_real")
00503     const char *type() { return "gsl_quartic_real"; }
00504 
00505   };
00506 
00507   /** 
00508       \brief Solve a quartic with real coefficients and real roots (GSL)
00509 
00510       \todo Document the distinction between this class and
00511       \ref gsl_quartic_real
00512   */
00513   class gsl_quartic_real2 : public quartic_real {
00514 
00515   public:
00516 
00517     virtual ~gsl_quartic_real2() {}
00518 
00519     virtual int solve_r(const double a4, const double b4, const double c4, 
00520                         const double d4, const double e4, double &x1, 
00521                         double &x2, 
00522                         double &x3, double &x4);
00523 
00524     /// Return a string denoting the type ("gsl_quartic_real2")
00525     const char *type() { return "gsl_quartic_real2"; }
00526   };
00527 
00528   /** 
00529       \brief Solve a general polynomial with real coefficients (GSL)
00530   */
00531   class gsl_poly_real_coeff : public poly_real_coeff {
00532 
00533   public:
00534 
00535     gsl_poly_real_coeff();
00536 
00537     virtual ~gsl_poly_real_coeff();
00538 
00539     virtual int solve_rc(int n, const double co[], 
00540                          std::complex<double> ro[]);
00541 
00542     virtual int solve_rc(const double a3, const double b3, const double c3, 
00543                          const double d3, double &x1, 
00544                          std::complex<double> &x2, 
00545                          std::complex<double> &x3);
00546 
00547     virtual int solve_rc(const double a2, const double b2, const double c2, 
00548                          std::complex<double> &x1, 
00549                          std::complex<double> &x2);
00550 
00551     virtual int solve_rc(const double a4, const double b4, const double c4, 
00552                          const double d4, const double e4, 
00553                          std::complex<double> &x1, std::complex<double> &x2, 
00554                          std::complex<double> &x3, std::complex<double> &x4);
00555 
00556     /// Return a string denoting the type ("gsl_poly_real_coeff")
00557     const char *type() { return "gsl_poly_real_coeff"; }
00558 
00559   protected:
00560 
00561 #ifndef DOXYGEN_INTERNAL
00562 
00563     /// Workspace for quadratic polynomials
00564     gsl_poly_complex_workspace *w2;
00565 
00566     /// Workspace for cubic polynomials
00567     gsl_poly_complex_workspace *w3;
00568 
00569     /// Workspace for quartic polynomials
00570     gsl_poly_complex_workspace *w4;
00571 
00572     /// Workspace for general polynomials
00573     gsl_poly_complex_workspace *wgen;
00574 
00575     /// The size of the workspace \ref wgen
00576     int gen_size;
00577 
00578 #endif
00579 
00580   };
00581 
00582   /** 
00583       \brief Solve a quadratic with complex coefficients and complex roots
00584   */
00585   class quadratic_std_complex : public quadratic_complex {
00586 
00587   public:
00588 
00589     virtual ~quadratic_std_complex() {}
00590 
00591     virtual int solve_c(const std::complex<double> a2, 
00592                         const std::complex<double> b2, 
00593                         const std::complex<double> c2, 
00594                         std::complex<double> &x1, std::complex<double> &x2);
00595 
00596     /// Return a string denoting the type ("quadratic_std_complex")
00597     const char *type() { return "quadratic_std_complex"; }
00598   };
00599 
00600   /** 
00601       \brief Solve a cubic with complex coefficients and complex roots
00602   */
00603   class cubic_std_complex : public cubic_complex {
00604 
00605   public:
00606 
00607     virtual ~cubic_std_complex() {}
00608 
00609     virtual int solve_c(const std::complex<double> a3, 
00610                         const std::complex<double> b3, 
00611                         const std::complex<double> c3, 
00612                         const std::complex<double> d3, 
00613                         std::complex<double> &x1, std::complex<double> &x2, 
00614                         std::complex<double> &x3);
00615 
00616     /// Return a string denoting the type ("cubic_std_complex")
00617     const char *type() { return "cubic_std_complex"; }
00618   };
00619 
00620   /** 
00621       \brief Solve a quartic with real coefficients and real roots
00622       
00623       \todo 3/8/07 - Compilation at the NSCL produced non-finite values
00624       in solve_r() for some values of the coefficients. This should
00625       be checked.
00626       \todo It looks like this code is tested only for a4=1, and if 
00627       so, the tests should be generalized.
00628       \todo Also, there is a hard-coded number in here (\f$ 10^{-6} \f$),
00629       which might be moved to a data member?
00630   */
00631   class naive_quartic_real : public quartic_real {
00632 
00633   public:
00634 
00635     virtual ~naive_quartic_real() {}
00636 
00637     virtual int solve_r(const double a4, const double b4, const double c4, 
00638                         const double d4, const double e4, double &x1, 
00639                         double &x2, double &x3, double &x4);
00640 
00641     /// Return a string denoting the type ("naive_quartic_real")
00642     const char *type() { return "naive_quartic_real"; }
00643   };
00644 
00645   /** 
00646       \brief Solve a quartic with complex coefficients and complex roots
00647   */
00648   class naive_quartic_complex : public quartic_complex {
00649 
00650   public:
00651 
00652     virtual ~naive_quartic_complex() {}
00653 
00654     virtual int solve_c(const std::complex<double> a4, 
00655                         const std::complex<double> b4, 
00656                         const std::complex<double> c4, 
00657                         const std::complex<double> d4, 
00658                         const std::complex<double> e4, 
00659                         std::complex<double> &x1, 
00660                         std::complex<double> &x2, std::complex<double> &x3,
00661                         std::complex<double> &x4);
00662 
00663     /// Return a string denoting the type ("naive_quartic_complex")
00664     const char *type() { return "naive_quartic_complex"; }
00665 
00666 #ifndef DOXYGENP
00667 
00668   protected:
00669 
00670     /// The object to solve for the associated cubic
00671     cubic_std_complex cub_obj;
00672     
00673 #endif
00674 
00675   };
00676 
00677 #ifndef DOXYGENP
00678 }
00679 #endif
00680 
00681 #endif

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

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page