00001 #ifndef GENERICEACHPAIRSTDPSYNAPSE_H_
00002 #define GENERICEACHPAIRSTDPSYNAPSE_H_
00003
00004 #include <boost/format.hpp>
00005
00006 #include <string>
00007 using std::string;
00008
00009 #include "PCSIMException.h"
00010 #include "SpikeBuffer.h"
00011 #include "SimObject.h"
00012 #include "SimNetwork.h"
00013 #include "GenericFroemkeDanStdpSynapse.h"
00014 #include "GenericStaticSpikingSynapse.h"
00015 #include "GenericDynamicSpikingSynapse.h"
00016 #include "GenericCurrentBasedSpikingSynapse.h"
00017 #include "ExponentialDecaySpikeResponse.h"
00018
00019 template<class BaseSyn>
00020 class GenericEachPairStdpSynapse: public BaseSyn
00021 {
00022 public:
00023 GenericEachPairStdpSynapse()
00024 {
00025 };
00026
00027 virtual ~GenericEachPairStdpSynapse()
00028 {
00029 };
00030
00032 int activeSTDP;
00033
00035 float back_delay;
00036
00038 double Winit;
00039
00040
00042 virtual double stdpLearning(const double & delta, const double & t_post, const double & t_pre, const double & t_prev_post, const double & t_prev_pre ) = 0;
00043
00044 virtual double maxRelevantSpikeTimeDiff()=0;
00045
00046 virtual int reset( double dt )
00047 {
00048 presynapticSpikes.reset( maxRelevantSpikeTimeDiff() );
00049 postsynapticSpikes.reset( maxRelevantSpikeTimeDiff() );
00050 BaseSyn::W = Winit;
00051 return BaseSyn::reset(dt);
00052 };
00053
00054 virtual int spikeHit( spikeport_t port, SpikeEvent const& spike )
00055 {
00056 if( port == 0 ) {
00057
00058 presynapticSpikes.insert( spike.time() );
00059 postsynapticSpikes.cutoff( spike.time() );
00060 if (activeSTDP)
00061 preSpikeHit( spike );
00062 return BaseSyn::spikeHit( port, spike );
00063 } else {
00064
00065 postsynapticSpikes.insert( spike.time() );
00066 presynapticSpikes.cutoff( spike.time() );
00067 if (activeSTDP)
00068 postSpikeHit( spike );
00069 return 0;
00070 }
00071 };
00072
00074 void preSpikeHit( SpikeEvent const& spike );
00075
00077 void postSpikeHit( SpikeEvent const& spike );
00078
00080 virtual void incoming(SimObject *post, SimObject::ID const& postid, SimObject::ID const& self, SimNetwork & net)
00081 {
00082 if( post->outputPortType( 0 ) == SimObject::spiking ) {
00083 net.addSpikeMessage( postid, (port_t)0, self, (port_t)1, Time::sec( back_delay ) );
00084 } else {
00085 throw(
00086 PCSIM::Exception( "GenericStdpSynapse::incoming",
00087 boost::str( boost::format( "Output port 0 of postsynaptic object must be spiking; which is not true for %1%!\n") % typeid(*post).name() ) )
00088 );
00089 }
00090 };
00091
00092 virtual SimObject::PortType inputPortType(port_t p) const {
00093 if (p < 2) {
00094 return SimObject::spiking;
00095 }
00096 return SimObject::undefined;
00097 }
00098
00099 private:
00100
00101 SpikeBuffer postsynapticSpikes;
00102 SpikeBuffer presynapticSpikes;
00103 };
00104
00105 template<class BaseSyn>
00106 void GenericEachPairStdpSynapse<BaseSyn>::preSpikeHit( SpikeEvent const& pre_spike )
00107 {
00108 double t_prev_pre = presynapticSpikes.second();
00109
00110 if (postsynapticSpikes.size() > 1) {
00111 SpikeBuffer::const_iterator post_spike = postsynapticSpikes.begin();
00112 SpikeBuffer::const_iterator post_spike_end = postsynapticSpikes.end_of_window();
00113 SpikeBuffer::const_iterator prev_post_spike = post_spike;
00114 for (prev_post_spike++; prev_post_spike != post_spike_end ; post_spike++, prev_post_spike++ ) {
00115 stdpLearning( *post_spike - pre_spike.time(), *post_spike, pre_spike.time(), *prev_post_spike, t_prev_pre );
00116 }
00117 }
00118
00119 }
00120
00121 template<class BaseSyn>
00122 void GenericEachPairStdpSynapse<BaseSyn>::postSpikeHit( SpikeEvent const& post_spike )
00123 {
00124 double t_prev_post = postsynapticSpikes.second();
00125
00126 if (presynapticSpikes.size() > 1) {
00127 SpikeBuffer::const_iterator pre_spike = presynapticSpikes.begin();
00128 SpikeBuffer::const_iterator pre_spike_end = presynapticSpikes.end_of_window();
00129
00130 SpikeBuffer::const_iterator prev_pre_spike = pre_spike;
00131 for (prev_pre_spike++; prev_pre_spike != pre_spike_end ; pre_spike++, prev_pre_spike++ ) {
00132 stdpLearning( post_spike.time() - *pre_spike, post_spike.time(), *pre_spike, t_prev_post, *prev_pre_spike );
00133 }
00134 }
00135
00136 }
00137
00138
00139 #endif