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-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiCholeskyDecomposition.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 7.7.2003 00030 * revisions ..: $Id: ltiCholeskyDecomposition.h,v 1.8 2006/02/08 12:14:12 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_CHOLESKY_DECOMPOSITION_H_ 00034 #define _LTI_CHOLESKY_DECOMPOSITION_H_ 00035 00036 #include "ltiLinearAlgebraFunctor.h" 00037 #include "ltiMatrix.h" 00038 #include "ltiTriangularMatrixType.h" 00039 00040 namespace lti { 00041 /** 00042 * This functor calculates the Cholesky decomposition of a 00043 * symmetric, positive-definite matrix A. The Cholesky decomposition 00044 * is defined as A = L * L' (with L' the transpose of L) or A = U' * 00045 * U. The cholesky factor L or U are lower or upper triangular 00046 * matrices, respectively, where L=U'. The nature of the Cholesky 00047 * factor can be determined by setting parameters::triangularType or 00048 * using the appropriate apply method. The default is Upper due to 00049 * shorter calculation time. 00050 * 00051 * The Cholesky decomposition can be used to solve a linear equation 00052 * system A*x=b by first solving L*y=b and then L'*x=y using the 00053 * forwardSubstitution and backSubstitution functors, respectively. 00054 */ 00055 template<class T> 00056 class choleskyDecomposition : public linearAlgebraFunctor { 00057 public: 00058 /** 00059 * the parameters for the class choleskyDecomposition 00060 */ 00061 class parameters 00062 : public linearAlgebraFunctor::parameters, 00063 virtual public triangularMatrixType { 00064 public: 00065 /** 00066 * default constructor. The triangularType is Upper by default. 00067 */ 00068 parameters() : linearAlgebraFunctor::parameters() { 00069 00070 triangularType = Upper; 00071 }; 00072 00073 /** 00074 * copy constructor 00075 * @param other the parameters object to be copied 00076 */ 00077 parameters(const parameters& other) : linearAlgebraFunctor::parameters() { 00078 copy(other); 00079 } 00080 00081 /** 00082 * destructor 00083 */ 00084 ~parameters() { 00085 }; 00086 00087 /** 00088 * returns name of this type 00089 */ 00090 const char* getTypeName() const { 00091 return "choleskyDecomposition::parameters"; 00092 }; 00093 00094 /** 00095 * copy the contents of a parameters object 00096 * @param other the parameters object to be copied 00097 * @return a reference to this parameters object 00098 */ 00099 parameters& copy(const parameters& other) { 00100 # ifndef _LTI_MSC_6 00101 // MS Visual C++ 6 is not able to compile this... 00102 linearAlgebraFunctor::parameters::copy(other); 00103 # else 00104 // ...so we have to use this workaround. 00105 // Conditional on that, copy may not be virtual. 00106 functor::parameters& (functor::parameters::* p_copy) 00107 (const functor::parameters&) = 00108 functor::parameters::copy; 00109 (this->*p_copy)(other); 00110 # endif 00111 triangularMatrixType::copy(other); 00112 00113 00114 return *this; 00115 }; 00116 00117 /** 00118 * copy the contents of a parameters object 00119 * @param other the parameters object to be copied 00120 * @return a reference to this parameters object 00121 */ 00122 parameters& operator=(const parameters& other) { 00123 return copy(other); 00124 }; 00125 00126 /** 00127 * returns a pointer to a clone of the parameters 00128 */ 00129 virtual functor::parameters* clone() const { 00130 return new parameters(*this); 00131 }; 00132 00133 # ifndef _LTI_MSC_6 00134 /** 00135 * write the parameters in the given ioHandler 00136 * @param handler the ioHandler to be used 00137 * @param complete if true (the default) the enclosing begin/end will 00138 * be also written, otherwise only the data block will be written. 00139 * @return true if write was successful 00140 */ 00141 virtual bool write(ioHandler& handler,const bool complete=true) const 00142 # else 00143 /** 00144 * this function is required by MSVC only, as a workaround for a 00145 * very awful bug, which exists since MSVC V.4.0, and still by 00146 * V.6.0 with all bugfixes (so called "service packs") remains 00147 * there... This method is also public due to another bug, so please 00148 * NEVER EVER call this method directly: use write() instead 00149 */ 00150 bool writeMS(ioHandler& handler,const bool complete=true) const 00151 # endif 00152 { 00153 bool b = true; 00154 if (complete) { 00155 b = handler.writeBegin(); 00156 } 00157 00158 if (b) { 00159 00160 } 00161 00162 # ifndef _LTI_MSC_6 00163 // This is the standard C++ code, which MS Visual C++ 6 is not able to 00164 // compile... 00165 b = b && linearAlgebraFunctor::parameters::write(handler,false); 00166 # else 00167 bool (linearAlgebraFunctor::parameters::* p_writeMS)(ioHandler&, 00168 const bool) const = 00169 linearAlgebraFunctor::parameters::writeMS; 00170 b = b && (this->*p_writeMS)(handler,false); 00171 # endif 00172 b = b && triangularMatrixType::write(handler,false); 00173 00174 if (complete) { 00175 b = b && handler.writeEnd(); 00176 } 00177 00178 return b; 00179 } 00180 00181 # ifdef _LTI_MSC_6 00182 /** 00183 * write the parameters in the given ioHandler 00184 * @param handler the ioHandler to be used 00185 * @param complete if true (the default) the enclosing begin/end will 00186 * be also written, otherwise only the data block will be written. 00187 * @return true if write was successful 00188 */ 00189 bool write(ioHandler& handler, 00190 const bool complete=true) const { 00191 // ...we need this workaround to cope with another really 00192 // awful MSVC bug. 00193 return writeMS(handler,complete); 00194 } 00195 # endif 00196 00197 00198 # ifndef _LTI_MSC_6 00199 /** 00200 * read the parameters from the given ioHandler 00201 * @param handler the ioHandler to be used 00202 * @param complete if true (the default) the enclosing begin/end will 00203 * be also written, otherwise only the data block will be written. 00204 * @return true if write was successful 00205 */ 00206 virtual bool read(ioHandler& handler,const bool complete=true) 00207 # else 00208 /** 00209 * this function is required by MSVC only, as a workaround for a 00210 * very awful bug, which exists since MSVC V.4.0, and still by 00211 * V.6.0 with all bugfixes (so called "service packs") remains 00212 * there... This method is also public due to another bug, so please 00213 * NEVER EVER call this method directly: use read() instead 00214 */ 00215 bool readMS(ioHandler& handler,const bool complete=true) 00216 # endif 00217 { 00218 bool b = true; 00219 if (complete) { 00220 b = handler.readBegin(); 00221 } 00222 00223 if (b) { 00224 00225 } 00226 00227 # ifndef _LTI_MSC_6 00228 // This is the standard C++ code, which MS Visual C++ 6 is not 00229 // able to compile... 00230 b = b && linearAlgebraFunctor::parameters::read(handler,false); 00231 # else 00232 bool (linearAlgebraFunctor::parameters::* p_readMS)(ioHandler&, 00233 const bool) = 00234 linearAlgebraFunctor::parameters::readMS; 00235 b = b && (this->*p_readMS)(handler,false); 00236 # endif 00237 b = b && triangularMatrixType::read(handler,false); 00238 00239 if (complete) { 00240 b = b && handler.readEnd(); 00241 } 00242 00243 return b; 00244 } 00245 00246 # ifdef _LTI_MSC_6 00247 /** 00248 * read the parameters from the given ioHandler 00249 * @param handler the ioHandler to be used 00250 * @param complete if true (the default) the enclosing begin/end will 00251 * be also written, otherwise only the data block will be written. 00252 * @return true if write was successful 00253 */ 00254 bool read(ioHandler& handler,const bool complete=true) { 00255 // ...we need this workaround to cope with another really awful MSVC 00256 // bug. 00257 return readMS(handler,complete); 00258 } 00259 # endif 00260 00261 // ------------------------------------------------ 00262 // the parameters 00263 // ------------------------------------------------ 00264 00265 //TODO: comment the parameters of your functor 00266 // If you add more parameters manually, do not forget to do following: 00267 // 1. indicate in the default constructor the default values 00268 // 2. make sure that the copy member also copy your new parameters 00269 // 3. make sure that the read and write members also read and 00270 // write your parameters 00271 00272 00273 }; 00274 00275 /** 00276 * default constructor 00277 */ 00278 choleskyDecomposition(); 00279 00280 /** 00281 * Construct a functor using the given parameters 00282 */ 00283 choleskyDecomposition(const parameters& par); 00284 00285 /** 00286 * copy constructor 00287 * @param other the object to be copied 00288 */ 00289 choleskyDecomposition(const choleskyDecomposition& other); 00290 00291 /** 00292 * destructor 00293 */ 00294 virtual ~choleskyDecomposition(); 00295 00296 /** 00297 * returns the name of this type ("choleskyDecomposition") 00298 */ 00299 virtual const char* getTypeName() const; 00300 00301 /** 00302 * The matrix given must be symmetric and positive-definite. The 00303 * apply method returns the upper or lower triangular matrix 00304 * version of the Cholosky decomposition, depending on the value 00305 * of parameters::triangularType. The default Upper is faster. 00306 * @param srcdest matrix<T> with the source data. The result 00307 * will be left here too. 00308 * @return true if apply successful or false otherwise. 00309 */ 00310 bool apply(matrix<T>& srcdest) const; 00311 00312 /** 00313 * The matrix given must be symmetric and positive-definite. The 00314 * apply method returns the upper or lower triangular matrix 00315 * version of the Cholosky decomposition, depending on the value 00316 * of parameters::triangularType. The default Upper is faster. 00317 * @param src matrix<T> with the source data. 00318 * @param l matrix<T> where the result will be left. 00319 * @return true if apply successful or false otherwise. 00320 */ 00321 bool apply(const matrix<T>& src,matrix<T>& l) const; 00322 00323 /** 00324 * The matrix given must be symmetric and positive-definite. The 00325 * apply method returns the upper or lower triangular matrix 00326 * version of the Cholosky decomposition, depending on the value 00327 * of \a tType. 00328 * @param srcdest matrix<T> with the source data. The result 00329 * will be left here too. 00330 * @param tType type of triangular matrix 00331 * @return true if apply successful or false otherwise. 00332 */ 00333 bool apply(matrix<T>& srcdest, 00334 const typename parameters::eTriangularType& tType) const; 00335 00336 /** 00337 * The matrix given must be symmetric and positive-definite. The 00338 * apply method returns the upper or lower triangular matrix 00339 * version of the Cholosky decomposition, depending on the value 00340 * of \a tType. 00341 * @param src matrix<T> with the source data. 00342 * @param l matrix<T> where the result will be left. 00343 * @param tType type of triangular matrix 00344 * @return true if apply successful or false otherwise. 00345 */ 00346 bool apply(const matrix<T>& src,matrix<T>& l, 00347 const typename parameters::eTriangularType& tType) const; 00348 00349 /** 00350 * copy data of "other" functor. 00351 * @param other the functor to be copied 00352 * @return a reference to this functor object 00353 */ 00354 choleskyDecomposition& copy(const choleskyDecomposition& other); 00355 00356 /** 00357 * alias for copy member 00358 * @param other the functor to be copied 00359 * @return a reference to this functor object 00360 */ 00361 choleskyDecomposition& operator=(const choleskyDecomposition& other); 00362 00363 /** 00364 * returns a pointer to a clone of this functor. 00365 */ 00366 virtual functor* clone() const; 00367 00368 /** 00369 * returns used parameters 00370 */ 00371 const parameters& getParameters() const; 00372 00373 //TODO: comment the attributes of your functor 00374 // If you add more attributes manually, do not forget to do following: 00375 // 1. indicate in the default constructor the default values 00376 // 2. make sure that the copy member also copy your new attributes, or 00377 // to ensure there, that these attributes are properly initialized. 00378 00379 }; 00380 } 00381 00382 #endif