Wm4Eigen.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 WM4EIGEN_H
00018 #define WM4EIGEN_H
00019 
00020 #include "Wm4FoundationLIB.h"
00021 #include "Wm4Matrix2.h"
00022 #include "Wm4Matrix3.h"
00023 #include "Wm4Matrix4.h"
00024 #include "Wm4GMatrix.h"
00025 
00026 namespace Wm4
00027 {
00028 
00029 template <class Real>
00030 class WM4_FOUNDATION_ITEM Eigen
00031 {
00032 public:
00033     Eigen (int iSize);
00034     Eigen (const Matrix2<Real>& rkM);
00035     Eigen (const Matrix3<Real>& rkM);
00036     Eigen (const GMatrix<Real>& rkM);
00037     ~Eigen ();
00038 
00039     // set the matrix for eigensolving
00040     Real& operator() (int iRow, int iCol);
00041     Eigen& operator= (const Matrix2<Real>& rkM);
00042     Eigen& operator= (const Matrix3<Real>& rkM);
00043     Eigen& operator= (const GMatrix<Real>& rkM);
00044 
00045     // Get the eigenresults (eigenvectors are columns of eigenmatrix).  The
00046     // GetEigenvector calls involving Vector2 and Vector3 should only be
00047     // called if you know that the eigenmatrix is of the appropriate size.
00048     Real GetEigenvalue (int i) const;
00049     const Real* GetEigenvalues () const;
00050     void GetEigenvector (int i, Vector2<Real>& rkV) const;
00051     void GetEigenvector (int i, Vector3<Real>& rkV) const;
00052     GVector<Real> GetEigenvector (int i) const;
00053     const GMatrix<Real>& GetEigenvectors () const;
00054 
00055     // solve eigensystem
00056     void EigenStuff2 ();
00057     void EigenStuff3 ();
00058     void EigenStuffN ();
00059     void EigenStuff  ();
00060 
00061     // solve eigensystem, use decreasing sort on eigenvalues
00062     void DecrSortEigenStuff2 ();
00063     void DecrSortEigenStuff3 ();
00064     void DecrSortEigenStuffN ();
00065     void DecrSortEigenStuff  ();
00066 
00067     // solve eigensystem, use increasing sort on eigenvalues
00068     void IncrSortEigenStuff2 ();
00069     void IncrSortEigenStuff3 ();
00070     void IncrSortEigenStuffN ();
00071     void IncrSortEigenStuff  ();
00072 
00073 private:
00074     int m_iSize;
00075     GMatrix<Real> m_kMat;
00076     Real* m_afDiag;
00077     Real* m_afSubd;
00078 
00079     // For odd size matrices, the Householder reduction involves an odd
00080     // number of reflections.  The product of these is a reflection.  The
00081     // QL algorithm uses rotations for further reductions.  The final
00082     // orthogonal matrix whose columns are the eigenvectors is a reflection,
00083     // so its determinant is -1.  For even size matrices, the Householder
00084     // reduction involves an even number of reflections whose product is a
00085     // rotation.  The final orthogonal matrix has determinant +1.  Many
00086     // algorithms that need an eigendecomposition want a rotation matrix.
00087     // We want to guarantee this is the case, so m_bRotation keeps track of
00088     // this.  The DecrSort and IncrSort further complicate the issue since
00089     // they swap columns of the orthogonal matrix, causing the matrix to
00090     // toggle between rotation and reflection.  The value m_bRotation must
00091     // be toggled accordingly.
00092     bool m_bIsRotation;
00093     void GuaranteeRotation ();
00094 
00095     // Householder reduction to tridiagonal form
00096     void Tridiagonal2 ();
00097     void Tridiagonal3 ();
00098     void TridiagonalN ();
00099 
00100     // QL algorithm with implicit shifting, applies to tridiagonal matrices
00101     bool QLAlgorithm ();
00102 
00103     // sort eigenvalues from largest to smallest
00104     void DecreasingSort ();
00105 
00106     // sort eigenvalues from smallest to largest
00107     void IncreasingSort ();
00108 };
00109 
00110 typedef Eigen<float> Eigenf;
00111 typedef Eigen<double> Eigend;
00112 
00113 }
00114 
00115 #endif

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