latest version v1.9 - last update 10 Apr 2010 |
00001 /* 00002 * Copyright (C) 2000, 2001, 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 .......: ltiPCA.h 00027 * authors ....: Jochen Wickel 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 27.11.2000 00030 * revisions ..: $Id: ltiRegularizedPCA.h,v 1.7 2006/02/08 12:41:37 ltilib Exp $ 00031 */ 00032 00033 #ifndef _LTI_REG_PCA_H_ 00034 #define _LTI_REG_PCA_H_ 00035 00036 #include "ltiPCA.h" 00037 00038 namespace lti { 00039 /** 00040 * Almost a functor for computing a principal component analysis. 00041 * 00042 * It receives a set of input vectors in form of a matrix (each row of 00043 * the matrix corresponds to an input vector), which will be transformed 00044 * with PCA. 00045 * 00046 * The first time you use the apply()-method, the transformation 00047 * matrix will be computed. You can use this transformation matrix 00048 * with other data sets using the transform() methods. 00049 * 00050 * Please note that the eigenvector matrices will contain the 00051 * eigenvector in the COLUMNS and not in the rows, as could be 00052 * expected. This avoids the requirement of transposing matrices in 00053 * the vector transformations (see also lti::eigenSystem<T>). 00054 * 00055 * The only difference to PCA is that this receives 00056 * an additional parameter kappa which is used in dimensionality 00057 * reductions. If kappa is greater than zero, we keep the dimensionality 00058 * of the original space and set the insignificant eigenvalues to the 00059 * value of the smallest significant one times kappa. 00060 */ 00061 template <class T> 00062 class regularizedPCA : public principalComponents<T> { 00063 public: 00064 /** 00065 * the parameters for the class regularizedPCA 00066 */ 00067 class parameters : public principalComponents<T>::parameters { 00068 public: 00069 /** 00070 * default constructor 00071 */ 00072 parameters() 00073 : principalComponents<T>::parameters() { 00074 kappa=T(1); 00075 } 00076 00077 /** 00078 * copy constructor 00079 * @param other the parameters object to be copied 00080 */ 00081 parameters(const parameters& other) { 00082 copy(other); 00083 } 00084 00085 00086 /** 00087 * destructor 00088 */ 00089 virtual ~parameters() { 00090 } 00091 00092 /** 00093 * returns name of this type 00094 */ 00095 const char* getTypeName() const { 00096 return "regularizedPCA::parameters"; 00097 } 00098 00099 /** 00100 * copy the contents of a parameters object 00101 * @param other the parameters object to be copied 00102 * @return a reference to this parameters object 00103 */ 00104 parameters& copy(const parameters& other) { 00105 # ifndef _LTI_MSC_6 00106 // MS Visual C++ 6 is not able to compile this... 00107 principalComponents<T>::parameters::copy(other); 00108 # else 00109 // ...so we have to use this workaround. 00110 // Conditional on that, copy may not be virtual. 00111 functor::parameters& 00112 (functor::parameters::* p_copy) 00113 (const functor::parameters&) = 00114 functor::parameters::copy; 00115 (this->*p_copy)(other); 00116 # endif 00117 00118 kappa=other.kappa; 00119 return *this; 00120 } 00121 00122 00123 /** 00124 * Assigns the contents of the other object to this object 00125 */ 00126 inline parameters& operator=(const parameters& other) { 00127 copy(other); 00128 return *this; 00129 } 00130 00131 /** 00132 * returns a pointer to a clone of the parameters 00133 */ 00134 virtual functor::parameters* clone() const { 00135 return new parameters(*this); 00136 } 00137 00138 # ifndef _LTI_MSC_6 00139 /** 00140 * read the parameters from the given ioHandler 00141 * @param handler the ioHandler to be used 00142 * @param complete if true (the default) the enclosing begin/end will 00143 * be also read, otherwise only the data block will be read. 00144 * @return true if write was successful 00145 */ 00146 virtual bool read(ioHandler &handler, const bool complete=true) 00147 # else 00148 bool readMS(ioHandler& handler,const bool complete=true) 00149 # endif 00150 { 00151 bool b=true; 00152 00153 if (complete) { 00154 b=handler.readBegin(); 00155 } 00156 00157 if (b) { 00158 b=b && lti::read(handler, "kappa", kappa); 00159 } 00160 00161 # ifndef _LTI_MSC_6 00162 // This is the standard C++ code, which MS Visual C++ 6 is not 00163 // able to compile... 00164 b = b && principalComponents<T>::parameters::read(handler,false); 00165 # else 00166 bool (functor::parameters::* p_readMS)(ioHandler&,const bool) = 00167 functor::parameters::readMS; 00168 b = b && (this->*p_readMS)(handler,false); 00169 # endif 00170 00171 if (complete) { 00172 b=b && handler.readEnd(); 00173 } 00174 00175 return b; 00176 } 00177 00178 # ifdef _LTI_MSC_6 00179 /** 00180 * read the parameters from the given ioHandler 00181 * @param handler the ioHandler to be used 00182 * @param complete if true (the default) the enclosing begin/end will 00183 * be also read, otherwise only the data block will be read. 00184 * @return true if write was successful 00185 */ 00186 virtual bool read(ioHandler& handler,const bool complete=true) { 00187 // ...we need this workaround to cope with another really awful MSVC 00188 // bug. 00189 return readMS(handler,complete); 00190 } 00191 # endif 00192 00193 # ifndef _LTI_MSC_6 00194 /** 00195 * write the parameters in the given ioHandler 00196 * @param handler the ioHandler to be used 00197 * @param complete if true (the default) the enclosing begin/end will 00198 * be also written, otherwise only the data block will be 00199 * written. 00200 * @return true if write was successful 00201 */ 00202 virtual bool write(ioHandler& handler,const bool complete=true) const 00203 # else 00204 bool writeMS(ioHandler& handler,const bool complete=true) const 00205 # endif 00206 { 00207 bool b=true; 00208 00209 if (complete) { 00210 b=handler.writeBegin(); 00211 } 00212 00213 if (b) { 00214 lti::write(handler, "kappa", kappa); 00215 } 00216 00217 # ifndef _LTI_MSC_6 00218 // This is the standard C++ code, which MS Visual C++ 6 is not 00219 // able to compile... 00220 b = b && principalComponents<T>::parameters::write(handler,false); 00221 # else 00222 bool 00223 (functor::parameters::* p_writeMS)(ioHandler&,const bool) const = 00224 functor::parameters::writeMS; 00225 b = b && (this->*p_writeMS)(handler,false); 00226 # endif 00227 00228 if (complete) { 00229 b=b && handler.writeEnd(); 00230 } 00231 00232 return b; 00233 } 00234 00235 # ifdef _LTI_MSC_6 00236 /** 00237 * write the parameters to the given ioHandler 00238 * @param handler the ioHandler to be used 00239 * @param complete if true (the default) the enclosing begin/end will 00240 * be also writen, otherwise only the data block will be writen. 00241 * @return true if write was successful 00242 */ 00243 virtual bool write(ioHandler& handler,const bool complete=true) { 00244 // ...we need this workaround to cope with another really awful MSVC 00245 // bug. 00246 return writeMS(handler,complete); 00247 } 00248 # endif 00249 00250 /** 00251 * The kappa parameter. Kappa controls the factor by which the 00252 * last significant eigenvalue is scaled to yield a replacement 00253 * for the insignificant eigenvalues. 00254 */ 00255 T kappa; 00256 00257 }; 00258 00259 /** 00260 * default constructor 00261 */ 00262 regularizedPCA(); 00263 00264 /** 00265 * copy constructor 00266 * @param other the object to be copied 00267 */ 00268 regularizedPCA(const regularizedPCA& other); 00269 00270 /** 00271 * destructor 00272 */ 00273 virtual ~regularizedPCA(); 00274 00275 /** 00276 * returns used parameters 00277 */ 00278 const parameters& getParameters() const; 00279 00280 /** 00281 * returns a pointer to a clone of this functor. 00282 */ 00283 virtual functor* clone() const; 00284 00285 protected: 00286 /** 00287 * Determines the intrinsic dimensionality of the data set if the 00288 * user specify autoDim, otherwise return parameters::resultDim. 00289 * The member usedDimensionality will be set with the returned value 00290 */ 00291 int checkDim(); 00292 00293 }; 00294 00295 template <class T> 00296 bool read(ioHandler& handler, 00297 regularizedPCA<T>& pca, 00298 const bool complete=true) { 00299 return pca.read(handler,complete); 00300 } 00301 00302 00303 template <class T> 00304 bool write(ioHandler& handler, 00305 const regularizedPCA<T>& pca, 00306 const bool complete=true) { 00307 return pca.write(handler,complete); 00308 } 00309 00310 } 00311 00312 #include "ltiRegularizedPCA_template.h" 00313 00314 #endif