IZNeuron.C

Go to the documentation of this file.
00001 /*!@file ModelNeuron/IZNeuron.C Class declarations for an izhikevich 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/IZNeuron.C $
00035 
00036 #include "ModelNeuron/IZNeuron.H"
00037 
00038 // ######################################################################
00039 // #####  functions for IZNeuronFunc:
00040 // ######################################################################
00041 void IZNeuronFunc::integrate()
00042 {
00043   //lets just run our difference equation one time step, dt.
00044   //Integrate V
00045   double temp = itsk * (itsV - itsVr) * (itsV - itsVth) - itsU + itsI;
00046   
00047   //multiply timestep converted to ms, and devide capacitance      
00048   itsV += (temp / itsCm);
00049   
00050   //Integrate U      
00051   itsU += itsa * (itsb * (itsV-itsVr) - itsU); 
00052   
00053   // Check if voltage has exceeded threshold -> if so, then fire:
00054   if (itsV > itsVp) 
00055     {
00056       itsSpike = true; 
00057       reset();
00058     }
00059   else
00060     itsSpike = false;
00061 }
00062 
00063 // ######################################################################
00064 void IZNeuronFunc::initialize() {
00065   itsSpike = false; 
00066   itsV = itsVr;
00067   itsI = 0.0;
00068   itsU = 0.0;
00069 }
00070 
00071 // ######################################################################
00072 void IZNeuronFunc::reset()
00073 {
00074   itsV =  itsc;
00075   itsU += itsd;
00076 }
00077 
00078 // ######################################################################
00079 void IZNeuronFunc::setup(const std::string& name, const bool use_random)
00080 {
00081   if (name.compare("RS") == 0)
00082     {
00083       itsa = 0.01;         // timescale of recovery variable
00084       itsb = 5.0;          // sensitivity of u to voltage
00085       itsc = -60.0;        // after-spike reset value of v
00086       itsd = 400.0;        // after-spike reset value of u
00087       itsk = 3.0;          // current voltage relationship
00088       itsCm = 100.0;       // in microfarads
00089       itsVr = -60.0;       // in millivolts
00090       itsVth = -50.0;      // in millivolts
00091       itsVp = 50.0;        // in millivolts
00092     }
00093   else if (name.compare("FS") == 0)
00094     {
00095       itsa = 0.15;         // timescale of recovery variable
00096       itsb = 8.0;          // sensitivity of u to voltage
00097       itsc = -55.0;        // after-spike reset value of v
00098       itsd = 200.0;        // after-spike reset value of u
00099       itsk = 1.0;          // current voltage relationship
00100       itsCm = 20.0;        // in microfarads
00101       itsVr = -55.0;       // in millivolts
00102       itsVth = -40.0;      // in millivolts
00103       itsVp = 25.0;        // in millivolts
00104     }
00105   else if (name.compare("EB") == 0)
00106     {
00107       itsa = 0.01;         // timescale of recovery variable
00108       itsb = 17.0;         // sensitivity of u to voltage
00109       itsc = -42.0;        // after-spike reset value of v
00110       itsd = 1.5;          // after-spike reset value of u
00111       itsk = 1.4;          // current voltage relationship
00112       itsCm = 20.0;        // in microfarads
00113       itsVr = -55.0;       // in millivolts
00114       itsVth = -50.0;      // in millivolts
00115       itsVp = 25.0;        // in millivolts
00116     }
00117   
00118   if (use_random)
00119     {
00120       //perterbate the parameters a little bit 
00121     }
00122 }
00123 
00124 // ######################################################################
00125 // ##### Functions for IZNeuron:
00126 // ######################################################################
00127 IZNeuron::IZNeuron(const double& a, const double& b,
00128                    const double& c, const double& d, const double& k, 
00129                    const double& Cm, const double& V_rest, 
00130                    const double& V_thresh, const double& V_peak, 
00131                    const std::string& name, const std::string& units) : 
00132   SimUnit(SimTime::MSECS(1.0), SimUnit::STRICT, name, units), 
00133   itsI(0.0), itsN(a,b,c,d,k,Cm,V_rest,V_thresh,V_peak), 
00134   ampa(SimTime::MSECS(1.0)), nmda(SimTime::MSECS(1.0)), 
00135   gabaa(SimTime::MSECS(1.0)), gabab(SimTime::MSECS(1.0))
00136 { 
00137 }
00138 
00139 // ######################################################################
00140 void IZNeuron::setV(const double& v)
00141 {
00142   itsN.setV(v);
00143 }
00144 
00145 // ######################################################################
00146 const double IZNeuron::getDisplayOutput() const
00147 {
00148   return getV();
00149 }
00150 
00151 // ######################################################################
00152 const uint IZNeuron::numSubs() const 
00153 {
00154   return 4; 
00155 }
00156  
00157 // ######################################################################
00158 const SimUnit& IZNeuron::getSub(const uint i) const
00159 {
00160   switch (i)
00161     {
00162     case 0:
00163       return ampa;
00164     case 1:
00165       return nmda;
00166     case 2:
00167       return gabaa;
00168     case 3:
00169       return gabab;
00170     default:
00171       LFATAL("Sub module position out of range.");
00172       return ampa;//will never execute;
00173     }
00174 }
00175 
00176 // ######################################################################
00177 SimUnit& IZNeuron::editSub(const uint i)
00178 {
00179   switch (i)
00180     {
00181     case 0:
00182       return ampa;
00183     case 1:
00184       return nmda;
00185     case 2:
00186       return gabaa;
00187     case 3:
00188       return gabab;
00189     default:
00190       LFATAL("Sub module position out of range.");
00191       return ampa;//will never execute;
00192     }
00193 }
00194 
00195 // ######################################################################
00196 const double IZNeuron::getV() const 
00197 {
00198   return itsN.getV(); 
00199 }
00200 
00201 // ######################################################################
00202 const double IZNeuron::getI() const 
00203 {
00204   return itsN.getCurrent(); 
00205 }
00206 
00207 // ######################################################################
00208 void  IZNeuron::setI(const double& current)
00209 {
00210   itsI = current;
00211 }
00212 
00213 // ######################################################################
00214 const IZNeuron& IZNeuron::setup(const std::string& name, const bool use_random)
00215 {
00216   itsN.setup(name, false);
00217   setName(name + getName());
00218   return *this;
00219 }
00220 
00221 // ######################################################################
00222 const double IZNeuron::doIntegrate(const SimTime& dt, 
00223                                    const double& exc, const double& inh)
00224 {
00225   //input to synapses
00226   const double inh1 = inh * -1.0;
00227   ampa.input(exc);
00228   nmda.input(exc);
00229   gabaa.input(inh1);
00230   gabab.input(inh1);
00231   
00232   //set the synapse voltage to cells membrane voltage
00233   ampa.setV(getV());
00234   nmda.setV(getV());
00235   gabaa.setV(getV());
00236   gabab.setV(getV());
00237   
00238   //evolve our synapse to current time
00239   ampa.evolve(getTime());
00240   nmda.evolve(getTime());
00241   gabaa.evolve(getTime());
00242   gabab.evolve(getTime());
00243   
00244   const double synCurr = ampa.getOutput() + nmda.getOutput() + 
00245     gabaa.getOutput() + gabab.getOutput();
00246   
00247   const double inp = itsI - synCurr;
00248   itsN.setCurrent(inp);  //set the current level
00249   itsN.integrate(); //integrate 1ms in the future
00250 
00251   return (double)itsN.getSpike(); //return any spikes
00252 }
00253 
00254 // ######################################################################
00255 void IZNeuron::doInit()
00256 {
00257   itsI = 0.0;
00258   itsN.initialize();
00259   ampa.initialize();
00260   nmda.initialize();
00261   gabaa.initialize();
00262   gabab.initialize();
00263 }
00264 
00265 // ######################################################################
00266 IZNeuron* IZNeuron::doClone() const 
00267 { return new IZNeuron(*this); };
00268 
00269 /*
00270 // ######################################################################
00271 // ##### Functions for IZNeuronSyn:
00272 // ######################################################################
00273   //! Constructor with default params
00274 IZNeuronSyn::IZNeuronSyn(const double& a, const double& b,
00275                       const double& c, const double& d, const double& k, 
00276                       const double& Cm, const double& V_rest, 
00277                       const double& V_thresh, const double& V_peak, 
00278                       const std::string& name, const std::string& units) : 
00279   SimUnit(SimTime::MSECS(1.0), SimUnit::STRICT, name, units), 
00280   itsI(0.0), itsN(a, b, c, d, k, Cm, V_rest, V_thresh, V_peak), itsS()
00281 { 
00282 }
00283 
00284 // ######################################################################
00285 IZNeuronSyn::IZNeuronSyn(const IZNeuronSyn& rhs) :
00286   SimUnit(rhs), itsI(rhs.itsI), itsN(rhs.itsN), itsS()
00287 {
00288   map::const_iterator i(rhs.itsS.begin()), end(rhs.itsS.begin());
00289   while (i != end)
00290     {
00291       itsS[i->first] = pair(i->second.first, 
00292                             i->second.second->clone());
00293       ++i;
00294     }
00295 }
00296 
00297 // ######################################################################
00298 IZNeuronSyn& IZNeuronSyn::operator=(const IZNeuronSyn& rhs)
00299 {
00300   if (this != &rhs)
00301     {
00302       SimUnit::operator=(rhs);
00303 
00304       itsI = rhs.itsI;
00305       itsN = rhs.itsN;
00306       map::const_iterator i(rhs.itsS.begin()), end(rhs.itsS.begin());
00307       while (i != end)
00308         {
00309           itsS[i->first] = pair(i->second.first, 
00310                                 i->second.second->clone());
00311           ++i;
00312         }
00313     }
00314   return *this;
00315 }
00316 
00317 // ######################################################################
00318 IZNeuronSyn::~IZNeuronSyn()
00319 { 
00320   cleanup();
00321 }
00322 
00323 // ######################################################################
00324 void IZNeuronSyn::setV(const double& v)
00325 {
00326   itsN.setV(v);
00327 }
00328 
00329 // ######################################################################
00330 const double IZNeuronSyn::getDisplayOutput() const 
00331 {
00332   return getV();
00333 }
00334 
00335 // ######################################################################
00336 const uint IZNeuronSyn::numSubs() const 
00337 {
00338   return (uint)itsS.size(); 
00339 }
00340  
00341 // ######################################################################
00342 const SimUnit& IZNeuronSyn::getSub(const uint pos) const
00343 {
00344   if (pos >= (uint)itsS.size() )
00345     LFATAL("You have not added %d synapses", pos);
00346   map::const_iterator i(itsS.begin());
00347     for (uint j = 0; j < pos; ++j)
00348     ++i;
00349     SimUnit* tmp = i->second.second;
00350     return *tmp;
00351 }
00352 
00353 // ######################################################################
00354 SimUnit& IZNeuronSyn::editSub(const uint pos)
00355 {
00356   if (pos >= (uint)itsS.size() )
00357     LFATAL("You have not added %d synapses", pos);
00358     map::iterator i(itsS.begin());
00359     for (uint j = 0; j < pos; ++j)
00360     ++i;
00361     SimUnit* tmp = i->second.second;
00362     return *tmp;
00363 }
00364 
00365 // ######################################################################
00366 const double IZNeuronSyn::getV() const 
00367 {
00368   return itsN.getV(); 
00369 }
00370 
00371 // ######################################################################
00372 const double IZNeuronSyn::getI() const 
00373 {
00374   return itsN.getCurrent(); 
00375 }
00376 
00377 // ######################################################################
00378 void  IZNeuronSyn::setI(const double& current)
00379 {
00380   itsI = current;
00381 }
00382 
00383 // ######################################################################
00384 const IZNeuronSyn& IZNeuronSyn::setup(const std::string& name, 
00385                                       const bool use_random)
00386 {
00387   itsN.setup(name, false);
00388   setName(name + getName());
00389   return *this;
00390 }
00391 
00392 // ######################################################################
00393 template <class S, class I>
00394 void IZNeuronSyn::addSynapse(const Synapse<S, I>& synapse, const double& ratio)
00395 {
00396   //make sure we dont already have it
00397   map::const_iterator i(itsS.find(S::id));
00398   if (i != itsS.end())
00399     LFATAL("Synapse %s of type already added", synapse.getName().c_str());
00400   else
00401     itsS[S::id] = pair(ratio, synapse.clone()); 
00402 }
00403 
00404 // ######################################################################
00405 void IZNeuronSyn::inputSynapse(const double& input, 
00406                                const Receptor::Type receptor)
00407 {
00408   map::const_iterator i(itsS.find(receptor));
00409   if (i != itsS.end())
00410     {
00411       i->second.second->input(i->second.first * input);
00412       ++i;
00413     }
00414 }
00415 
00416 // ######################################################################
00417 void IZNeuronSyn::cleanup()
00418 {
00419   map::iterator i(itsS.begin()), end(itsS.begin());
00420   while (i != end)
00421     {
00422       delete i->second.second;
00423       i->second.second = NULL;
00424       ++i;
00425     }
00426 }
00427 
00428 // ######################################################################
00429 const double IZNeuronSyn::doIntegrate(const SimTime& dt, 
00430                                       const double& exc, const double& inh)
00431 {
00432   double synCurr = 0.0;
00433   map::const_iterator i(itsS.begin()), end(itsS.end());
00434   while (i != end)
00435     {
00436       i->second.second->setV(getV());//set starting voltage
00437       i->second.second->evolve(getTime());//evolve our synapse to current time
00438       synCurr += i->second.second->getOutput(); //add synaptic currents
00439       ++i;
00440     }
00441 
00442   const double inp = itsI - synCurr;
00443   itsN.setCurrent(inp);  //set the current level
00444   itsN.integrate(); //integrate
00445   
00446   return (double)itsN.getSpike(); //return any spikes
00447 }
00448 
00449 // ######################################################################
00450 void IZNeuronSyn::doInit()
00451 {
00452   map::const_iterator i(itsS.begin()), end(itsS.end());
00453   while (i != end)
00454     (i++)->second.second->initialize();
00455   
00456   itsN.initialize();
00457 }
00458 
00459 // ######################################################################
00460 IZNeuronSyn* IZNeuronSyn::doClone() const 
00461 { return new IZNeuronSyn(*this); };
00462 
00463 // ######################################################################
00464 // specific instantiation for addSynapse
00465 // ######################################################################
00466 template
00467 void IZNeuronSyn::addSynapse(Synapse<Receptor::AMPA, LowPassExpEuler> const&, 
00468                              double const&);
00469 template
00470 void IZNeuronSyn::addSynapse(Synapse<Receptor::NMDA, LowPassExpEuler> const&, 
00471                              double const&);
00472 template
00473 void IZNeuronSyn::addSynapse(Synapse<Receptor::GABAA, LowPassExpEuler> const&, 
00474                              double const&);
00475 template
00476 void IZNeuronSyn::addSynapse(Synapse<Receptor::GABAB, LowPassExpEuler> const&, 
00477                              double const&);
00478   
00479 */
00480 // ######################################################################
00481 /* So things look consistent in everyone's emacs... */
00482 /* Local Variables: */
00483 /* indent-tabs-mode: nil */
00484 /* End: */
Generated on Sun May 8 08:05:21 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3