Wm4PolynomialRoots.h

Go to the documentation of this file.
00001 // Wild Magic Source Code
00002 // David Eberly
00003 // http://www.geometrictools.com
00004 // Copyright (c) 1998-2007
00005 //
00006 // This library is free software; you can redistribute it and/or modify it
00007 // under the terms of the GNU Lesser General Public License as published by
00008 // the Free Software Foundation; either version 2.1 of the License, or (at
00009 // your option) any later version.  The license is available for reading at
00010 // either of the locations:
00011 //     http://www.gnu.org/copyleft/lgpl.html
00012 //     http://www.geometrictools.com/License/WildMagicLicense.pdf
00013 // The license applies to versions 0 through 4 of Wild Magic.
00014 //
00015 // Version: 4.0.0 (2006/06/28)
00016 
00017 #ifndef WM4POLYNOMIALROOTS_H
00018 #define WM4POLYNOMIALROOTS_H
00019 
00020 #include "Wm4FoundationLIB.h"
00021 #include "Wm4GMatrix.h"
00022 #include "Wm4Vector3.h"
00023 #include "Wm4Polynomial1.h"
00024 
00025 namespace Wm4
00026 {
00027 
00028 // Methods are
00029 //
00030 // A: algebraic using closed-form expressions (fast, typically not robust)
00031 // B: bisection (after root bounding, slow and robust)
00032 // N: Newton's/bisection hybrid (after root bounding, medium and robust)
00033 // E: eigenvalues of a companion matrix (fast and robust)
00034 
00035 // Root bounds:
00036 //
00037 // For a monic polynomial
00038 //   x^n + a[n-1]*x^{n-1} + ... + a[1]*x + a[0]
00039 // the Cauchy bound is
00040 //   M = 1 + max{|a[0]|,...,|a[n-1]|}.
00041 // All real-value roots must lie in the interval [-M,M].  For a non-monic
00042 // polynomial,
00043 //   b[n]*x^n + b[n-1]*x^{n-1} + ... + b[1]*x + b[0],
00044 // if b[n] is not zero, divide through by it and calculate Cauchy's
00045 // bound:
00046 //   1 + max{|b[0]/b[n]|,...,|b[n-1]/b[n]|}.
00047 
00048 template <class Real>
00049 class WM4_FOUNDATION_ITEM PolynomialRoots
00050 {
00051 public:
00052     // construction and destruction
00053     PolynomialRoots (Real fEpsilon);
00054     ~PolynomialRoots ();
00055 
00056     // member access
00057     int GetCount () const;
00058     const Real* GetRoots () const;
00059     Real GetRoot (int i) const;
00060     Real& Epsilon ();
00061     Real Epsilon () const;
00062 
00063     // for FindE functions, default is 128
00064     int& MaxIterations ();
00065     int MaxIterations () const;
00066 
00067     // linear equations:  c1*x+c0 = 0
00068     bool FindA (Real fC0, Real fC1);
00069     Real GetBound (Real fC0, Real fC1);
00070 
00071     // quadratic equations: c2*x^2+c1*x+c0 = 0
00072     bool FindA (Real fC0, Real fC1, Real fC2);
00073     Real GetBound (Real fC0, Real fC1, Real fC2);
00074 
00075     // cubic equations: c3*x^3+c2*x^2+c1*x+c0 = 0
00076     bool FindA (Real fC0, Real fC1, Real fC2, Real fC3);
00077     bool FindE (Real fC0, Real fC1, Real fC2, Real fC3, bool bDoBalancing);
00078     Real GetBound (Real fC0, Real fC1, Real fC2, Real fC3);
00079 
00080     // Solve A*r^3 + B*r = C where A > 0 and B > 0.  This equation always has
00081     // exactly one root.
00082     Real SpecialCubic (Real fA, Real fB, Real fC);
00083 
00084     // quartic equations: c4*x^4+c3*x^3+c2*x^2+c1*x+c0 = 0
00085     bool FindA (Real fC0, Real fC1, Real fC2, Real fC3, Real fC4);
00086     bool FindE (Real fC0, Real fC1, Real fC2, Real fC3, Real fC4,
00087         bool bDoBalancing);
00088     Real GetBound (Real fC0, Real fC1, Real fC2, Real fC3, Real fC4);
00089 
00090     // general equations: sum_{i=0}^{degree} c(i)*x^i = 0
00091     bool FindB (const Polynomial1<Real>& rkPoly, int iDigits);
00092     bool FindN (const Polynomial1<Real>& rkPoly, int iDigits);
00093     bool FindE (const Polynomial1<Real>& rkPoly, bool bDoBalancing);
00094     Real GetBound (const Polynomial1<Real>& rkPoly);
00095 
00096     // find roots on specified intervals
00097     bool FindB (const Polynomial1<Real>& rkPoly, Real fXMin, Real fXMax,
00098         int iDigits);
00099 
00100     bool FindN (const Polynomial1<Real>& rkPoly, Real fXMin, Real fXMax,
00101         int iDigits);
00102 
00103     bool AllRealPartsNegative (const Polynomial1<Real>& rkPoly);
00104     bool AllRealPartsPositive (const Polynomial1<Real>& rkPoly);
00105 
00106     // Count the number of roots on [t0,t1].  Uses Sturm sequences to do the
00107     // counting.  It is allowed to pass in t0 = -Math<Real>::MAX_REAL or
00108     // t1 = Math<Real>::MAX_REAL.  The value of m_fEpsilon is used as a
00109     // threshold on the value of a Sturm polynomial at an end point.  If
00110     // smaller, that value is assumed to be zero.  The return value is the
00111     // number of roots.  If there are infinitely many, -1 is returned.
00112     int GetRootCount (const Polynomial1<Real>& rkPoly, Real fT0, Real fT1);
00113 
00114 private:
00115     // support for FindB
00116     bool Bisection (const Polynomial1<Real>& rkPoly, Real fXMin, Real fXMax,
00117         int iDigitsAccuracy, Real& rfRoot);
00118 
00119     // support for FindE
00120     void GetHouseholderVector (int iSize, const Vector3<Real>& rkU,
00121         Vector3<Real>& rkV);
00122 
00123     void PremultiplyHouseholder (GMatrix<Real>& rkMat, GVector<Real>& rkW,
00124         int iRMin, int iRMax, int iCMin, int iCMax, int iVSize,
00125         const Vector3<Real>& rkV);
00126 
00127     void PostmultiplyHouseholder (GMatrix<Real>& rkMat, GVector<Real>& rkW,
00128         int iRMin, int iRMax, int iCMin, int iCMax, int iVSize,
00129         const Vector3<Real>& rkV);
00130 
00131     void FrancisQRStep (GMatrix<Real>& rkH, GVector<Real>& rkW);
00132 
00133     Real GetRowNorm (int iRow, GMatrix<Real>& rkMat);
00134     Real GetColNorm (int iCol, GMatrix<Real>& rkMat);
00135     void ScaleRow (int iRow, Real fScale, GMatrix<Real>& rkMat);
00136     void ScaleCol (int iCol, Real fScale, GMatrix<Real>& rkMat);
00137     void Balance3 (GMatrix<Real>& rkMat);
00138     bool IsBalanced3 (GMatrix<Real>& rkMat);
00139     void BalanceCompanion3 (GMatrix<Real>& rkMat);
00140     bool IsBalancedCompanion3 (Real fA10, Real fA21, Real fA02, Real fA12,
00141         Real fA22);
00142     bool QRIteration3 (GMatrix<Real>& rkMat);
00143 
00144     void BalanceCompanion4 (GMatrix<Real>& rkMat);
00145     bool IsBalancedCompanion4 (Real fA10, Real fA21, Real fA32, Real fA03,
00146         Real fA13, Real fA23, Real fA33);
00147     bool QRIteration4 (GMatrix<Real>& rkMat);
00148 
00149     // support for testing if all roots have negative real parts
00150     bool AllRealPartsNegative (int iDegree, Real* afCoeff);
00151 
00152 
00153     Real m_fEpsilon;
00154     int m_iCount, m_iMaxRoot;
00155     Real* m_afRoot;
00156     int m_iMaxIterations;
00157 };
00158 
00159 typedef PolynomialRoots<float> PolynomialRootsf;
00160 typedef PolynomialRoots<double> PolynomialRootsd;
00161 
00162 }
00163 
00164 #endif

Generated on Wed Nov 23 19:01:07 2011 for FreeCAD by  doxygen 1.6.1