core/vnl/algo/vnl_rpoly_roots.h
Go to the documentation of this file.
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_