00001 // This is core/vnl/algo/vnl_rpoly_roots.h 00002 #ifndef vnl_rpoly_roots_h_ 00003 #define vnl_rpoly_roots_h_ 00004 #ifdef VCL_NEEDS_PRAGMA_INTERFACE 00005 #pragma interface 00006 #endif 00007 //: 00008 // \file 00009 // \brief Finds roots of a real polynomial 00010 // \author Andrew W. Fitzgibbon, Oxford RRG 00011 // \date 06 Aug 96 00012 // 00013 // \verbatim 00014 // Modifications 00015 // 23 may 97, Peter Vanroose - "NO_COMPLEX" option added (until "complex" type is standardised) 00016 // dac (Manchester) 28/03/2001: tidied up documentation 00017 // Joris Van den Wyngaerd - June 2001 - impl for vnl_real_polynomial constr added 00018 // Feb.2002 - Peter Vanroose - brief doxygen comment placed on single line 00019 // \endverbatim 00020 00021 #include <vcl_complex.h> 00022 #include <vnl/vnl_vector.h> 00023 00024 class vnl_real_polynomial; 00025 00026 //: Find the roots of a real polynomial. 00027 // Uses algorithm 493 from 00028 // ACM Trans. Math. Software - the Jenkins-Traub algorithm, described 00029 // by Numerical Recipes under "Other sure-fire techniques" as 00030 // "practically a standard in black-box polynomial rootfinders". 00031 // (See M.A. Jenkins, ACM TOMS 1 (1975) pp. 178-189.). 00032 // 00033 // This class is not very const-correct as it is intended as a compute object 00034 // rather than a data object. 00035 00036 class vnl_rpoly_roots 00037 { 00038 public: 00039 // Constructors/Destructors-------------------------------------------------- 00040 00041 //: The constructor calculates the roots. 00042 // This is the most efficient interface 00043 // as all the result variables are initialized to the correct size. 00044 // The polynomial is $ a[0] x^d + a[1] x^{d-1} + \cdots + a[d] = 0 $. 00045 // 00046 // Note that if the routine fails, not all roots will be found. In this case, 00047 // the "realroots" and "roots" functions will return fewer than n roots. 00048 00049 vnl_rpoly_roots(const vnl_vector<double>& a); 00050 00051 //: Calculate roots of a vnl_real_polynomial. Same comments apply. 00052 vnl_rpoly_roots(const vnl_real_polynomial& poly); 00053 00054 // Operations---------------------------------------------------------------- 00055 00056 //: Return i'th complex root 00057 vcl_complex<double> operator [] (int i) const { return vcl_complex<double>(r_[i], i_[i]); } 00058 00059 //: Complex vector of all roots. 00060 vnl_vector<vcl_complex<double> > roots() const; 00061 00062 //: Real part of root I. 00063 const double& real(int i) const { return r_[i]; } 00064 00065 //: Imaginary part of root I. 00066 const double& imag(int i) const { return i_[i]; } 00067 00068 //: Vector of real parts of roots 00069 vnl_vector<double>& real() { return r_; } 00070 00071 //: Vector of imaginary parts of roots 00072 vnl_vector<double>& imag() { return i_; } 00073 00074 //: Return real roots only. 00075 // Roots are real if the absolute value of their imaginary part is less than 00076 // the optional argument TOL. TOL defaults to 1e-12 [untested] 00077 vnl_vector<double> realroots(double tol = 1e-12) const; 00078 00079 // Computations-------------------------------------------------------------- 00080 00081 //: Compute roots using Jenkins-Traub algorithm. 00082 bool compute(); 00083 00084 //: Compute roots using QR decomposition of companion matrix. [unimplemented] 00085 bool compute_qr(); 00086 00087 //: Compute roots using Laguerre algorithm. [unimplemented] 00088 bool compute_laguerre(); 00089 00090 protected: 00091 // Data Members-------------------------------------------------------------- 00092 vnl_vector<double> coeffs_; 00093 00094 vnl_vector<double> r_; 00095 vnl_vector<double> i_; 00096 00097 int num_roots_found_; 00098 }; 00099 00100 #endif // vnl_rpoly_roots_h_