LeakyIntFireAdp.H

Go to the documentation of this file.
00001 /*!@file Neuro/LeakyIntFireAdp.H Class declarations for an adaptive leaky integrator neuron */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the //
00005 // University of Southern California (USC) and the iLab at USC.         //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Laurent Itti <itti@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Neuro/LeakyIntFireAdp.H $
00035 // $Id: LeakyIntFireAdp.H 10729 2009-02-02 03:44:27Z itti $
00036 //
00037 
00038 #ifndef LEAKY_INTFIRE_ADP_H_DEFINED
00039 #define LEAKY_INTFIRE_ADP_H_DEFINED
00040 
00041 #include "Util/SimTime.H"
00042 
00043 // ######################################################################
00044 //! A leaky integrate & fire neuron, used by standard winner-take-all (WTA)
00045 // ######################################################################
00046 /*! This is the integrate & fire neuron used in conjunction with WTA
00047   which is a 2D array of LeakyIntFire. It has a slightly more
00048   complicated Euler equation then LeakyIntegrator used by SM but the
00049   basic idea is the same.  All parameters are in MKSA (SI) units
00050   (i.e., volts, amperes, siemens, etc).  This neuron uses an Euler
00051   integration of the following form:
00052 
00053   At each time step,
00054 
00055   \f[ V \leftarrow V + \frac{\delta t}{C} \left(I - G_{leak}(V - E_{leak}) -
00056   G_{ex}(V - E_{ex}) - G_{inh}(V - E_{inh})\right) \f]
00057 
00058   V is also clamped to never become smaller than \f$E_{inh}\f$ and
00059   a spike is generated when \f$V \ge V_{th}\f$ (and V is then reset to zero).*/
00060 class LeakyIntFireAdp
00061 {
00062 public:
00063   //! constructor
00064   /*! Constructor with default params
00065     @param timeStep is the integration time step, in s.
00066     See the general description for the other params. */
00067   inline LeakyIntFireAdp(const SimTime timeStep = SimTime::SECS(0.0001),
00068                          const float El      = 0.0F,         // in Volts
00069                          const float Ee      = 100.0e-3F,    // in Volts
00070                          const float Ei      = -20.0e-3F,    // in Volts
00071                          const float Gl      = 5.0e-8F,      // in Siemens
00072                          const float Ge      = 0.0F,         // in Siemens
00073                          const float Gi      = 0.0F,         // in Siemens
00074                          const float Vth     = 0.001F,       // in Volts
00075                          const float C       = 1.0E-9F,      // in Farads
00076                          const float VthMod  = 1.0F,
00077                          const float VthDec  = 0.01F,
00078                          const float VthBase = 0.001F,
00079                          const float Vfire   = 0.0F);
00080 
00081   //! set input current (A)
00082   inline void input(const float current);
00083 
00084   //! set membrane potential to given value relative to Ei (in Volts)
00085   inline void setV(const double val);
00086 
00087   //! integrate for up to given time (in s)
00088   /*! Returns true if a spike was generated. */
00089   inline bool integrate(const SimTime& t);
00090 
00091   //! get current membrane potential (in V)
00092   inline float getV() const;
00093 
00094   //! get current membrane potential threshold
00095   inline float getVth() const;
00096 
00097   //! get current membrane potential at time of fire
00098   inline float getVfire() const;
00099 
00100   //! set excitatory and inhibitory conductances (S)
00101   inline void setG(const float Exc, const float Inh);
00102 
00103   //! set leak conductance (S)
00104   inline void setGleak(const float Leak);
00105 
00106   //! return our internal time step:
00107   inline SimTime getTimeStep() const;
00108 
00109   //! get the logistic sigmoid of the input value
00110   inline float logsig(const float x, const float o, const float b) const;
00111 
00112   //! change the threshold for firing
00113   /*! We change the fire threshold based on three primary factors
00114       (1) How salient is this location - salVal
00115       (2) At what voltage did the winner fire at - VfireVal
00116       (3) How far am I from the winner - dist
00117 
00118       Thus, the new Vth is increased based on these three factors
00119   */
00120   inline void setNewVth(const float salVal, const float VfireVal,
00121                         const float dist);
00122 
00123 private:
00124   inline void reset();// reset when a spike occurs
00125 
00126   SimTime itsTimeStep;// time step to use for difference equations (in s)
00127   float itsV;         // membrane potential in Volts
00128   float itsI;         // input current in Amperes
00129   float itsGl;        // leak conductance in Siemens
00130   float itsGe;        // excitatory conductance in Siemens
00131   float itsGi;        // inhibitory conductance in Siemens
00132   float itsC;         // capacitance in Farads
00133   float itsEl;        // driving potential for leak part, in Volts
00134   float itsEe;        // driving potential for excitatory part, in Volts
00135   float itsEi;        // driving potential for inhibitory part, in Volts
00136   float itsVth;       // spike threshold voltage in Volts
00137   float itsVthMod;    // How much to modulate V threshold
00138   float itsVthDecay;  // How much to decay V threshold
00139   float itsVthBase;   // Smallest V threshold
00140   float itsVfire;     // what V did we fire at?
00141   SimTime itsT;       // time of last integration
00142 };
00143 
00144 // ######################################################################
00145 // ##### Inline functions for LeakyIntFireAdp:
00146 // ######################################################################
00147 
00148 inline LeakyIntFireAdp::LeakyIntFireAdp(const SimTime timeStep,
00149                                   const float El,
00150                                   const float Ee,
00151                                   const float Ei,
00152                                   const float Gl,
00153                                   const float Ge,
00154                                   const float Gi,
00155                                   const float Vth,
00156                                   const float C,
00157                                   const float VthMod,
00158                                   const float VthDec,
00159                                   const float VthBase,
00160                                   const float Vfire) :
00161   itsTimeStep(timeStep), itsV(Ei), itsI(0.0), itsGl(Gl), itsGe(Ge), itsGi(Gi),
00162   itsC(C), itsEl(El), itsEe(Ee), itsEi(Ei), itsVth(Vth), itsVthMod(VthMod),
00163   itsVthDecay(VthDec), itsVthBase(VthBase), itsVfire(0), itsT(SimTime::ZERO())
00164 {  }
00165 
00166 // ######################################################################
00167 inline void LeakyIntFireAdp::input(const float current)
00168 { itsI = current; }
00169 
00170 // ######################################################################
00171 inline bool LeakyIntFireAdp::integrate(const SimTime& t)
00172 {
00173   // we run our difference equations with a time step of itsTimeStep;
00174   // let's here figure out how many iterations we will need to go from
00175   // itsT to t. We will iterate for a number of equal steps, with each
00176   // step as close to itsTimeStep as possible to that we end up at
00177   // time t after iterating for an integer number of time steps:
00178   const SimTime dt = SimTime::computeDeltaT((t - itsT), itsTimeStep);
00179   const float dtsc = float(dt.secs()) / itsC;
00180 
00181   bool spike = false;
00182   for (SimTime tt = itsT; tt < t; tt += dt)
00183   {
00184     // Integrate :    all units MKSA
00185     itsV += dtsc * (itsI - itsGl * (itsV - itsEl) -
00186        itsGe * (itsV - itsEe) - itsGi * (itsV - itsEi));
00187 
00188     // Check if the potential is lower than Ei -> if so, then clamp:
00189     if (itsV < itsEi) itsV = itsEi;
00190 
00191     // Check if voltage has exceeded threshold -> if so, then fire:
00192     if (itsV >= itsVth)
00193     {
00194       // raise the threshold proportionally to spike voltage
00195       // Use this one once we test the simple version
00196       //itsVth += itsVthMod * logsig(itsV - itsVth,0.0001,100);
00197       // simple version
00198       LINFO("itsVth %f",itsVth);
00199       LINFO("SETTING Vfire %f to V %f",itsVfire,itsV);
00200       itsVfire = itsV;
00201       spike = true;
00202       reset();
00203     }
00204 
00205     const float change = itsVth + dt.secs() * itsVthDecay;
00206     //LINFO("CHANGED VTH from %f to %f",itsVth,change);
00207     if(change >= itsVthBase)
00208       itsVth = change;
00209     // clamp the Vth base
00210     if(itsVth < itsVthBase)
00211       itsVth = itsVthBase;
00212   }
00213 
00214   // we are done, just keep track of new current time:
00215   itsT = t;
00216   return spike;
00217 }
00218 
00219 // ######################################################################
00220 inline void LeakyIntFireAdp::setV(const double val)
00221 { itsV = val + itsEi; }
00222 
00223 // ######################################################################
00224 inline float LeakyIntFireAdp::getV() const
00225 { return itsV; }
00226 
00227 // ######################################################################
00228 inline float LeakyIntFireAdp::getVth() const
00229 { return itsVth; }
00230 
00231 // ######################################################################
00232 inline float LeakyIntFireAdp::getVfire() const
00233 { return itsVfire; }
00234 
00235 // ######################################################################
00236 inline void LeakyIntFireAdp::setG(const float Exc, const float Inh)
00237 { itsGe = Exc; itsGi = Inh; }
00238 
00239 // ######################################################################
00240 inline void LeakyIntFireAdp::setGleak(const float Leak)
00241 { itsGl = Leak; }
00242 
00243 // ######################################################################
00244 inline void LeakyIntFireAdp::reset()
00245 { itsV = 0.0F; }
00246 
00247 // ######################################################################
00248 inline SimTime LeakyIntFireAdp::getTimeStep() const
00249 { return itsTimeStep; }
00250 
00251 // ######################################################################
00252 inline float LeakyIntFireAdp::logsig(const float x, const float o,
00253                                      const float b) const
00254 {
00255   return 1/(1+pow(2.718281,-(b*(x-o))));
00256 }
00257 
00258 // ######################################################################
00259 inline void LeakyIntFireAdp::setNewVth(const float salVal,
00260                                        const float VfireVal,
00261                                        const float dist)
00262 {
00263   // add more features later, just test with VfireVal alone for now
00264   LINFO("%f %f %f",salVal,VfireVal,dist);
00265 
00266   const float newVal = (1 + salVal + VfireVal)/(dist + 1);
00267 
00268   LINFO("OLD Vth %f new %f",itsVth,itsVth+newVal);
00269   itsVth += newVal;
00270   if(itsVth < itsVthBase)
00271     itsVth = itsVthBase;
00272 }
00273 #endif
00274 
00275 // ######################################################################
00276 /* So things look consistent in everyone's emacs... */
00277 /* Local Variables: */
00278 /* indent-tabs-mode: nil */
00279 /* End: */
Generated on Sun May 8 08:41:03 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3