NeuralDecoder.C

Go to the documentation of this file.
00001 /*!@file ModelNeuron/NeuralDecoder.C Class declaration for a neural
00002    simulation module*/
00003 
00004 // //////////////////////////////////////////////////////////////////// //
00005 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00006 // University of Southern California (USC) and the iLab at USC.         //
00007 // See http://iLab.usc.edu for information about this project.          //
00008 // //////////////////////////////////////////////////////////////////// //
00009 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00010 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00011 // in Visual Environments, and Applications'' by Christof Koch and      //
00012 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00013 // pending; application number 09/912,225 filed July 23, 2001; see      //
00014 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00015 // //////////////////////////////////////////////////////////////////// //
00016 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00017 //                                                                      //
00018 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00019 // redistribute it and/or modify it under the terms of the GNU General  //
00020 // Public License as published by the Free Software Foundation; either  //
00021 // version 2 of the License, or (at your option) any later version.     //
00022 //                                                                      //
00023 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00024 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00025 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00026 // PURPOSE.  See the GNU General Public License for more details.       //
00027 //                                                                      //
00028 // You should have received a copy of the GNU General Public License    //
00029 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00030 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00031 // Boston, MA 02111-1307 USA.                                           //
00032 // //////////////////////////////////////////////////////////////////// //
00033 //
00034 // Primary maintainer for this file: David Berg <dberg@usc.edu>
00035 // $HeadURL:svn://ilab.usc.edu/trunk/saliency/src/ModelNeuron/NeuralDecoder.C$
00036 
00037 #include "ModelNeuron/NeuralDecoder.H"
00038 
00039 #include <cmath>
00040 
00041 // ######################################################################
00042 //!  implementations of NeuralDecoder
00043 // #####################################################################
00044 NeuralDecoder::NeuralDecoder(const NeuralDecoder& rhs) : 
00045   itsWindowSize(rhs.itsWindowSize), itsSamples(rhs.itsSamples)
00046 {
00047 }
00048 
00049 // ######################################################################
00050 NeuralDecoder& NeuralDecoder::operator=(const NeuralDecoder& rhs)
00051 {
00052   if (this != &rhs)
00053     {
00054       itsWindowSize = rhs.itsWindowSize;
00055       itsSamples = rhs.itsSamples;
00056     }
00057   return *this;
00058 }
00059 
00060 // ######################################################################
00061 //!  implementations of HoldDecoder
00062 // ######################################################################
00063 void HoldDecoder::push(const double& data) 
00064 {
00065   if (itsSignal.size() < 1)
00066     itsLastSpike = data;
00067   else
00068     {
00069       itsSignal.push_back(data);
00070       itsLastSpike = itsSignal.front();
00071       itsSignal.pop_front();
00072     }
00073 }
00074 
00075 // ######################################################################
00076 const double HoldDecoder::getOutput() const 
00077 {
00078   return itsLastSpike;
00079 }
00080 
00081 // ######################################################################
00082 void HoldDecoder::reset()
00083 {
00084   itsLastSpike = 0.0;
00085   itsSignal.clear();
00086   itsSignal.resize(itsSamples, 0.0);
00087 }
00088 
00089 // ######################################################################
00090 //!  implementations of HistDecoder
00091 // ######################################################################
00092 void HistDecoder::push(const double& data) 
00093 {
00094   
00095   itsSpikeCount += data;
00096   itsSampleCount++;
00097   
00098   if (itsSampleCount == itsSamples)
00099     {
00100       itsSampleCount = 0;
00101       itsLastCount = itsSpikeCount;
00102       itsSpikeCount = 0.0;
00103     }
00104 }
00105 
00106 // ######################################################################
00107 const double HistDecoder::getOutput() const 
00108 {
00109   return itsLastCount / itsWindowSize.secs();
00110 }
00111 
00112 // ######################################################################
00113 void HistDecoder::reset()
00114 {
00115   itsSpikeCount = 0;
00116   itsLastCount = 0.0;
00117   itsSampleCount = 0;
00118 }
00119 
00120 // ######################################################################
00121 //!  implementations of RectDecoder
00122 // ######################################################################
00123 void RectDecoder::push(const double& data) 
00124 {
00125   itsSpikeRate += data - itsSignal.front();
00126   itsSignal.pop_front();
00127   itsSignal.push_back(data);
00128 }
00129 
00130 // ######################################################################
00131 const double RectDecoder::getOutput() const 
00132 {
00133   return itsSpikeRate / itsWindowSize.secs();
00134 }
00135 
00136 // ######################################################################
00137 void RectDecoder::reset()
00138 {
00139   itsSpikeRate = 0.0;
00140   itsSignal.clear();
00141   itsSignal.resize(itsSamples, 0.0);
00142 }
00143 
00144 // ######################################################################
00145 //!  implementations of ExpDecoder
00146 // ######################################################################
00147 void ExpDecoder::push(const double& data) 
00148 {
00149   itsSpikeRate *= itsAlpha;
00150   itsSpikeRate += (1.0-itsAlpha)*data;
00151 }
00152 
00153 // ######################################################################
00154 const double ExpDecoder::getOutput() const 
00155 {
00156   return itsSpikeRate;
00157 }
00158 
00159 // ######################################################################
00160 void ExpDecoder::reset()
00161 {
00162   itsSpikeRate = 0.0;
00163 }
00164 
00165 // ######################################################################
00166 //! implementation of AlphaDecoder
00167 // ######################################################################
00168 AlphaDecoder::AlphaDecoder(const SimTime& timeStep,
00169                            const SimTime& windowSize) :
00170   NeuralDecoderDerived<AlphaDecoder>(timeStep,windowSize), 
00171   itsSignal(), itsKernel()
00172 {
00173   const double a = 1.0 / windowSize.secs();  
00174   //find the optimal array size of the filter if we truncate at a
00175   //small value, C. No easy analytical solution exists to this problem,
00176   //so lets just use newtons method of roots to approximate
00177   double C = 0.0001;              
00178   //our initial estimate b. Since 1/a should define the peak of the
00179   //function in time, a good place to start is just a little beond that.
00180   double b = 1.0/a + 0.1 * (1.0 / a);
00181   for (int i = 0; i < 20; i++)
00182     {
00183       //our function
00184       double func = (a*a) * b * exp(-1 * a * b);
00185       //its second derivitive
00186       double func2 = ( (a*a) - (a * a * a) * b ) / exp(a * b);
00187       b = b - ( func - C ) / func2;
00188     }
00189   SimTime end = SimTime::SECS(b);
00190   SimTime ii =  SimTime::SECS(-1*b);  
00191   for (; ii  < end; ii += timeStep)
00192     {
00193       if (ii > SimTime::ZERO())
00194         {
00195           double  temp = (a * a) * ii.secs() * exp(-1.0 * a * ii.secs());
00196           itsKernel.push_back(temp);
00197         }
00198     } 
00199   itsSignal.resize(itsKernel.size(),0.0);
00200 }
00201 
00202 // ######################################################################
00203 void AlphaDecoder::push(const double& data) 
00204  {
00205    itsSignal.push_back(data);
00206    itsSignal.pop_front();
00207  }
00208 
00209 // ######################################################################
00210 const double AlphaDecoder::getOutput() const 
00211 {
00212   std::vector<double>::const_reverse_iterator iter = itsKernel.rbegin();
00213   std::deque<double>::const_iterator iters = itsSignal.begin();
00214   double val = 0.0;
00215   while (iters != itsSignal.end())
00216     val += (*iter++) * (*iters++);
00217   return val;
00218 }
00219 
00220 // ######################################################################
00221 void AlphaDecoder::reset()
00222 {
00223   itsSignal.clear();
00224 }
00225 
00226 // ######################################################################
00227 /* So things look consistent in everyone's emacs... */
00228 /* Local Variables: */
00229 /* indent-tabs-mode: nil */
00230 /* End: */
Generated on Sun May 8 08:41:01 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3