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

ltiSammonsMapping.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-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

Generated on Sat Apr 10 15:26:06 2010 for LTI-Lib by Doxygen 1.6.1