![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
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
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).