00001 /*!@file ModelNeuron/LowpassNeuron.H a very simple and abstract kind of 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: David Berg <dberg@usc.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/ModelNeuron/LowpassNeuron.H $ 00035 00036 #ifndef MODELNEURON_LOWPASSNEURON_H_DEFINED 00037 #define MODELNEURON_LOWPASSNEURON_H_DEFINED 00038 00039 #include "ModelNeuron/SimUnit.H" 00040 #include "ModelNeuron/LowPass.H" 00041 00042 // ###################################################################### 00043 // abstract neural model made from simple first order linear dynamic systems 00044 // 00045 // the underlying currents are represented by : 00046 // 00047 // dc/dt = (I_p - c)/t_p + (c - I_n)/t_n 00048 // 00049 // where c is the state variable, I_p are the possitive (excitatory) inputs and 00050 // I_n are the negative (inhibitory) inputs. t_p and t_n are the excitatory 00051 // and inhibitory decay factors. 00052 // 00053 // the state of the system is then given by : 00054 // 00055 // tau * dg/dt = -g + c + H 00056 // 00057 // ###################################################################### 00058 template <class RateFunc = RateFunctions::EmptyFunction, class IntType = LowPassExpEuler> 00059 class LowpassNeuronImpl: public SimUnit 00060 { 00061 public: 00062 //! Constructor with default params 00063 LowpassNeuronImpl(const double& tau_ef, // excite time constant msecs 00064 const double& tau_es, // excite time constant msecs 00065 const double& tau_if, // inhibit time constant msecs 00066 const double& tau_is, // inhibit time constant msecs 00067 const double& tau_s, // system time constant msecs 00068 const double& gain, // ration of excitatory to inhibitory gain 00069 const double& h, // system steady state 00070 const SimTime& timestep, // simulaton timestep 00071 const std::string& name = "LowpassNeuron", 00072 const std::string& units = "pA"); 00073 00074 //! Constructor with default params 00075 LowpassNeuronImpl(const double& tau_ef, // excite time constant msecs 00076 const double& tau_es, // excite time constant msecs 00077 const double& tau_if, // inhibit time constant msecs 00078 const double& tau_is, // inhibit time constant msecs 00079 const double& tau_s, // system time constant msecs 00080 const double& gain, // ration of excitatory to inhibitory gain 00081 const double& h, // system steady state 00082 const double& param1, // param 1 for the rate function 00083 const SimTime& timestep, // simulaton timestep 00084 const std::string& name = "LowpassNeuron", 00085 const std::string& units = "pA"); 00086 00087 //! Constructor with default params 00088 LowpassNeuronImpl(const double& tau_ef, // excite time constant msecs 00089 const double& tau_es, // excite time constant msecs 00090 const double& tau_if, // inhibit time constant msecs 00091 const double& tau_is, // inhibit time constant msecs 00092 const double& tau_s, // system time constant msecs 00093 const double& gain, //ration of excitatory to inhibitory gain 00094 const double& h, // system steady state 00095 const double& param1, //param 1 for the rate function 00096 const double& param2, //param 2 for the rate function 00097 const SimTime& timestep, //simulaton timestep 00098 const std::string& name = "LowpassNeuron", 00099 const std::string& units = "pA"); 00100 00101 //! destructor 00102 ~LowpassNeuronImpl() { }; 00103 00104 //! get the display output 00105 const double getDisplayOutput() const; 00106 00107 private: 00108 //! integrate a time step using exponential euler 00109 const double doIntegrate(const SimTime& dt, const double& ine, const double& inh); 00110 00111 //!initialize or reset internal variables 00112 void doInit(); 00113 00114 //! clone this object 00115 LowpassNeuronImpl<RateFunc,IntType>* doClone() const; 00116 00117 IntType itsEf, itsEs, itsIf, itsIs, itsG; //5 temporal filters to construct a neuron 00118 double itsEsf, itsEss, itsIsf, itsIss, itsGs;//state variables 00119 double itsGain; //inhibit to excite ratio 00120 RateFunc firingRate; // our firing rate functor 00121 }; 00122 00123 // ###################################################################### 00124 // typedefs 00125 // ###################################################################### 00126 typedef 00127 LowpassNeuronImpl<RateFunctions::EmptyFunction, LowPassExpEuler> LowpassNeuron; 00128 typedef 00129 LowpassNeuronImpl<RateFunctions::RectifyFunction, LowPassExpEuler> LowpassNeuronRectify; 00130 typedef 00131 LowpassNeuronImpl<RateFunctions::FullRectifyFunction, LowPassExpEuler> LowpassNeuronFullRectify; 00132 typedef 00133 LowpassNeuronImpl<RateFunctions::StepFunction, LowPassExpEuler> LowpassNeuronStep; 00134 typedef 00135 LowpassNeuronImpl<RateFunctions::MaxRectFunction, LowPassExpEuler> LowpassNeuronMaxRect; 00136 typedef 00137 LowpassNeuronImpl<RateFunctions::LogThreshFunction, LowPassExpEuler> LowpassNeuronLog; 00138 typedef 00139 LowpassNeuronImpl<RateFunctions::SigmoidFunction, LowPassExpEuler> LowpassNeuronSigmoid; 00140 00141 // ###################################################################### 00142 // register our objects 00143 // ###################################################################### 00144 namespace 00145 { 00146 typedef SimUnit::Factory LPNFactory; 00147 typedef SimUnit::Creator LPNCreator; 00148 //define creation functions 00149 struct RegisterLowpassNeuron 00150 { 00151 RegisterLowpassNeuron() 00152 { 00153 const double tauef = 10.0; 00154 const double taues = 150.0; 00155 const double tauif = 15.0; 00156 const double tauis = 150.0; 00157 const double taus = 15.0; 00158 const double gain = 1; 00159 00160 const SimTime time = SimTime::MSECS(1.0); 00161 00162 LPNFactory::instance().add("LowpassNeuron", 00163 LPNCreator::make<LowpassNeuron>(tauef, taues, tauif, tauis, 00164 taus, gain, -0.5, time)); 00165 LPNFactory::instance().add("LowpassNeuronRectify", 00166 LPNCreator::make<LowpassNeuronRectify>(tauef, taues, tauif, tauis, 00167 taus, gain, -0.5, 0.0, time)); 00168 LPNFactory::instance().add("LowpassNeuronFullRectify", 00169 LPNCreator::make<LowpassNeuronFullRectify>(tauef, taues, tauif, 00170 tauis, taus, gain, 0.0, time)); 00171 LPNFactory::instance().add("LowpassNeuronStep", 00172 LPNCreator::make<LowpassNeuronStep>(tauef, taues, tauif, 00173 tauis, taus, gain, -0.5, 0.0, 1.0, time)); 00174 LPNFactory::instance().add("LowpassNeuronMaxRect", 00175 LPNCreator::make<LowpassNeuronMaxRect>(tauef, taues, tauif, 00176 tauis, taus, gain, -0.5, 0.0, 1.0, time)); 00177 LPNFactory::instance().add("LowpassNeuronLog", 00178 LPNCreator::make<LowpassNeuronLog>(tauef, taues, tauif, 00179 tauis, taus, gain, 0.0, 0.1, time)); 00180 LPNFactory::instance().add("LowpassNeuronSigmoid", 00181 LPNCreator::make<LowpassNeuronSigmoid>(tauef, taues, tauif, 00182 tauis, taus, gain, -0.5, 0.55,12.0, time)); 00183 } 00184 }; 00185 static RegisterLowpassNeuron registerlpn; 00186 } 00187 00188 // ###################################################################### 00189 // ##### implementation for LowpassNeuronImpl 00190 // ###################################################################### 00191 // default case rate function takes 0 params 00192 // ###################################################################### 00193 template <class RateFunc, class IntType> inline 00194 LowpassNeuronImpl<RateFunc,IntType>::LowpassNeuronImpl(const double& tauef, 00195 const double& taues, 00196 const double& tauif, 00197 const double& tauis, 00198 const double& taus, 00199 const double& gain, 00200 const double& h, 00201 const SimTime& timestep, 00202 const std::string& name, 00203 const std::string& units) : 00204 SimUnit(timestep, IntType::RateType, name+RateFunc::name(), units), 00205 itsEf(timestep.msecs(), 0.0, tauef), itsEs(timestep.msecs(), 0.0, taues), 00206 itsIf(timestep.msecs(), 0.0, tauif), itsIs(timestep.msecs(), 0.0, tauis), 00207 itsG(timestep.msecs(), h, taus), itsEsf(0.0), itsEss(0.0), itsIsf(0.0), itsIss(0.0), 00208 itsGs(h), itsGain(gain), firingRate() { }; 00209 00210 // ###################################################################### 00211 // default case rate function takes 1 params 00212 // ###################################################################### 00213 template <class RateFunc, class IntType> inline 00214 LowpassNeuronImpl<RateFunc,IntType>::LowpassNeuronImpl(const double& tauef, 00215 const double& taues, 00216 const double& tauif, 00217 const double& tauis, 00218 const double& taus, 00219 const double& gain, 00220 const double& h, 00221 const double& param1, 00222 const SimTime& timestep, 00223 const std::string& name, 00224 const std::string& units) : 00225 SimUnit(timestep, IntType::RateType, name+RateFunc::name(), units), 00226 itsEf(timestep.msecs(), 0.0, tauef), itsEs(timestep.msecs(), 0.0, taues), 00227 itsIf(timestep.msecs(), 0.0, tauif), itsIs(timestep.msecs(), 0.0, tauis), 00228 itsG(timestep.msecs(), h, taus), itsEsf(0.0), itsEss(0.0), itsIsf(0.0), itsIss(0.0), 00229 itsGs(h), itsGain(gain), firingRate(param1) { }; 00230 00231 // ###################################################################### 00232 // default case rate function takes 2 params 00233 // ###################################################################### 00234 template <class RateFunc, class IntType> inline 00235 LowpassNeuronImpl<RateFunc,IntType>::LowpassNeuronImpl(const double& tauef, 00236 const double& taues, 00237 const double& tauif, 00238 const double& tauis, 00239 const double& taus, 00240 const double& gain, 00241 const double& h, 00242 const double& param1, 00243 const double& param2, 00244 const SimTime& timestep, 00245 const std::string& name, 00246 const std::string& units) : 00247 SimUnit(timestep, IntType::RateType, name+RateFunc::name(), units), 00248 itsEf(timestep.msecs(), 0.0, tauef), itsEs(timestep.msecs(), 0.0, taues), 00249 itsIf(timestep.msecs(), 0.0, tauif), itsIs(timestep.msecs(), 0.0, tauis), 00250 itsG(timestep.msecs(), h, taus), itsEsf(0.0), itsEss(0.0), itsIsf(0.0), itsIss(0.0), 00251 itsGs(h), itsGain(gain), firingRate(param1, param2) { }; 00252 00253 00254 // ###################################################################### 00255 template <class RateFunc, class IntType> inline 00256 const double LowpassNeuronImpl<RateFunc,IntType>::getDisplayOutput() const 00257 { 00258 return itsGs; 00259 } 00260 00261 // ###################################################################### 00262 template <class RateFunc, class IntType> inline 00263 const double LowpassNeuronImpl<RateFunc,IntType>::doIntegrate(const SimTime& dt, 00264 const double& ine, 00265 const double& inh) 00266 { 00267 //update our excitatory synapses 00268 itsEf.update(ine, itsEsf); //fast 00269 itsEs.update(ine, itsEss); //slow 00270 00271 //update our inhibitory synapses 00272 itsIf.update(inh, itsIsf); //fast 00273 itsIs.update(inh, itsIss); //slow 00274 00275 //excitatory drives go up if the system state is less than one, and inhibitory 00276 //go down if greater than -1, this helps keep the system stable. between those 00277 //ranges. 00278 00279 //relationship between system state and drive 00280 //only excites if < 1, else inhibit 00281 const double exc_point = 1.0 - itsGs; 00282 //only inhibits if > 1, else excite 00283 const double inh_point = itsGs + 1.0; 00284 //nonlinear relationhip, excite < rest, 0 at rest, and excite > rest, inhbit > 1 00285 const double exc_slow = (itsGs - itsG.H)*(itsGs - itsG.H)*exc_point; 00286 00287 //excitatory and inhibitory drives 00288 const double exc_drive = itsEsf*exc_point + itsEss*exc_slow; //itsEsf and itsEss will be pos 00289 const double inh_drive = itsIsf*inh_point + itsIss*inh_point; //itsIsf and itsIss will be neg 00290 00291 //system drive with weighted inhibition 00292 const double drive = exc_drive + itsGain*inh_drive; 00293 00294 //update system dynamics and return rate 00295 itsG.update(drive, itsGs); 00296 return firingRate(itsGs); 00297 } 00298 00299 // ###################################################################### 00300 template <class RateFunc, class IntType> inline 00301 void LowpassNeuronImpl<RateFunc,IntType>::doInit() 00302 { 00303 itsEss = 0.0; 00304 itsEsf = 0.0; 00305 itsIss = 0.0; 00306 itsIsf = 0.0; 00307 itsGs = itsG.H; 00308 } 00309 00310 // ###################################################################### 00311 template <class RateFunc, class IntType> inline 00312 LowpassNeuronImpl<RateFunc,IntType>* LowpassNeuronImpl<RateFunc,IntType>::doClone() const 00313 { 00314 return new LowpassNeuronImpl<RateFunc,IntType>(*this); 00315 } 00316 00317 #endif 00318 // ###################################################################### 00319 /* So things look consistent in everyone's emacs... */ 00320 /* Local Variables: */ 00321 /* indent-tabs-mode: nil */ 00322 /* End: */