latest version v1.9 - last update 10 Apr 2010 |
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-Lib: Image Processing and Computer Vision Library 00026 * file .......: ltiSammonsMapping.h 00027 * authors ....: Peter Doerfler 00028 * organization: LTI, RWTH Aachen 00029 * creation ...: 9.10.2002 00030 * revisions ..: $Id: ltiSammonsMapping.h,v 1.8 2008/05/29 02:57:04 alvarado Exp $ 00031 */ 00032 00033 #ifndef _LTI_SAMMONS_MAPPING_H_ 00034 #define _LTI_SAMMONS_MAPPING_H_ 00035 00036 #include "ltiFunctor.h" 00037 #include "ltiVector.h" 00038 #include "ltiMatrix.h" 00039 #include "ltiProgressInfo.h" 00040 00041 namespace lti { 00042 /** 00043 * Performs Sammon's Mapping. The data from some high dimensional 00044 * source space is mapped to a destination space of lower 00045 * dimensionality. In the process Sammon's Mapping tries to keep 00046 * distances between samples in the destination space as close to 00047 * those in the source space. Typical uses are data analysis or 00048 * visualization of SOFM networks. For details see: 00049 * 00050 * John W. Sammon, Jr. <i>A nonlinear mapping for data structure 00051 * analysis.</i> IEEE Transactions on Computers, C-18(5):401-409, May 00052 * 1969. 00053 * 00054 * There are several parameters the algorithm can be tuned 00055 * with. Initialization is usually performed using principal 00056 * component analysis. It projects the data from the original space 00057 * into the destination space using the eigenvectors with largest 00058 * eingenvalues. The other option --- random initialization --- 00059 * seems to be useful for demonstration purposes, only. 00060 * 00061 * Three methods are available for minimizing the error or stress 00062 * of the mapping: gradient descent, gradient descent with momentum 00063 * and steepest descent. Of these, steepest descent usually 00064 * requires the smallest number of iterations, but each iteration 00065 * is more costly. Further, with many planes in the error surface, 00066 * the computation of the second derivative might not be 00067 * possible. In case of 0 this value is set to 1.E-4 as a 00068 * work-around. The gradient descent methods are much more 00069 * stable. Their convergence, however, is much slower. Using 00070 * momentum can lead to faster convergence than regular gradient 00071 * descent but also needs more computation per iteration. According 00072 * to Sammon, errors should be below 1E-2 to be considered 00073 * good. Usually, much smaller errors are achieved. 00074 */ 00075 class sammonsMapping : public functor { 00076 public: 00077 /** 00078 * the parameters for the class sammonsMapping 00079 */ 00080 class parameters : public functor::parameters { 00081 public: 00082 00083 /** 00084 * Initialization for the lower dimensional image space. The 00085 * Random version uses initBox for the size of the hyper cube 00086 * the values are drawn from. The PCA version was suggested by 00087 * Sammon for real-world problems. It uses the projection of the 00088 * data points into the image space as initialization. 00089 */ 00090 enum eInit { 00091 Random, /*!< choose initial values randomly from hyper cube initBox */ 00092 PCA /*!< initial values are projection of the data by PCA */ 00093 }; 00094 00095 /** 00096 * Different methods for seeking the minimum of the error: 00097 * <p><ul> 00098 * <li><b>Steepest</b> uses steepest descent, i.e. the gradient 00099 * is divided by the norm of the second derivative.</li> 00100 * <li><b>Gradient</b> uses regular gradient descent</li> 00101 * <li><b>Momentum</b> uses gradient descent with momentum. The momentum 00102 * is set by the parameter mu.</li> 00103 * </ul> 00104 */ 00105 enum eSearch { 00106 Steepest, /*!< steepest descent */ 00107 Gradient, /*!< gradient descent */ 00108 Momentum /*!< gradient descent with momentum */ 00109 }; 00110 00111 00112 /** 00113 * default constructor 00114 */ 00115 parameters(); 00116 00117 /** 00118 * copy constructor 00119 * @param other the parameters object to be copied 00120 */ 00121 parameters(const parameters& other); 00122 00123 /** 00124 * destructor 00125 */ 00126 ~parameters(); 00127 00128 /** 00129 * returns name of this type 00130 */ 00131 const char* getTypeName() const; 00132 00133 /** 00134 * copy the contents of a parameters object 00135 * @param other the parameters object to be copied 00136 * @return a reference to this parameters object 00137 */ 00138 parameters& copy(const parameters& other); 00139 00140 /** 00141 * copy the contents of a parameters object 00142 * @param other the parameters object to be copied 00143 * @return a reference to this parameters object 00144 */ 00145 parameters& operator=(const parameters& other); 00146 00147 00148 /** 00149 * returns a pointer to a clone of the parameters 00150 */ 00151 virtual functor::parameters* clone() const; 00152 00153 /** 00154 * write the parameters in the given ioHandler 00155 * @param handler the ioHandler to be used 00156 * @param complete if true (the default) the enclosing begin/end will 00157 * be also written, otherwise only the data block will be written. 00158 * @return true if write was successful 00159 */ 00160 virtual bool write(ioHandler& handler,const bool complete=true) const; 00161 00162 /** 00163 * read the parameters from the given ioHandler 00164 * @param handler the ioHandler to be used 00165 * @param complete if true (the default) the enclosing begin/end will 00166 * be also written, otherwise only the data block will be written. 00167 * @return true if write was successful 00168 */ 00169 virtual bool read(ioHandler& handler,const bool complete=true); 00170 00171 # ifdef _LTI_MSC_6 00172 /** 00173 * this function is required by MSVC only, as a workaround for a 00174 * very awful bug, which exists since MSVC V.4.0, and still by 00175 * V.6.0 with all bugfixes (so called "service packs") remains 00176 * there... This method is also public due to another bug, so please 00177 * NEVER EVER call this method directly: use read() instead 00178 */ 00179 bool readMS(ioHandler& handler,const bool complete=true); 00180 00181 /** 00182 * this function is required by MSVC only, as a workaround for a 00183 * very awful bug, which exists since MSVC V.4.0, and still by 00184 * V.6.0 with all bugfixes (so called "service packs") remains 00185 * there... This method is also public due to another bug, so please 00186 * NEVER EVER call this method directly: use write() instead 00187 */ 00188 bool writeMS(ioHandler& handler,const bool complete=true) const; 00189 # endif 00190 00191 // ------------------------------------------------ 00192 // the parameters 00193 // ------------------------------------------------ 00194 00195 /** 00196 * The number of dimensions of the output space. Since Sammon's 00197 * Mapping is mostly used for visualization the dafault is 2. 00198 */ 00199 int dimensions; 00200 00201 /** 00202 * Number of steps. Default is 200. 00203 */ 00204 int steps; 00205 00206 /** 00207 * Threshold for the error of the mapping. By default not used, thus 0. 00208 */ 00209 double errorThresh; 00210 00211 /** 00212 * A 'learn' rate or step size. According to Kohonen it should 00213 * be somewhere between 0.3 and 0.4. The default is 0.35 00214 */ 00215 double alpha; 00216 00217 /** 00218 * Sets the initType. Default is PCA. 00219 */ 00220 eInit initType; 00221 00222 /** 00223 * Hyper cube random init values are chosen from in case 00224 * initType is Random. Each dimension ranges from 0 to the given 00225 * value. Take care to choose the same dimesionality for initBox 00226 * as the value of dimensions. Default is a unit cube. 00227 */ 00228 dvector initBox; 00229 00230 /** 00231 * Sets the type of search method used to minimize the 00232 * error. Default is Steepest. 00233 */ 00234 eSearch searchType; 00235 00236 /** 00237 * The momentum. Used if searchType is set to Momentum. Default is 0.1 00238 */ 00239 double mu; 00240 00241 }; 00242 00243 /** 00244 * default constructor 00245 */ 00246 sammonsMapping(); 00247 00248 /** 00249 * copy constructor 00250 * @param other the object to be copied 00251 */ 00252 sammonsMapping(const sammonsMapping& other); 00253 00254 /** 00255 * destructor 00256 */ 00257 virtual ~sammonsMapping(); 00258 00259 /** 00260 * returns the name of this type ("sammonsMapping") 00261 */ 00262 virtual const char* getTypeName() const; 00263 00264 //TODO: comment your apply methods! 00265 00266 /** 00267 * operates on a copy of the given %parameters. 00268 * @param src dmatrix with the source data. 00269 * @param dest dmatrix where the result will be left. 00270 * @param error the error of the mapping 00271 * @return true if apply successful or false otherwise. 00272 */ 00273 bool apply(const dmatrix& src,dmatrix& dest,double& error) const; 00274 00275 /** 00276 * operates on a copy of the given %parameters. 00277 * @param src dmatrix with the source data. 00278 * @param dest dmatrix where the result will be left. 00279 * @return true if apply successful or false otherwise. 00280 */ 00281 bool apply(const dmatrix& src,dmatrix& dest) const; 00282 00283 /** 00284 * copy data of "other" functor. 00285 * @param other the functor to be copied 00286 * @return a reference to this functor object 00287 */ 00288 sammonsMapping& copy(const sammonsMapping& other); 00289 00290 /** 00291 * alias for copy member 00292 * @param other the functor to be copied 00293 * @return a reference to this functor object 00294 */ 00295 sammonsMapping& operator=(const sammonsMapping& other); 00296 00297 /** 00298 * returns a pointer to a clone of this functor. 00299 */ 00300 virtual functor* clone() const; 00301 00302 /** 00303 * returns used parameters 00304 */ 00305 const parameters& getParameters() const; 00306 00307 /** 00308 * set a progress %object 00309 * 00310 * A clone of the given %object will be generated. 00311 */ 00312 void setProgressObject(const progressInfo& progBox); 00313 00314 /** 00315 * remove the active progress %object 00316 */ 00317 void removeProgressObject(); 00318 00319 /** 00320 * return true if a valid progressInfo %object has already been setted 00321 */ 00322 bool validProgressObject() const; 00323 00324 /** 00325 * get progress %object 00326 */ 00327 progressInfo& getProgressObject(); 00328 00329 /** 00330 * get progress %object 00331 */ 00332 const progressInfo& getProgressObject() const; 00333 00334 protected: 00335 00336 /** 00337 * current progress %object 00338 */ 00339 mutable progressInfo* progressBox; 00340 00341 /** 00342 * Random initialization 00343 */ 00344 void initRandom(dmatrix& dest) const ; 00345 00346 /** 00347 * Initialization using PCA 00348 */ 00349 void initPca(const dmatrix& data, dmatrix& dest) const ; 00350 00351 }; 00352 } 00353 00354 #endif