1 /*
2  *  diffusion_connection.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 DIFFUSION_CONNECTION_H
24 #define DIFFUSION_CONNECTION_H
25 
26 #include "connection.h"
27 
28 namespace nest
29 {
30 
31 /* BeginUserDocs: synapse, instantaneous rate
32 
33 Short description
34 +++++++++++++++++
35 
36 Synapse type for instantaneous rate connections between neurons of type siegert_neuron
37 
38 Description
39 +++++++++++
40 
41 diffusion_connection is a connector to create
42 instantaneous connections between neurons of type siegert_neuron. The
43 connection type is identical to type rate_connection_instantaneous
44 for instantaneous rate connections except for the two parameters
45 drift_factor and diffusion_factor substituting the parameter weight.
46 
47 These two factor origin from the mean-field reduction of networks of
48 leaky-integrate-and-fire neurons. In this reduction the input to the
49 neurons is characterized by its mean and its variance. The mean is
50 obtained by a sum over presynaptic activities (e.g as in eq.28 in
51 [1]_), where each term of the sum consists of the presynaptic activity
52 multiplied with the drift_factor. Similarly, the variance is obtained
53 by a sum over presynaptic activities (e.g as in eq.29 in [1]_), where
54 each term of the sum consists of the presynaptic activity multiplied
55 with the diffusion_factor. Note that in general the drift and
56 diffusion factors might differ from the ones given in eq. 28 and 29.,
57 for example in case of a reduction on the single neuron level or in
58 case of distributed in-degrees (see discussion in chapter 5.2 of [1]_)
59 
60 The values of the parameters delay and weight are ignored for
61 connections of this type.
62 
63 Transmits
64 +++++++++
65 
66 DiffusionConnectionEvent
67 
68 References
69 ++++++++++
70 
71 
72 .. [1] Hahne J, Dahmen D, Schuecker J, Frommer A,
73        Bolten M, Helias M, Diesmann, M. (2017).
74        Integration of continuous-time dynamics in a
75        spiking neural network simulator.
76        Frontiers in Neuroinformatics, 11:34.
77        DOI: https://doi.org/10.3389/fninf.2017.00034
78 
79 
80 See also
81 ++++++++
82 
83 siegert_neuron, rate_connection_instantaneous
84 
85 EndUserDocs */
86 
87 template < typename targetidentifierT >
88 class DiffusionConnection : public Connection< targetidentifierT >
89 {
90 
91 public:
92   // this line determines which common properties to use
93   typedef CommonSynapseProperties CommonPropertiesType;
94   typedef Connection< targetidentifierT > ConnectionBase;
95   typedef DiffusionConnectionEvent EventType;
96 
97   /**
98    * Default Constructor.
99    * Sets default values for all parameters. Needed by GenericConnectorModel.
100    */
DiffusionConnection()101   DiffusionConnection()
102     : ConnectionBase()
103     , drift_factor_( 1.0 )
104     , diffusion_factor_( 1.0 )
105   {
106   }
107 
108   // Explicitly declare all methods inherited from the dependent base
109   // ConnectionBase.
110   // This avoids explicit name prefixes in all places these functions are used.
111   // Since ConnectionBase depends on the template parameter, they are not
112   // automatically
113   // found in the base class.
114   using ConnectionBase::get_delay_steps;
115   using ConnectionBase::get_rport;
116   using ConnectionBase::get_target;
117 
118   void
check_connection(Node & s,Node & t,rport receptor_type,const CommonPropertiesType &)119   check_connection( Node& s, Node& t, rport receptor_type, const CommonPropertiesType& )
120   {
121     EventType ge;
122 
123     s.sends_secondary_event( ge );
124     ge.set_sender( s );
125     Connection< targetidentifierT >::target_.set_rport( t.handles_test_event( ge, receptor_type ) );
126     Connection< targetidentifierT >::target_.set_target( &t );
127   }
128 
129   /**
130    * Send an event to the receiver of this connection.
131    * \param e The event to send
132    * \param p The port under which this connection is stored in the Connector.
133    */
134   void
send(Event & e,thread t,const CommonSynapseProperties &)135   send( Event& e, thread t, const CommonSynapseProperties& )
136   {
137     e.set_drift_factor( drift_factor_ );
138     e.set_diffusion_factor( diffusion_factor_ );
139     e.set_receiver( *get_target( t ) );
140     e.set_rport( get_rport() );
141     e();
142   }
143 
144   void get_status( DictionaryDatum& d ) const;
145 
146   void set_status( const DictionaryDatum& d, ConnectorModel& cm );
147 
148   void
set_weight(double)149   set_weight( double )
150   {
151     throw BadProperty(
152       "Please use the parameters drift_factor and "
153       "diffusion_factor to specifiy the weights." );
154   }
155 
156   void
set_delay(double)157   set_delay( double )
158   {
159     throw BadProperty( "diffusion_connection has no delay." );
160   }
161 
162 private:
163   double weight_;
164   double drift_factor_;
165   double diffusion_factor_;
166 };
167 
168 template < typename targetidentifierT >
169 void
get_status(DictionaryDatum & d)170 DiffusionConnection< targetidentifierT >::get_status( DictionaryDatum& d ) const
171 {
172   ConnectionBase::get_status( d );
173   def< double >( d, names::weight, weight_ );
174   def< double >( d, names::drift_factor, drift_factor_ );
175   def< double >( d, names::diffusion_factor, diffusion_factor_ );
176   def< long >( d, names::size_of, sizeof( *this ) );
177 }
178 
179 template < typename targetidentifierT >
180 void
set_status(const DictionaryDatum & d,ConnectorModel & cm)181 DiffusionConnection< targetidentifierT >::set_status( const DictionaryDatum& d, ConnectorModel& cm )
182 {
183   // If the delay is set, we throw a BadProperty
184   if ( d->known( names::delay ) )
185   {
186     throw BadProperty( "diffusion_connection has no delay." );
187   }
188   // If the parameter weight is set, we throw a BadProperty
189   if ( d->known( names::weight ) )
190   {
191     throw BadProperty(
192       "Please use the parameters drift_factor and "
193       "diffusion_factor to specifiy the weights." );
194   }
195 
196   ConnectionBase::set_status( d, cm );
197   updateValue< double >( d, names::drift_factor, drift_factor_ );
198   updateValue< double >( d, names::diffusion_factor, diffusion_factor_ );
199 }
200 
201 } // namespace
202 
203 #endif /* #ifndef DIFFUSION_CONNECTION_H */
204