NeuralDecoder.H

Go to the documentation of this file.
00001 /*!@file ModelNeuron/NeuralDecoder.H Class declaration for neural
00002    decoders, which expect as input a spike train, and outputs a
00003    decoded signal such as a spike density function, inter spike
00004    interval etc...*/
00005 
00006 // //////////////////////////////////////////////////////////////////// //
00007 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00008 // University of Southern California (USC) and the iLab at USC.         //
00009 // See http://iLab.usc.edu for information about this project.          //
00010 // //////////////////////////////////////////////////////////////////// //
00011 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00012 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00013 // in Visual Environments, and Applications'' by Christof Koch and      //
00014 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00015 // pending; application number 09/912,225 filed July 23, 2001; see      //
00016 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00017 // //////////////////////////////////////////////////////////////////// //
00018 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00019 //                                                                      //
00020 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00021 // redistribute it and/or modify it under the terms of the GNU General  //
00022 // Public License as published by the Free Software Foundation; either  //
00023 // version 2 of the License, or (at your option) any later version.     //
00024 //                                                                      //
00025 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00026 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00027 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00028 // PURPOSE.  See the GNU General Public License for more details.       //
00029 //                                                                      //
00030 // You should have received a copy of the GNU General Public License    //
00031 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00032 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00033 // Boston, MA 02111-1307 USA.                                           //
00034 // //////////////////////////////////////////////////////////////////// //
00035 //
00036 // Primary maintainer for this file: David Berg <dberg@usc.edu>
00037 // $HeadURL:svn://ilab.usc.edu/trunk/saliency/src/ModelNeuron/NeuralDecoder.H$
00038 
00039 #ifndef MODELNEURON_NEURALDECODER_H_DEFINED
00040 #define MODELNEURON_NEURALDECODER_H_DEFINED
00041 
00042 #include "Util/SimTime.H"
00043 #include "GenericUtils/GenericFactory.H"
00044 #include "GenericUtils/CreateFunctor.H"
00045 
00046 // ######################################################################
00047 //! An abstract class for a neural decoder. Neural decoders transform
00048 //! input and output of SimUnit's, possibly with a delay.
00049 // ######################################################################
00050 class NeuralDecoder
00051 {
00052 public:
00053   //typedef for registering decoders
00054   typedef CreateFunctor<NeuralDecoder, ParamList<SimTime> >  Creator;
00055   typedef GenericFactory<NeuralDecoder, std::string, Creator> Factory;
00056 
00057   //!constructor 
00058   NeuralDecoder(const SimTime& timeStep = SimTime::MSECS(1.0),
00059                 const SimTime& windowSize = SimTime::MSECS(100.0)) :
00060     itsWindowSize(windowSize),
00061     itsSamples( (uint)(itsWindowSize.secs()*timeStep.hertz()) ) { };
00062   
00063   //!desctrctor
00064   virtual ~NeuralDecoder() { };
00065   
00066   //!add some data to the decoder
00067   virtual void push(const double& in) = 0; 
00068 
00069   //!get the latest (and possibly time delayed) output of the decoder
00070   virtual const double getOutput() const = 0;
00071 
00072   //!make a copy of the this object
00073   virtual NeuralDecoder* clone() const = 0;
00074 
00075   //! reset the decoder internals to the state after construction
00076   virtual void reset() { };
00077   
00078 protected:
00079   //prohibit copy and assign
00080   NeuralDecoder(const NeuralDecoder& rhs);
00081   NeuralDecoder& operator=(const NeuralDecoder& rhs);
00082 
00083   SimTime itsWindowSize;
00084   uint itsSamples;
00085 };
00086 
00087 // ######################################################################
00088 //! A class to derive from to create new NeuralDecoders. New
00089 //! NeuralDecoder derived types can derive from this class to inherit
00090 //! the clone() function if desired.
00091 /*
00092   Programmer Note: This class uses the 'quriously recursive template
00093   pattern' to simplify creation of new classes for the programmer. As
00094   such, to create a new simulation module, classes should adhear the
00095   following convention:
00096   
00097   class mymodule : public NeuralDecoderDerived<mymodule>
00098   {
00099       mymodule(//params//) : NeuralDecoder<mymodule>(//params//) { };
00100       //...rest of functions
00101   };
00102 */
00103 // ######################################################################
00104 template <class Derived>
00105 class NeuralDecoderDerived : public NeuralDecoder
00106 {
00107 public:
00108   NeuralDecoder* clone() const 
00109   { return new Derived(dynamic_cast<const Derived&>(*this)); };               
00110 
00111 protected:
00112   NeuralDecoderDerived(const SimTime& timeStep = SimTime::MSECS(1.0),
00113                        const SimTime& windowSize = SimTime::MSECS(100.0)) : 
00114     NeuralDecoder(timeStep, windowSize) { };
00115   
00116   ~NeuralDecoderDerived() { };
00117 };
00118 
00119 // ######################################################################
00120 //! A decoder that just passes through the data, possibly with a delay
00121 // ######################################################################
00122 class HoldDecoder: public NeuralDecoderDerived<HoldDecoder>
00123 {
00124 public:
00125   //!constructor 
00126   HoldDecoder(const SimTime& timeStep = SimTime::MSECS(1.0),
00127               const SimTime& windowSize = SimTime::ZERO()) :
00128     NeuralDecoderDerived<HoldDecoder>(timeStep, windowSize), itsLastSpike(0.0), 
00129     itsSignal(itsSamples, 0.0) { };
00130   
00131   //!desctructor
00132   ~HoldDecoder() { };
00133   
00134   //!add some data to the decoder
00135   void push(const double& in); 
00136 
00137   //!get the instantaneous Spikes/Second
00138   const double getOutput() const;
00139 
00140   //! reset decoder internals
00141   void reset();
00142 
00143 private:
00144   double itsLastSpike;
00145   std::deque<double> itsSignal;
00146 };
00147 
00148 // ######################################################################
00149 //! A histogram (non overlapping) decoder, spike count
00150 // ######################################################################
00151 class HistDecoder: public NeuralDecoderDerived<HistDecoder>
00152 {
00153 public:
00154   //!constructor 
00155   HistDecoder(const SimTime& timeStep = SimTime::MSECS(1.0),
00156               const SimTime& windowSize = SimTime::MSECS(100.0)) :
00157     NeuralDecoderDerived<HistDecoder>(timeStep,windowSize), itsSpikeCount(0),
00158     itsLastCount(0.0), itsSampleCount(0) { };
00159   
00160   //!desctructor
00161   ~HistDecoder() { };
00162   
00163   //!add some data to the decoder
00164   void push(const double& in); 
00165 
00166   //!get the instantaneous Spikes/Second
00167   const double getOutput() const;
00168 
00169   //! reset decoder internals
00170   void reset();
00171 
00172 private:
00173   double itsSpikeCount, itsLastCount;
00174   uint itsSampleCount;
00175 };
00176 
00177 // ######################################################################
00178 //!A decoder using a sliding rectangular window, or moving average
00179 //######################################################################
00180 class RectDecoder: public NeuralDecoderDerived<RectDecoder>
00181 {
00182 public:
00183   //!constructor 
00184   RectDecoder(const SimTime& timeStep = SimTime::MSECS(1.0),
00185               const SimTime& windowSize = SimTime::MSECS(100.0)) :
00186     NeuralDecoderDerived<RectDecoder>(timeStep, windowSize), 
00187     itsSpikeRate(0.0), itsSignal(itsSamples, 0.0) { };
00188   
00189   //!desctructor
00190   ~RectDecoder() { };
00191   
00192   //!add some data to the decoder
00193   void push(const double& in); 
00194 
00195   //!get the instantaneous Spikes/Second
00196   const double getOutput() const;
00197 
00198   //! reset decoder internals
00199   void reset();
00200   
00201 private:
00202   double itsSpikeRate;
00203   std::deque<double> itsSignal;
00204 };
00205 
00206 // ######################################################################
00207 //! A Exponential rate decoder
00208 // ######################################################################
00209 class ExpDecoder: public NeuralDecoderDerived<ExpDecoder>
00210 {
00211 public:
00212   //!constructor 
00213   ExpDecoder(const SimTime& timeStep = SimTime::MSECS(1.0),
00214              const SimTime& windowSize = SimTime::MSECS(100.0), 
00215              const double& alpha = 0.99) :
00216     NeuralDecoderDerived<ExpDecoder>(timeStep,windowSize), itsSpikeRate(0.0), 
00217     itsAlpha(alpha) { };
00218   
00219   //!desctructor
00220   ~ExpDecoder() { };
00221 
00222   //!add some data to the decoder
00223   void push(const double& in); 
00224 
00225   //!get the instantaneous Spikes/Second
00226   const double getOutput() const;
00227 
00228   //! reset decoder internals
00229   void reset();
00230   
00231 private:
00232   double itsSpikeRate;
00233   double itsAlpha;
00234 };
00235 
00236 // ######################################################################
00237 //! A Rate decoder using an alpha function
00238 // ######################################################################
00239 class AlphaDecoder: public NeuralDecoderDerived<AlphaDecoder>
00240 {
00241 public:
00242   //!constructor: in this case windowSize is the alpha parameter of
00243   //!the kernel function 1/alpha^2 * t * exp(-1/alpha * t), the actual
00244   //!length of the kernel is determined automatically
00245   AlphaDecoder(const SimTime& timeStep = SimTime::MSECS(1.0),
00246                const SimTime& windowSize = SimTime::MSECS(15.0));
00247   //!destructor
00248   ~AlphaDecoder() { };
00249   
00250   //!add some data to the decoder
00251   void push(const double& in); 
00252 
00253   //!get the instantaneous Spikes/Second
00254   const double getOutput() const;
00255 
00256   //! reset decoder internals
00257   void reset();
00258 
00259 private:
00260   std::deque<double> itsSignal;
00261   std::vector<double> itsKernel;
00262 };
00263 
00264 // ######################################################################
00265 // register or types with a factory
00266 // ######################################################################
00267 namespace 
00268 {
00269   typedef NeuralDecoder::Factory NDFactory;
00270   typedef NeuralDecoder::Creator NDCreator;
00271   //define creation functions
00272   struct RegisterNeuralDecoder
00273   {
00274     RegisterNeuralDecoder()
00275     {
00276       const SimTime time = SimTime::MSECS(1.0);
00277       NDFactory::instance().add("HoldDecoder",  NDCreator::make<HoldDecoder>(time));
00278       NDFactory::instance().add("HistDecoder",  NDCreator::make<HistDecoder>(time));
00279       NDFactory::instance().add("RectDecoder",  NDCreator::make<RectDecoder>(time));
00280       NDFactory::instance().add("ExpDecoder",   NDCreator::make<ExpDecoder>(time));
00281       NDFactory::instance().add("AlphaDecoder", NDCreator::make<AlphaDecoder>(time));
00282     }
00283   };
00284   static RegisterNeuralDecoder registerneuraldecoder;  
00285 }
00286 
00287 #endif
00288 
00289 // ######################################################################
00290 /* So things look consistent in everyone's emacs... */
00291 /* Local Variables: */
00292 /* indent-tabs-mode: nil */
00293 /* End: */
00294 
00295 
00296 
Generated on Sun May 8 08:05:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3