00001 // 00002 // C++ Implementation: ODESystemBasedSpikingNeuron 00003 // 00004 // Description: 00005 // 00006 // 00007 // Author: Thomas Natschläger <tnatschl@lichtenberg>, (C) 2007 00008 // 00009 // Copyright: See COPYING file that comes with this distribution 00010 // 00011 // 00012 #include "ODESystemBasedSpikingNeuron.h" 00013 #include <iostream> 00014 00015 using std::cerr; 00016 using std::endl; 00017 00018 ThreadSpecificRandomDistribution< NormalDistribution > ODESystemBasedSpikingNeuron::noise; 00019 00020 ODESystemBasedSpikingNeuron::ODESystemBasedSpikingNeuron( size_t dim ) : ODESystem( dim ) { 00021 solver = NULL; 00022 } 00023 00024 int ODESystemBasedSpikingNeuron::init(InitializeInfo *ii) { 00025 // cerr << "ODESystemBasedSpikingNeuron::init( ): solver=" << solver << endl; 00026 setSystem( this ); 00027 if( ! solver ) 00028 solver = new odeiv::AdaptiveStepSolver( *this, odeiv::RungeKutta4() ); 00029 //solver = new odeiv::FixedStepSolver( *this, odeiv::RungeKutta4() ); 00030 return 0; 00031 } 00032 00033 ODESystemBasedSpikingNeuron::~ODESystemBasedSpikingNeuron() { 00034 if( solver ) 00035 delete solver; 00036 } 00037 00038 int ODESystemBasedSpikingNeuron::reset( double dt, double *y0 ) { 00039 if( ! solver ) 00040 init(NULL); 00041 SingleOutputSpikeSender::reset(); 00042 nStepsInRefr = -1; /* we are not refractory at the begining */ 00043 clearSynapticInput(); 00044 adjust( dt ); 00045 solver->reset( dt, *this, y0 ); 00046 Vm = y0[0]; 00047 // cerr << "ODESystemBasedSpikingNeuron::reset( double dt, double *y0 ): " << y0[0]<< endl; 00048 return 0; 00049 } 00050 00051 int ODESystemBasedSpikingNeuron::adjust( double dt ) { 00052 noise.set( NormalDistribution( 0.0, 1.0 ) ); 00053 return 0; 00054 } 00055 00056 int ODESystemBasedSpikingNeuron::advance( AdvanceInfo const &ai ) { 00057 00058 I0 = Em / Rm + Isyn + Iinject; 00059 G0 = 1.0 / Rm + Gsyn; 00060 00061 if ( Inoise > 0.0 ) { 00062 I0 += ( noise() * Inoise ); 00063 } 00064 00065 solver->advance( ai.t.in_sec(), ai.dt.in_sec(), *this ); 00066 copySolverStateToFields(); 00067 Vm = solver->y(0); 00068 00069 bool hasFired = false; 00070 00071 if ( ( ( --nStepsInRefr ) <= 0 ) && ( Vm >= Vthresh ) ) { 00072 // Note that the neuron has fired! 00073 hasFired = true; 00074 // calc number of steps how long we are refractory 00075 nStepsInRefr = ( int )( Trefract / ai.dt.in_sec() ) - 1; 00076 } 00077 00078 // clear synaptic input for next time step 00079 clearSynapticInput(); 00080 00081 // Return proper value 00082 if ( hasFired ) { 00083 out_port.setSpike( ai ); 00084 return ADVANCEFLAG_HASSPIKED; 00085 } else { 00086 return 0; 00087 } 00088 }