00001 #ifndef GENERICONEPAIRSTDPSYNAPSE_H_
00002 #define GENERICONEPAIRSTDPSYNAPSE_H_
00003
00004 #include <string>
00005 using std::string;
00006 #include <boost/format.hpp>
00007
00008 #include "PCSIMException.h"
00009 #include "SpikeBuffer.h"
00010 #include "SimObject.h"
00011 #include "SimNetwork.h"
00012 #include "GenericFroemkeDanStdpSynapse.h"
00013 #include "GenericStaticSpikingSynapse.h"
00014 #include "GenericDynamicSpikingSynapse.h"
00015 #include "GenericCurrentBasedSpikingSynapse.h"
00016 #include "ExponentialDecaySpikeResponse.h"
00017
00018 template<class BaseSyn>
00019 class GenericOnePairStdpSynapse: public BaseSyn
00020 {
00021 public:
00022 GenericOnePairStdpSynapse()
00023 {
00024 };
00025
00026 virtual ~GenericOnePairStdpSynapse()
00027 {
00028 };
00029
00031 bool activeSTDP;
00032
00034 float back_delay;
00035
00037 double Winit;
00038
00040 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;
00041
00042 virtual double maxRelevantSpikeTimeDiff()=0;
00043
00044 virtual int reset( double dt )
00045 {
00046 max_delta = maxRelevantSpikeTimeDiff();
00047 BaseSyn::W = Winit;
00048 return BaseSyn::reset(dt);
00049 };
00050
00051 virtual int spikeHit( spikeport_t port, SpikeEvent const& spike )
00052 {
00053 if( port == 0 ) {
00054 next_to_last_pre_spike = last_pre_spike;
00055 last_pre_spike = spike.time();
00056 if (activeSTDP)
00057 preSpikeHit( spike );
00058 return BaseSyn::spikeHit( port, spike );
00059 } else {
00060 next_to_last_post_spike = last_post_spike;
00061 last_post_spike = spike.time();
00062 if (activeSTDP)
00063 postSpikeHit( spike );
00064 return 0;
00065 }
00066 };
00067
00069 void preSpikeHit( SpikeEvent const& spike );
00070
00072 void postSpikeHit( SpikeEvent const& spike );
00073
00075 virtual void incoming(SimObject *post, SimObject::ID const& postid, SimObject::ID const& self, SimNetwork & net)
00076 {
00077 if( post->outputPortType( 0 ) == SimObject::spiking ) {
00078 net.addSpikeMessage( postid, (port_t)0, self, (port_t)1, Time::sec( back_delay ) );
00079 } else {
00080 throw(
00081 PCSIM::Exception( "GenericStdpSynapse::incoming",
00082 boost::str( boost::format( "Output port 0 of postsynaptic object must be spiking; which is not true for %1%!\n" ) % typeid(*post).name() ) )
00083 );
00084 }
00085 };
00086
00087 private:
00088 double max_delta;
00089 double last_pre_spike;
00090 double last_post_spike;
00091 double next_to_last_post_spike;
00092 double next_to_last_pre_spike;
00093 };
00094
00095 template<class BaseSyn>
00096 void GenericOnePairStdpSynapse<BaseSyn>::preSpikeHit( SpikeEvent const& pre_spike )
00097 {
00098 if (last_pre_spike - last_post_spike < max_delta )
00099 stdpLearning( last_post_spike - last_pre_spike, last_post_spike, pre_spike.time(), next_to_last_post_spike, next_to_last_pre_spike );
00100 }
00101
00102 template<class BaseSyn>
00103 void GenericOnePairStdpSynapse<BaseSyn>::postSpikeHit( SpikeEvent const& post_spike )
00104 {
00105 if (last_post_spike - last_pre_spike < max_delta )
00106 stdpLearning( last_post_spike - last_pre_spike, post_spike.time(), last_pre_spike, next_to_last_post_spike, next_to_last_pre_spike );
00107 }
00108
00109
00110 #endif