LifNeuron.cpp

Go to the documentation of this file.
00001 
00005 #include "LifNeuron.h"
00006 
00007 #include <cmath>
00008 #include <iostream>
00009 using std::cerr;
00010 using std::endl;
00011 
00012 ThreadSpecificRandomDistribution< NormalDistribution > LifNeuronBase::noise_gen;
00013 
00015 
00016 LifNeuronBase::LifNeuronBase(float Rm, float Cm, float Vresting, float Vthresh, float Vreset,
00017                                                          float Vinit, float Trefract, float Inoise, float Iinject)
00018         : Rm(Rm), Cm(Cm), Vresting(Vresting), Vthresh(Vthresh), Vreset(Vreset)
00019            , Vinit(Vinit), Trefract(Trefract), Inoise(Inoise), Iinject(Iinject)            
00020         
00021 {
00022 }
00023 
00024 int LifNeuronBase::reset( double dt )
00025 {
00026     SingleOutputSpikeSender::reset();
00027 
00028 
00029     Vm             = Vinit;     /* set membrane voltage to its initial value */
00030     nStepsInRefr   = -1;        /* we are not refractory at the begining     */
00031     //cerr << "LifNeuron::reset\n\n";
00032     clearSynapticInput();
00033     adjust( dt );
00034     return 0;
00035 }
00036 
00038 
00039 LifNeuron::LifNeuron(float Rm, float Cm, float Vresting, float Vthresh, float Vreset, float Vinit, float Trefract,
00040                                           float Inoise, float Iinject)
00041         :LifNeuronBase(Rm, Cm, Vresting, Vthresh, Vreset, Vinit, Trefract, Inoise, Iinject)
00042 {
00043 }
00044 
00045 
00046 int LifNeuron::adjust( double dt )
00047 {
00048     _dt = dt ;
00049     double tau = Cm*Rm;          /* the membrane time constant                          */
00050     if ( tau > 0 ) {             /* init consts C1,C2 for exponential Euler integration */
00051         C1 = exp( - dt / tau );
00052         C2 = Rm*(1-C1);
00053     } else {
00054         C1 = 0.0;
00055         C2 = Rm;
00056     }
00057 
00058     //cerr << "LifNeuron::adjust\n\n";
00059 
00060     noise_gen.set( NormalDistribution( 0.0, 1.0 ) );
00061 
00062     if ( Rm > 0 )
00063         I0 =  Iinject + Vresting/Rm;
00064     else {
00065         // TheCsimError.add("LifNeuron::fieldChangeNotify: Rm <= 0!\n"); return -1;
00066     }
00067     return 0;
00068 }
00069 
00070 int LifNeuron::advance( AdvanceInfo const &ai )
00071 {
00072     bool register hasFired = false;
00073 
00074     if (nStepsInRefr > 0) {
00075         --nStepsInRefr;
00076     } else  {
00077         // all synapses have added the contributions to Isyn
00078         // we add I0
00079         double Itot = Isyn + I0;
00080         
00081         // Add white noise
00082         if (Inoise > 0.0) {             
00083                         Itot += (noise_gen() * Inoise);
00084         }
00085         
00086         // Add additional noise (custom implemented in derived classes)                 
00087         Itot += currentNoiseInput();
00088         
00089 
00090         // do the exponential Euler integration step
00091         Vm = C1 * Vm + C2 * Itot;
00092 
00093         if ( Vm >= Vthresh ) {
00094             // Note that the neuron has fired!
00095             hasFired = true;
00096             // calc number of steps how long we are refractory
00097             nStepsInRefr = (int)( Trefract / ai.dt.in_sec() ) - 1;
00098             // reset to 'Vreset'
00099             Vm = Vreset;
00100         }
00101     }
00102 
00103     // clear synaptic input for next time step
00104     clearSynapticInput();
00105 
00106     // Return proper value
00107     if( hasFired ) {
00108         out_port.setSpike( ai );
00109         return ADVANCEFLAG_HASSPIKED;
00110     } else {
00111         return 0;
00112     }
00113 }
00114 
00115 
00117 
00118 CbLifNeuron::CbLifNeuron(float Rm, float Cm, float Vresting, float Vthresh, float Vreset, float Vinit, 
00119                                              float Trefract, float Inoise, float Iinject)
00120         :LifNeuronBase(Rm, Cm, Vresting, Vthresh, Vreset, Vinit, Trefract, Inoise, Iinject)
00121 {
00122 }
00123 
00124 
00125 int CbLifNeuron::adjust( double dt )
00126 {
00127     _dt = dt;
00128     double tau = Cm*Rm;          /* the membrane time constant                          */
00129     if ( tau > 0 ) {             /* init consts C1,C2 for exponential Euler integration */
00130         C1 = exp( - dt / tau );
00131         C2 = Rm*(1-C1);
00132     } else {
00133         C1 = 0.0;
00134         C2 = Rm;
00135     }
00136 
00137     noise_gen.set( NormalDistribution( 0.0, 1.0 ) );
00138 
00139     if ( Rm > 0 )
00140         I0 =  Iinject + Vresting/Rm;
00141     else {
00142         // TheCsimError.add("LifNeuron::fieldChangeNotify: Rm <= 0!\n"); return -1;
00143     }
00144     return 0;
00145 }
00146 
00147 int CbLifNeuron::advance(AdvanceInfo const &ai )
00148 {
00149     bool register hasFired = false;
00150 
00151     if (nStepsInRefr > 0) {
00152         --nStepsInRefr;
00153     } else  {
00154         // all synapses have added the contributions to Isyn
00155         // we add I0
00156         double Itot = Isyn + I0;
00157         double Gtot = Gsyn + 1.0/Rm;
00158 
00159         if (Inoise > 0.0) {     
00160                         Itot += (noise_gen() * Inoise);     
00161         }
00162         
00163         // Add additional noise (custom implemented in derived classes)                 
00164         Itot += currentNoiseInput();
00165         Gtot += conductanceNoiseInput();        
00166 
00167         // do the exponential Euler integration step
00168         C1 = exp( - _dt / (Cm/Gtot) );
00169         Vm = C1*Vm+(1.0-C1)*(Itot/Gtot);
00170 
00171         if ( Vm >= Vthresh ) {
00172             // Note that the neuron has fired!
00173             hasFired = true;
00174             // calc number of steps how long we are refractory
00175             nStepsInRefr = (int)( Trefract / ai.dt.in_sec() ) - 1;
00176             // reset to 'Vreset'
00177             Vm = Vreset;
00178         }
00179     }
00180 
00181     // clear synaptic input for next time step
00182     clearSynapticInput();
00183 
00184     // Return proper value
00185     if( hasFired ) {
00186         out_port.setSpike( ai );
00187         return ADVANCEFLAG_HASSPIKED;
00188     } else {
00189         return 0;
00190     }
00191 }
00192 
00193 
00194         

Generated on Wed Jul 9 16:34:39 2008 for PCSIM by  doxygen 1.5.5