1 /*
2 * :copyright: Copyright 2006-2021 by the PyNN team, see AUTHORS.
3 * :license: CeCILL, see LICENSE for details.
4 *
5 */
6
7 #ifndef SIMPLE_STOCHASTIC_SYNAPSE_H
8 #define SIMPLE_STOCHASTIC_SYNAPSE_H
9
10 // Includes from nestkernel:
11 #include "connection.h"
12
13
14 /* BeginUserDocs: synapse, short-term plasticity
15
16 Short description
17 +++++++++++++++++
18
19 Synapse dropping spikes stochastically.
20
21 Description
22 +++++++++++
23
24 This synapse will deliver spikes with probability p.
25
26 Parameters
27 ++++++++++
28
29 = ==== =========================================================================================
30 p real probability that a spike is transmitted, default = 1.0 (i.e. spike is always transmitted)
31 = ==== =========================================================================================
32
33 Transmits
34 +++++++++
35
36 SpikeEvent
37
38 SeeAlso
39 +++++++
40
41 static_synapse, synapsedict
42 EndUserDocs */
43
44 namespace pynn
45 {
46
47 template < typename targetidentifierT >
48 class simple_stochastic_synapse : public nest::Connection< targetidentifierT >
49 {
50 private:
51 double weight_; //!< Synaptic weight
52 double p_; //!< Probability of spike transmission
53
54 public:
55 //! Type to use for representing common synapse properties
56 typedef nest::CommonSynapseProperties CommonPropertiesType;
57
58 //! Shortcut for base class
59 typedef nest::Connection< targetidentifierT > ConnectionBase;
60
61 /**
62 * Default Constructor.
63 * Sets default values for all parameters. Needed by GenericConnectorModel.
64 */
simple_stochastic_synapse()65 simple_stochastic_synapse()
66 : ConnectionBase()
67 , weight_( 1.0 )
68 , p_( 1.0 )
69 {
70 }
71
72 //! Default Destructor.
~simple_stochastic_synapse()73 ~simple_stochastic_synapse()
74 {
75 }
76
77 /**
78 * Helper class defining which types of events can be transmitted.
79 *
80 * These methods are only used to test whether a certain type of connection
81 * can be created.
82 *
83 * `handles_test_event()` should be added for all event types that the
84 * synapse can transmit. The methods shall return `invalid_port_`; the
85 * return value will be ignored.
86 *
87 * Since this is a synapse model dropping spikes, it is only for spikes,
88 * therefore we only implement `handles_test_event()` only for spike
89 * events.
90 *
91 * See Kunkel et al (2014), Sec 3.3.1, for background information.
92 */
93 class ConnTestDummyNode : public nest::ConnTestDummyNodeBase
94 {
95 public:
96 using nest::ConnTestDummyNodeBase::handles_test_event;
97 nest::port
handles_test_event(nest::SpikeEvent &,nest::rport)98 handles_test_event( nest::SpikeEvent&, nest::rport )
99 {
100 return nest::invalid_port_;
101 }
102
103 nest::port
handles_test_event(nest::DSSpikeEvent &,nest::rport)104 handles_test_event( nest::DSSpikeEvent&, nest::rport )
105 {
106 return nest::invalid_port_;
107 }
108 };
109
110 /**
111 * Check that requested connection can be created.
112 *
113 * This function is a boilerplate function that should be included unchanged
114 * in all synapse models. It is called before a connection is added to check
115 * that the connection is legal. It is a wrapper that allows us to call
116 * the "real" `check_connection_()` method with the `ConnTestDummyNode
117 * dummy_target;` class for this connection type. This avoids a virtual
118 * function call for better performance.
119 *
120 * @param s Source node for connection
121 * @param t Target node for connection
122 * @param receptor_type Receptor type for connection
123 * @param lastspike Time of most recent spike of presynaptic (sender) neuron,
124 * not used here
125 */
126 void
check_connection(nest::Node & s,nest::Node & t,nest::rport receptor_type,const CommonPropertiesType &)127 check_connection( nest::Node& s,
128 nest::Node& t,
129 nest::rport receptor_type,
130 const CommonPropertiesType& )
131 {
132 ConnTestDummyNode dummy_target;
133 ConnectionBase::check_connection_( dummy_target, s, t, receptor_type );
134 }
135
136 /**
137 * Send an event to the receiver of this connection.
138 * @param e The event to send
139 * @param t Thread
140 * @param cp Common properties to all synapses.
141 */
142 void send( nest::Event& e, nest::thread t, const CommonPropertiesType& cp );
143
144 // The following methods contain mostly fixed code to forward the
145 // corresponding tasks to corresponding methods in the base class and the w_
146 // data member holding the weight.
147
148 //! Store connection status information in dictionary
149 void get_status( DictionaryDatum& d ) const;
150
151 /**
152 * Set connection status.
153 *
154 * @param d Dictionary with new parameter values
155 * @param cm ConnectorModel is passed along to validate new delay values
156 */
157 void set_status( const DictionaryDatum& d, nest::ConnectorModel& cm );
158
159 //! Allows efficient initialization on construction
160 void
set_weight(double w)161 set_weight( double w )
162 {
163 weight_ = w;
164 }
165 };
166
167
168 template < typename targetidentifierT >
169 inline void
send(nest::Event & e,nest::thread t,const CommonPropertiesType & props)170 simple_stochastic_synapse< targetidentifierT >::send( nest::Event& e,
171 nest::thread t,
172 const CommonPropertiesType& props )
173 {
174 if ( nest::get_vp_specific_rng( t )->drand() < (1 - p_) ) // drop spike
175 return;
176
177 // Even time stamp, we send the spike using the normal sending mechanism
178 // send the spike to the target
179 e.set_weight( weight_ );
180 e.set_delay_steps( ConnectionBase::get_delay_steps() );
181 e.set_receiver( *ConnectionBase::get_target( t ) );
182 e.set_rport( ConnectionBase::get_rport() );
183 e(); // this sends the event
184 }
185
186 template < typename targetidentifierT >
187 void
get_status(DictionaryDatum & d)188 simple_stochastic_synapse< targetidentifierT >::get_status(
189 DictionaryDatum& d ) const
190 {
191 ConnectionBase::get_status( d );
192 def< double >( d, nest::names::weight, weight_ );
193 def< double >( d, nest::names::p, p_ );
194 def< long >( d, nest::names::size_of, sizeof( *this ) );
195 }
196
197 template < typename targetidentifierT >
198 void
set_status(const DictionaryDatum & d,nest::ConnectorModel & cm)199 simple_stochastic_synapse< targetidentifierT >::set_status(
200 const DictionaryDatum& d,
201 nest::ConnectorModel& cm )
202 {
203 ConnectionBase::set_status( d, cm );
204 updateValue< double >( d, nest::names::weight, weight_ );
205 updateValue< double >( d, nest::names::p, p_ );
206 }
207
208 } // namespace
209
210 #endif // simple_stochastic_synapse.h
211