00001 #ifndef GENERICHOMEOSTATICSYNAPSE_H_
00002 #define GENERICHOMEOSTATICSYNAPSE_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
00013 #include "GenericStaticSpikingSynapse.h"
00014 #include "GenericDynamicSpikingSynapse.h"
00015 #include "GenericConductanceBasedSpikingSynapse.h"
00016 #include "ExponentialDecaySpikeResponse.h"
00017 #include "AlphaInfiniteSpikeResponse.h"
00018 #include "GenericGlutamateSynapse.h"
00019
00020 template<class BaseSyn>
00021 class GenericHomeostaticSynapse: public BaseSyn
00022 {
00023 public:
00024 GenericHomeostaticSynapse()
00025 {
00026 active=true;
00027 inhibitory=false;
00028 };
00029
00030 virtual ~GenericHomeostaticSynapse()
00031 {
00032 };
00033
00035 bool active;
00036
00037 bool inhibitory;
00038
00040 double Winit;
00041
00043 double alpha;
00044
00045 double activity_tau;
00046
00047 double activity_goal;
00048
00049 double activity_init;
00050
00051 double activity_decay;
00052
00053 double activity_post;
00054
00055 double activity_pre;
00056
00057 double Wex;
00058
00060 float back_delay;
00061
00062 virtual int reset( double dt )
00063 {
00064 activity_decay = exp( - dt / activity_tau);
00065 activity_post = activity_init;
00066 activity_pre = activity_init;
00067
00068 BaseSyn::reset(dt);
00069 return RESETFLAG_ACTIVATE;
00070 }
00071
00072 virtual int init(InitializeInfo *ii)
00073 {
00074 BaseSyn::W = Winit;
00075 return 0;
00076 }
00077
00078 virtual int advance(AdvanceInfo const &ai)
00079 {
00080 activity_post *= activity_decay;
00081 activity_pre *= activity_decay;
00082
00083 if (active)
00084 {
00085 double dW = alpha*activity_pre*(activity_goal - activity_post)*fabs(BaseSyn::W);
00086 double Wold = BaseSyn::W;
00087
00088 if (inhibitory)
00089 dW *= -1.0;
00090
00091 BaseSyn::W += dW;
00092
00093 if (Wold*BaseSyn::W < 0.0)
00094 BaseSyn::W = Wold*0.1;
00095
00096 if (BaseSyn::W > fabs(Wex))
00097 BaseSyn::W = Wex;
00098 else if (BaseSyn::W < -fabs(Wex))
00099 BaseSyn::W = -Wex;
00100 }
00101
00102 BaseSyn::advance(ai);
00103 return 0;
00104 }
00105
00106 virtual int spikeHit( spikeport_t port, SpikeEvent const& spike )
00107 {
00108 if( port == 0 ) {
00109 preSpikeHit( spike );
00110 BaseSyn::spikeHit( port, spike );
00111 } else {
00112 postSpikeHit( spike );
00113 }
00114 return 0;
00115 };
00116
00118 void preSpikeHit( SpikeEvent const& spike );
00119
00121 void postSpikeHit( SpikeEvent const& spike );
00122
00124 virtual void incoming(SimObject *post, SimObject::ID const& postid, SimObject::ID const& self, SimNetwork & net)
00125 {
00126 if( post->outputPortType( 0 ) == SimObject::spiking ) {
00127 net.addSpikeMessage( postid, (port_t)0, self, (port_t)1, Time::sec( back_delay ) );
00128 } else {
00129 throw(
00130 PCSIM::Exception( "GenericStdpSynapse::incoming",
00131 boost::str( boost::format( "Output port 0 of postsynaptic object must be spiking; which is not true for %1%!\n" ) % typeid(*post).name() ) )
00132 );
00133 }
00134 };
00135
00136 };
00137
00138 template<class BaseSyn>
00139 void GenericHomeostaticSynapse<BaseSyn>::preSpikeHit( SpikeEvent const& spike )
00140 {
00141 activity_pre += 1.0 / exp(-spike.delta/activity_tau);
00142 }
00143
00144 template<class BaseSyn>
00145 void GenericHomeostaticSynapse<BaseSyn>::postSpikeHit( SpikeEvent const& spike )
00146 {
00147 activity_post += 1.0 / exp(-spike.delta/activity_tau);
00148 }
00149
00150
00151 #endif