• Main Page
  • Classes
  • Files
  • File List

GenericPLPoissonNeuron.h

00001 #ifndef GENERICPLPOISSONNEURON_H_
00002 #define GENERICPLPOISSONNEURON_H_
00003 
00004 #include "EvSimObject.h"
00005 #include "ProjectedEventSender.h"
00006 #include "DirectEventSender.h"
00007 #include "SpikeResponse.h"
00008 #include "Synapse.h"
00009 #include "EvSimObjectTypeUtils.h"
00010 #include "RandomDistribution.h"
00011 #include "GenericPoissonNeuron.h"
00012 #include "Neuron.h"
00013 
00014 #include <limits>
00015 
00016 
00017 template <class Base >
00018 class GenericPLPoissNeuronRecalcVm : public Base {
00019 public:
00020 
00021     virtual ~GenericPLPoissNeuronRecalcVm() {};
00022 
00023     virtual unsigned registerInputSynapse(EvSimObject *input_synapse)
00024     {
00025         post_syn_potentials.push_back(static_cast<double *>(dynamic_cast<EvSimObject *>(input_synapse)->getVariablePtr("psr")));
00026         double * slope_ptr = static_cast<double *>(dynamic_cast<EvSimObject *>(input_synapse)->getVariablePtr("slope"));
00027         if ( slope_ptr )
00028             post_syn_slopes.push_back(slope_ptr);
00029         return post_syn_potentials.size() - 1;
00030     }
00031     
00032     virtual void reset(SimContext &sim_ctxt)
00033     {
00034         Base::reset(sim_ctxt);
00035         Base::Vm = 0;
00036         slope = 0;
00037         cur_time = 0;
00038     };
00039 
00040 protected:
00041     struct Accum {
00042         Accum() : s(0) {}
00043 
00044         inline void operator()(double *p) {s+=*p;}
00045 
00046         double s;
00047     };
00048 
00049     inline void updateVm(Time time)
00050     {
00051         if (time > cur_time) {
00052             Accum accumulate_vm;
00053             Accum accumulate_slope;
00054             std::for_each(post_syn_potentials.begin(), post_syn_potentials.end(), accumulate_vm);
00055             std::for_each(post_syn_slopes.begin(), post_syn_slopes.end(), accumulate_slope);
00056             Base::Vm = accumulate_vm.s;
00057             slope = accumulate_slope.s;
00058             cur_time = time;
00059         }
00060     }
00061 
00062     vector<double *> post_syn_potentials;
00063     vector<double *> post_syn_slopes;
00064     double slope;
00065     Time cur_time;
00066 };
00067 
00068 
00069 template <class Base >
00070 class GenericPLPoissNeuronFast : public Base {
00071 public:
00072     virtual ~GenericPLPoissNeuronFast() {};
00073 
00074     virtual void updatePSR(double psr, double psr_diff, Time time)
00075     {
00076         updateVm(time);
00077         Base::Vm += psr_diff;
00078     }
00079     
00080     virtual void updatePSRSlope(double psr_slope, double psr_slope_diff, Time time)
00081     {
00082         updateVm(time);
00083         slope += psr_slope_diff;
00084     }
00085 
00086     virtual bool requiresActiveSynapse() {
00087         return true;
00088     }
00089 
00090     inline void updateVm(Time time) {
00091         if (time > cur_time) {
00092             Base::Vm += (time-cur_time)*slope;
00093             cur_time = time;
00094         }
00095     };
00096     
00097     virtual void reset(SimContext &sim_ctxt)
00098     {
00099         Base::reset(sim_ctxt);
00100         Base::Vm = 0;
00101         slope = 0;
00102         cur_time = 0;
00103     };
00104     
00105 protected:
00106     double slope;
00107     Time cur_time;
00108 };
00109 
00110 
00111 template <class Base >
00112 class GenericPLExpPoissonNeuron : public Base {
00113 public:
00114 
00115     virtual ~GenericPLExpPoissonNeuron() {};
00116 
00117     float C;
00118 
00119     float A;
00120 
00121     float bias;
00122 
00123 protected:
00124     inline double firingRate()
00125     {
00126         return A*exp(C*(Base::Vm+bias));
00127     };
00128     
00129         void recalcNextSpikeTime(SimContext &sim_info, Time time)
00130         {
00131         Time next_spike_time = MAX_TIME;
00132         Base::updateVm(time);
00133         double rate = firingRate();
00134         if (rate > 0) {
00135             ExponentialDistribution exp_dist(1.0);
00136             double exp_dist_sample = exp_dist( *global_sim_random_eng );
00137             double next_time_projected = Base::slope/rate*exp_dist_sample;
00138             if (next_time_projected > (-1 + std::numeric_limits<double>::epsilon()) ) {
00139                 if (fabs(next_time_projected) <= std::numeric_limits<double>::epsilon())
00140                     next_spike_time = Base::cur_time + exp_dist_sample/rate;
00141                 else
00142                     next_spike_time = Base::cur_time + (1/Base::slope)*log( next_time_projected + 1 );
00143             }
00144         }        
00145         Base::changeProjectedEventTime(sim_info, (port_id_t)0, next_spike_time);
00146     };
00147 };
00148 
00149 #endif /* GENERICPLPOISSONNEURON_H_ */
00150 

Generated on Wed Sep 18 2013 11:25:40 for NEVESIM by  doxygen 1.7.1