latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 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 .......: ltiFastGeneralizedEigenSystem.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 08.05.2003 00030 * revisions ..: $Id: ltiFastGeneralizedEigenSystem.h,v 1.7 2006/09/11 17:02:58 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_FAST_GENERALIZED_EIGEN_SYSTEM_H_ 00034 #define _LTI_FAST_GENERALIZED_EIGEN_SYSTEM_H_ 00035 00036 #include "ltiLapackInterface.h" 00037 00038 #ifdef HAVE_LAPACK 00039 00040 #include "ltiGeneralizedEigenSystem.h" 00041 00042 namespace lti { 00043 /** 00044 * Computes all the eigenvalues, and optionally, the eigenvectors 00045 * of a real generalized symmetric-definite eigenproblem, of the form 00046 * A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. 00047 * Here A and B are assumed to be symmetric and B is also 00048 * positive definite. 00049 * 00050 * The type of problem as stated above can be selected via 00051 * parameters::problemType. When all eigenvalues/eigenvectors are 00052 * needed you can select the divide and conquer algorithm by setting 00053 * parameters::useDC to true (_SYGVD instead of _SYGV). If only the 00054 * n most significant eigenvalues/eigenvectors are needed set 00055 * parameters::dimensions to n. The LAPACK routine _SYGVX is used. 00056 * 00057 * Divide and conquer is usually faster especially for large 00058 * matrices but also uses more workspace. 00059 * 00060 * @ingroup lapack 00061 * 00062 * @see \ref lapack 00063 */ 00064 template<class T> 00065 class fastGeneralizedEigenSystem : public generalizedEigenSystem<T>, lapackInterface { 00066 public: 00067 /** 00068 * parameter class for fastGeneralizedEigenSystem 00069 */ 00070 class parameters : public generalizedEigenSystem<T>::parameters { 00071 public: 00072 00073 /** 00074 * Defines different problem types for the generalized eigen system. 00075 */ 00076 enum eProblemType { 00077 Type1 = 1, /*!< A*x = lambda*B*x */ 00078 Type2, /*!< A*B*x = lambda*x */ 00079 Type3 /*!< B*A*x = lambda*x */ 00080 }; 00081 00082 /** 00083 * default constructor 00084 */ 00085 parameters() 00086 : generalizedEigenSystem<T>::parameters(),useDC(true) { 00087 problemType=Type1; 00088 }; 00089 00090 /** 00091 * copy constructor 00092 */ 00093 parameters(const parameters& other) { 00094 copy(other); 00095 }; 00096 00097 /** 00098 * the problem type to be solved. Default is Type1. 00099 */ 00100 eProblemType problemType; 00101 00102 /** 00103 * If true the divide-and-conquer method for calculating the SVD 00104 * is used. This is generally faster, especially on large 00105 * matrices. However, it uses more temporary memory than the 00106 * simple method. Thus, if the computation fails due to memory 00107 * problems setting this parameter to false might solve the 00108 * problem. Default is true. 00109 * 00110 * \b Note: If dimensions is unequal to zero, ie not all 00111 * eigenvalues/vectors are calculated this option is not 00112 * available and internally set to false. 00113 */ 00114 bool useDC; 00115 00116 /** 00117 * returns the name of this type 00118 */ 00119 virtual const char* getTypeName() const { 00120 return "fastGeneralizedEigenSystem::parameters"; 00121 }; 00122 00123 /** 00124 * copy member. 00125 */ 00126 parameters& copy(const parameters& other) { 00127 #ifndef _LTI_MSC_6 00128 // MS Visual C++ 6 is not able to compile this... 00129 generalizedEigenSystem<T>::parameters::copy(other); 00130 #else 00131 // ...so we have to use this workaround. 00132 // Conditional on that, copy may not be virtual. 00133 generalizedEigenSystem<T>::parameters& 00134 (generalizedEigenSystem<T>::parameters::* p_copy)(const generalizedEigenSystem<T>::parameters&) = 00135 generalizedEigenSystem<T>::parameters::copy; 00136 (this->*p_copy)(other); 00137 #endif 00138 useDC=other.useDC; 00139 problemType=other.problemType; 00140 00141 00142 return (*this); 00143 }; 00144 00145 /** 00146 * returns a pointer to a clone of the parameters. 00147 */ 00148 virtual functor::parameters* clone() const { 00149 return (new parameters(*this)); 00150 }; 00151 }; 00152 00153 /** 00154 * default constructor 00155 */ 00156 fastGeneralizedEigenSystem(); 00157 00158 /** 00159 * constructor, sets the parameters 00160 */ 00161 fastGeneralizedEigenSystem(const parameters& theParams); 00162 00163 /** 00164 * constructor, sets the parameters 00165 */ 00166 fastGeneralizedEigenSystem(const int dimensions); 00167 00168 /** 00169 * destructor 00170 */ 00171 virtual ~fastGeneralizedEigenSystem(); 00172 00173 /** 00174 * returns the current parameters. 00175 */ 00176 const parameters& getParameters() const; 00177 00178 /** 00179 * clone this functor 00180 */ 00181 virtual functor* clone() const; 00182 00183 /** 00184 * Computes eigenvalues and eigenvectors of the given matrix. The 00185 * functor can efficiently calculate only a few dimensions of the 00186 * eigenspace, taking those with the largest eigenvalues. The 00187 * number of dimensions is set with parameters::dimensions. 00188 * 00189 * @param a the symmetric matrix A 00190 * @param b the symmetric, positive definite matrix B 00191 * @param eigenvalues elements will contain the eigenvalues 00192 * @param eigenvectors columns will contain the eigenvectors 00193 * corresponding to the eigenvalues 00194 */ 00195 virtual bool apply(const matrix<T>& a, 00196 const matrix<T>& b, 00197 vector<T>& eigenvalues, 00198 matrix<T>& eigenvectors) const; 00199 00200 /** 00201 * Computes eigenvalues and eigenvectors of the given matrix. The 00202 * functor can efficiently calculate only a few dimensions of the 00203 * eigenspace, taking those with the largest eigenvalues. The 00204 * number of dimensions is set with parameters::dimensions. 00205 * 00206 * @param a the symmetric matrix A 00207 * @param b the symmetric, positive definite matrix B 00208 * @param eigenvalues elements will contain the eigenvalues 00209 */ 00210 virtual bool apply(const matrix<T>& a, 00211 const matrix<T>& b, 00212 vector<T>& eigenvalues) const; 00213 00214 00215 /** 00216 * returns the name of this type 00217 */ 00218 virtual const char* getTypeName() const { 00219 return "fastGeneralizedEigenSystem"; 00220 }; 00221 00222 private: 00223 // lapack routines in template form 00224 00225 int sygv(integer* itype, char* jobz, char* uplo, 00226 integer* n, T* a, integer* lda, T* b, integer* ldb, T* w, 00227 T* work, integer* lwork, 00228 integer* info) const; 00229 00230 int sygvd(integer* itype, char* jobz, char* uplo, 00231 integer* n, T* a, integer* lda, T* b, integer* ldb, T* w, 00232 T* work, integer* lwork, integer* iwork, integer *liwork, 00233 integer* info) const; 00234 00235 int sygvx(integer* itype, char* jobz, char* range, char* uplo, 00236 integer* n, T* a, integer* lda, T* b, integer* ldb, 00237 T* vl, T* vu, integer* il, integer* iu, T* abstol, 00238 integer* m, T* w, T* z, integer* ldz, 00239 T* work, integer* lwork, integer* iwork, 00240 integer *ifail, integer* info) const; 00241 00242 }; 00243 00244 } 00245 00246 #endif 00247 #endif