00001 /*!@file Neuro/LeakyIntFire.H Class declarations for a 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/LeakyIntFire.H $ 00035 // $Id: LeakyIntFire.H 10729 2009-02-02 03:44:27Z itti $ 00036 // 00037 00038 #ifndef LEAKY_INTFIRE_H_DEFINED 00039 #define LEAKY_INTFIRE_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 LeakyIntFire 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 LeakyIntFire(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 00077 //! set input current (A) 00078 inline void input(const float current); 00079 00080 //! set membrane potential to given value relative to Ei (in Volts) 00081 inline void setV(const double val); 00082 00083 //! integrate for up to given time (in s) 00084 /*! Returns true if a spike was generated. */ 00085 inline bool integrate(const SimTime& t); 00086 00087 //! get current membrane potential (in V) 00088 inline float getV() const; 00089 00090 //! set excitatory and inhibitory conductances (S) 00091 inline void setG(const float Exc, const float Inh); 00092 00093 //! set leak conductance (S) 00094 inline void setGleak(const float Leak); 00095 00096 //! return our internal time step: 00097 inline SimTime getTimeStep() const; 00098 00099 private: 00100 inline void reset();// reset when a spike occurs 00101 00102 SimTime itsTimeStep;// time step to use for difference equations (in s) 00103 float itsV; // membrane potential in Volts 00104 float itsI; // input current in Amperes 00105 float itsGl; // leak conductance in Siemens 00106 float itsGe; // excitatory conductance in Siemens 00107 float itsGi; // inhibitory conductance in Siemens 00108 float itsC; // capacitance in Farads 00109 float itsEl; // driving potential for leak part, in Volts 00110 float itsEe; // driving potential for excitatory part, in Volts 00111 float itsEi; // driving potential for inhibitory part, in Volts 00112 float itsVth; // spike threshold voltage in Volts 00113 SimTime itsT; // time of last integration 00114 }; 00115 00116 // ###################################################################### 00117 // ##### Inline functions for LeakyIntFire: 00118 // ###################################################################### 00119 00120 inline LeakyIntFire::LeakyIntFire(const SimTime timeStep, 00121 const float El, 00122 const float Ee, 00123 const float Ei, 00124 const float Gl, 00125 const float Ge, 00126 const float Gi, 00127 const float Vth, 00128 const float C) : 00129 itsTimeStep(timeStep), itsV(Ei), itsI(0.0), itsGl(Gl), itsGe(Ge), itsGi(Gi), 00130 itsC(C), itsEl(El), itsEe(Ee), itsEi(Ei), itsVth(Vth), itsT(SimTime::ZERO()) 00131 { } 00132 00133 // ###################################################################### 00134 inline void LeakyIntFire::input(const float current) 00135 { itsI = current; } 00136 00137 // ###################################################################### 00138 inline bool LeakyIntFire::integrate(const SimTime& t) 00139 { 00140 // we run our difference equations with a time step of itsTimeStep; 00141 // let's here figure out how many iterations we will need to go from 00142 // itsT to t. We will iterate for a number of equal steps, with each 00143 // step as close to itsTimeStep as possible to that we end up at 00144 // time t after iterating for an integer number of time steps: 00145 const SimTime dt = SimTime::computeDeltaT((t - itsT), itsTimeStep); 00146 const float dtsc = float(dt.secs()) / itsC; 00147 00148 bool spike = false; 00149 for (SimTime tt = itsT; tt < t; tt += dt) 00150 { 00151 // Integrate : all units MKSA 00152 itsV += dtsc * (itsI - itsGl * (itsV - itsEl) - 00153 itsGe * (itsV - itsEe) - itsGi * (itsV - itsEi)); 00154 00155 // Check if the potential is lower than Ei -> if so, then clamp: 00156 if (itsV < itsEi) itsV = itsEi; 00157 00158 // Check if voltage has exceeded threshold -> if so, then fire: 00159 if (itsV >= itsVth) { spike = true; reset(); } 00160 } 00161 00162 // we are done, just keep track of new current time: 00163 itsT = t; 00164 return spike; 00165 } 00166 00167 // ###################################################################### 00168 inline void LeakyIntFire::setV(const double val) 00169 { itsV = val + itsEi; } 00170 00171 // ###################################################################### 00172 inline float LeakyIntFire::getV() const 00173 { return itsV; } 00174 00175 // ###################################################################### 00176 inline void LeakyIntFire::setG(const float Exc, const float Inh) 00177 { itsGe = Exc; itsGi = Inh; } 00178 00179 // ###################################################################### 00180 inline void LeakyIntFire::setGleak(const float Leak) 00181 { itsGl = Leak; } 00182 00183 // ###################################################################### 00184 inline void LeakyIntFire::reset() 00185 { itsV = 0.0F; } 00186 00187 // ###################################################################### 00188 inline SimTime LeakyIntFire::getTimeStep() const 00189 { return itsTimeStep; } 00190 00191 #endif 00192 00193 // ###################################################################### 00194 /* So things look consistent in everyone's emacs... */ 00195 /* Local Variables: */ 00196 /* indent-tabs-mode: nil */ 00197 /* End: */