1 /*
2 * ht_synapse.h
3 *
4 * This file is part of NEST.
5 *
6 * Copyright (C) 2004 The NEST Initiative
7 *
8 * NEST is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * NEST is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with NEST. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #ifndef HT_SYNAPSE_H
24 #define HT_SYNAPSE_H
25
26 // Includes from nestkernel:
27 #include "connection.h"
28
29 namespace nest
30 {
31
32 /* BeginUserDocs: synapse, Hill-Tononi plasticity
33
34 Short description
35 +++++++++++++++++
36
37 Synapse with depression after Hill & Tononi (2005)
38
39 Description
40 +++++++++++
41
42 This synapse implements the depression model described in [1, p 1678].
43
44 Synaptic dynamics are given by
45
46 .. math::
47
48 P'(t) = ( 1 - P ) / \tau_P \\
49 P(T+) = (1 - \delta_P) P(T-) \text{ for T : time of a spike } \\
50 P(t=0) = 1
51
52 :math:`w(t) = w_{max} * P(t)` is the resulting synaptic weight
53
54 For implementation details see:
55 `HillTononi_model <../model_details/HillTononiModels.ipynb>`_
56
57 .. warning::
58
59 This synaptic plasticity rule does not take
60 :doc:`precise spike timing <simulations_with_precise_spike_times>` into
61 account. When calculating the weight update, the precise spike time part
62 of the timestamp is ignored.
63
64 Parameters
65 ++++++++++
66
67 The following parameters can be set in the status dictionary:
68
69 ======== ====== =========================================================
70 tau_P ms Synaptic vesicle pool recovery time constant
71 delta_P real Fractional change in vesicle pool on incoming spikes
72 (unitless)
73 P real Current size of the vesicle pool [unitless, 0 <= P <= 1]
74 ======== ====== =========================================================
75
76 References
77 ++++++++++
78
79 .. [1] Hill S, Tononi G (2005). Modeling sleep and wakefulness in the
80 thalamocortical system. Journal of Neurophysiology. 93:1671-1698.
81 DOI: https://doi.org/10.1152/jn.00915.2004
82
83 Transmits
84 +++++++++
85
86 SpikeEvent
87
88 See also
89 ++++++++
90
91 ht_neuron, tsodyks_synapse, stdp_synapse, static_synapse
92
93 EndUserDocs */
94
95 template < typename targetidentifierT >
96 class ht_synapse : public Connection< targetidentifierT >
97 {
98 public:
99 typedef CommonSynapseProperties CommonPropertiesType;
100 typedef Connection< targetidentifierT > ConnectionBase;
101
102 /**
103 * Default Constructor.
104 * Sets default values for all parameters. Needed by GenericConnectorModel.
105 */
106 ht_synapse();
107
108 /**
109 * Copy constructor.
110 * Needs to be defined properly in order for GenericConnector to work.
111 */
112 ht_synapse( const ht_synapse& ) = default;
113
114 // Explicitly declare all methods inherited from the dependent base
115 // ConnectionBase. This avoids explicit name prefixes in all places these
116 // functions are used. Since ConnectionBase depends on the template parameter,
117 // they are not automatically found in the base class.
118 using ConnectionBase::get_delay_steps;
119 using ConnectionBase::get_delay;
120 using ConnectionBase::get_rport;
121 using ConnectionBase::get_target;
122
123 /**
124 * Default Destructor.
125 */
~ht_synapse()126 virtual ~ht_synapse()
127 {
128 }
129
130 /**
131 * Get all properties of this connection and put them into a dictionary.
132 */
133 virtual void get_status( DictionaryDatum& d ) const;
134
135 /**
136 * Set properties of this connection from the values given in dictionary.
137 */
138 virtual void set_status( const DictionaryDatum& d, ConnectorModel& cm );
139
140 /**
141 * Send an event to the receiver of this connection.
142 * \param e The event to send
143 * \param cp Common properties to all synapses (empty).
144 */
145 void send( Event& e, thread t, const CommonSynapseProperties& cp );
146
147 class ConnTestDummyNode : public ConnTestDummyNodeBase
148 {
149 public:
150 // Ensure proper overriding of overloaded virtual functions.
151 // Return values from functions are ignored.
152 using ConnTestDummyNodeBase::handles_test_event;
153 port
handles_test_event(SpikeEvent &,rport)154 handles_test_event( SpikeEvent&, rport )
155 {
156 return invalid_port_;
157 }
158 };
159
160 void
check_connection(Node & s,Node & t,rport receptor_type,const CommonPropertiesType &)161 check_connection( Node& s, Node& t, rport receptor_type, const CommonPropertiesType& )
162 {
163 ConnTestDummyNode dummy_target;
164 ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
165 }
166
167 //! allows efficient initialization from ConnectorModel::add_connection()
168 void
set_weight(double w)169 set_weight( double w )
170 {
171 weight_ = w;
172 }
173
174 private:
175 double weight_; //!< Synaptic weight
176
177 double tau_P_; //!< Time constant for recovery [ms]
178 double delta_P_; //!< Fractional decrease in pool size per spike
179
180 double p_; //!< Current pool size
181
182 double t_lastspike_; //!< Time point of last spike emitted
183 };
184
185
186 /**
187 * Send an event to the receiver of this connection.
188 * \param e The event to send
189 * \param p The port under which this connection is stored in the Connector.
190 */
191 template < typename targetidentifierT >
192 inline void
send(Event & e,thread t,const CommonSynapseProperties &)193 ht_synapse< targetidentifierT >::send( Event& e, thread t, const CommonSynapseProperties& )
194 {
195 // propagation t_lastspike -> t_spike, t_lastspike_ = 0 initially, p_ = 1
196 const double t_spike = e.get_stamp().get_ms();
197 const double h = t_spike - t_lastspike_;
198 p_ = 1 - ( 1 - p_ ) * std::exp( -h / tau_P_ );
199
200 // send the spike to the target
201 e.set_receiver( *get_target( t ) );
202 e.set_weight( weight_ * p_ );
203 e.set_delay_steps( get_delay_steps() );
204 e.set_rport( get_rport() );
205 e();
206
207 // reduce pool after spike is sent
208 p_ *= ( 1 - delta_P_ );
209
210 t_lastspike_ = t_spike;
211 }
212
213 template < typename targetidentifierT >
ht_synapse()214 ht_synapse< targetidentifierT >::ht_synapse()
215 : ConnectionBase()
216 , weight_( 1.0 )
217 , tau_P_( 500.0 )
218 , delta_P_( 0.125 )
219 , p_( 1.0 )
220 , t_lastspike_( 0.0 )
221 {
222 }
223
224 template < typename targetidentifierT >
225 void
get_status(DictionaryDatum & d)226 ht_synapse< targetidentifierT >::get_status( DictionaryDatum& d ) const
227 {
228 ConnectionBase::get_status( d );
229 def< double >( d, names::weight, weight_ );
230 def< double >( d, names::tau_P, tau_P_ );
231 def< double >( d, names::delta_P, delta_P_ );
232 def< double >( d, names::P, p_ );
233 def< long >( d, names::size_of, sizeof( *this ) );
234 }
235
236 template < typename targetidentifierT >
237 void
set_status(const DictionaryDatum & d,ConnectorModel & cm)238 ht_synapse< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm )
239 {
240 ConnectionBase::set_status( d, cm );
241
242 updateValue< double >( d, names::weight, weight_ );
243 updateValue< double >( d, names::tau_P, tau_P_ );
244 updateValue< double >( d, names::delta_P, delta_P_ );
245 updateValue< double >( d, names::P, p_ );
246
247 if ( tau_P_ <= 0.0 )
248 {
249 throw BadProperty( "tau_P > 0 required." );
250 }
251
252 if ( delta_P_ < 0.0 || delta_P_ > 1.0 )
253 {
254 throw BadProperty( "0 <= delta_P <= 1 required." );
255 }
256
257 if ( p_ < 0.0 || p_ > 1.0 )
258 {
259 throw BadProperty( "0 <= P <= 1 required." );
260 }
261 }
262
263 } // namespace
264
265 #endif // HT_SYNAPSE_H
266