LTI-Lib latest version v1.9 - last update 10 Apr 2010

ltiFastEigenSystem.h

00001 /*
00002  * Copyright (C) 2002, 2003, 2004, 2005, 2006
00003  * Lehrstuhl fuer Technische Informatik, RWTH-Aachen, Germany
00004  *
00005  * This file is part of the LTI-Computer Vision Library (LTI-Lib)
00006  *
00007  * The LTI-Lib is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License (LGPL)
00009  * as published by the Free Software Foundation; either version 2.1 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * The LTI-Lib is distributed in the hope that it will be
00013  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
00014  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU Lesser General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with the LTI-Lib; see the file LICENSE.  If
00019  * not, write to the Free Software Foundation, Inc., 59 Temple Place -
00020  * Suite 330, Boston, MA 02111-1307, USA.
00021  */
00022 
00023 
00024 /*----------------------------------------------------------------
00025  * project ....: LTI Digital Image/Signal Processing Library
00026  * file .......: ltiFastEigenSystem.h
00027  * authors ....: Peter Doerfler
00028  * organization: LTI, RWTH Aachen
00029  * creation ...: 12.04.02
00030  * revisions ..: $Id: ltiFastEigenSystem.h,v 1.7 2006/09/11 17:02:29 ltilib Exp $
00031  */
00032 
00033 #ifndef _LTI_FAST_EIGEN_SYSTEM_H_
00034 #define _LTI_FAST_EIGEN_SYSTEM_H_
00035 
00036 #include "ltiLapackInterface.h"
00037 
00038 #ifdef HAVE_LAPACK
00039 
00040 #include "ltiEigenSystem.h"
00041 
00042 namespace lti {
00043   /**
00044    * A fast LAPACK-based method for computation of (some) eigenvector
00045    * and eigenvalues. Depending on the parameters useRRR (relatively
00046    * robust representation), either xSYEVR (true) or xSYEVX (false)
00047    * are used. The latter is default since RRR goes into infinite
00048    * loops for some data. \b Note however that switching useRRR to
00049    * true is usually much faster (a simple test yielded 25% speed-up).
00050    *
00051    * Part of the man page of xSYEVR:
00052    *
00053    * DSYEVR (SSYEVR) computes selected eigenvalues and, optionally,
00054    * eigenvectors of a real symmetric tridiagonal matrix T.
00055    * Eigenvalues and eigenvectors can be selected by specifying either
00056    * a range of values or a range of indices for the desired
00057    * eigenvalues.
00058    *
00059    * Whenever possible, DSYEVR calls DSTEGR to compute the
00060    * eigenspectrum using Relatively Robust Representations.  DSTEGR
00061    * computes eigenvalues by the dqds algorithm, while orthogonal
00062    * eigenvectors are com­ puted from various "good" L D L^T
00063    * representations (also known as Relatively Robust
00064    * Representations). Gram-Schmidt orthogonalization is avoided as
00065    * far as possible.  More specifically, the various steps of the
00066    * algorithm are as fol­ lows. For the i-th unreduced block of T,
00067    *
00068    * (a) Compute T - sigma_i = L_i D_i L_i^T, such that L_i D_i L_i^T
00069    *     is a relatively robust representation,
00070    *
00071    * (b) Compute the eigenvalues, lambda_j, of L_i D_i L_i^T to
00072    *     high relative accuracy by the dqds algorithm,
00073    *
00074    * (c) If there is a cluster of close eigenvalues,
00075    *     "choose" sigma_i close to the cluster, and go to step (a),
00076    *
00077    * (d) Given the approximate eigenvalue lambda_j of
00078    *     L_i D_i L_i^T, compute the corresponding eigenvector by
00079    *     forming a rank-revealing twisted factorization.
00080    *
00081    * The desired accuracy of the output can be specified by the input
00082    * parameter ABSTOL.
00083    *
00084    * For more details, see "A new O(n^2) algorithm for the symmetric
00085    * tridiagonal eigenvalue/eigenvector problem", by Inderjit Dhillon,
00086    * Computer Science Division Technical Report No. UCB//CSD-97-971,
00087    * UC Berkeley, May 1997.
00088    *
00089    *
00090    * Part of the man page of xSYEVX:
00091    *
00092    * SSYEVX computes selected eigenvalues and, optionally, eigenvectors
00093    * of a real symmetric matrix A.  Eigenvalues and eigenvectors can be
00094    * selected by specifying either a range of values or a range of indices
00095    * for the desired eigenvalues.
00096    *
00097    * @ingroup lapack
00098    *
00099    * @see \ref lapack
00100    */
00101   template<class T>
00102   class fastEigenSystem : public eigenSystem<T>, lapackInterface {
00103   public:
00104     /**
00105      * eigenSystem parameter class
00106      */
00107     class parameters : public eigenSystem<T>::parameters {
00108     public:
00109       /**
00110        * default constructor
00111        */
00112       parameters()
00113         : eigenSystem<T>::parameters(),dimensions(0), useRRR(false) {
00114       };
00115 
00116       /**
00117        * copy constructor
00118        */
00119       parameters(const parameters& other) {
00120         copy(other);
00121       };
00122 
00123       /**
00124        * number of dimensions calculated. The default is zero. In this
00125        * case, all eigenvectors and eigenvalues are calculated.
00126        */
00127       int dimensions;
00128 
00129       /**
00130        * use relatively robust representation (RRR i.e. xSYEVR) or not
00131        * (i.e. xSYEVX)
00132        *
00133        * Default: false
00134        */
00135       bool useRRR;
00136 
00137       /**
00138        * returns the name of this type
00139        */
00140       virtual const char* getTypeName() const {
00141         return "fastEigenSystem::parameters";
00142       };
00143 
00144       /**
00145        * copy member.
00146        */
00147       parameters& copy(const parameters& other) {
00148 #ifndef _LTI_MSC_6
00149         // MS Visual C++ 6 is not able to compile this...
00150         eigenSystem<T>::parameters::copy(other);
00151 #else
00152         // ...so we have to use this workaround.
00153         // Conditional on that, copy may not be virtual.
00154         eigenSystem<T>::parameters&
00155           (eigenSystem<T>::parameters::* p_copy)(const eigenSystem<T>::parameters&) =
00156           eigenSystem<T>::parameters::copy;
00157         (this->*p_copy)(other);
00158 #endif
00159         dimensions = other.dimensions;
00160         useRRR     = other.useRRR; 
00161 
00162         return (*this);
00163       };
00164 
00165       /**
00166        * returns a pointer to a clone of the parameters.
00167        */
00168       virtual functor::parameters* clone() const {
00169         return (new parameters(*this));
00170       };
00171     };
00172 
00173     /**
00174      * default constructor
00175      */
00176     fastEigenSystem();
00177 
00178     /**
00179      * constructor, sets the parameters
00180      */
00181     fastEigenSystem(const parameters& theParams);
00182 
00183     /**
00184      * constructor, sets the parameters
00185      */
00186     fastEigenSystem(const int dimensions);
00187 
00188     /**
00189      * destructor
00190      */
00191     virtual ~fastEigenSystem();
00192 
00193     /**
00194      * returns the current parameters.
00195      */
00196     const parameters& getParameters() const;
00197 
00198     /**
00199      * clone this functor
00200      */
00201     virtual functor* clone() const;
00202 
00203     /**
00204      * Computes eigenvalues and eigenvectors of the given matrix. The
00205      * functor can efficiently calculate only a few dimensions of the
00206      * eigenspace, taking those with the largest eigenvalues. The
00207      * number of dimensions is set with parameters::dimensions.
00208      *
00209      * @param theMatrix    matrix whose eigenvectors are to be computed
00210      * @param eigenvalues  elements will contain the eigenvalues
00211      * @param eigenvectors columns will contain the  eigenvectors
00212      *                     corresponding to the eigenvalues
00213      */
00214     virtual bool apply(const matrix<T>& theMatrix,
00215                        vector<T>& eigenvalues,
00216                        matrix<T>& eigenvectors) const;
00217 
00218 
00219     /**
00220      * returns the name of this type
00221      */
00222     virtual const char* getTypeName() const {
00223       return "fastEigenSystem";
00224     };
00225 
00226   private:
00227     // lapack routine in template form
00228 
00229     int evr(char* jobz, char* range, char* uplo,
00230             integer* n, T* a, integer* lda,
00231             T* vl, T* vu,
00232             integer* il, integer* iu,
00233             T* abstol,
00234             integer* m, T* w,
00235             T* z, integer* ldz, integer* isuppz,
00236             T* work, integer* lwork,
00237             integer* iwork, integer* liwork,
00238             integer* info) const;
00239 
00240     int evx(char* jobz, char* range, char* uplo,
00241             integer* n, T* a, integer* lda,
00242             T* vl, T* vu,
00243             integer* il, integer* iu,
00244             T* abstol,
00245             integer* m, T* w,
00246             T* z, integer* ldz,
00247             T* work, integer* lwork,
00248             integer* iwork, integer* ifail,
00249             integer* info) const;
00250 
00251   };
00252 
00253 }
00254 
00255 #endif
00256 #endif

Generated on Sat Apr 10 15:25:27 2010 for LTI-Lib by Doxygen 1.6.1