Completed
Push — master ( aa8a9c...92a332 )
by Andrei
01:34
created

central_element.__init__()   B

Complexity

Conditions 1

Size

Total Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 26
rs 8.8571
c 0
b 0
f 0
1
"""!
2
3
@brief Oscillatory Neural Network based on Hodgkin-Huxley Neuron Model
4
@details Based on article description:
5
         - D.Chik, R.Borisyuk, Y.Kazanovich. Selective attention model with spiking elements. 2009.
6
7
@authors Andrei Novikov ([email protected])
8
@date 2014-2016
9
@copyright GNU Public License
10
11
@cond GNU_PUBLIC_LICENSE
12
    PyClustering is free software: you can redistribute it and/or modify
13
    it under the terms of the GNU General Public License as published by
14
    the Free Software Foundation, either version 3 of the License, or
15
    (at your option) any later version.
16
    
17
    PyClustering is distributed in the hope that it will be useful,
18
    but WITHOUT ANY WARRANTY; without even the implied warranty of
19
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
    GNU General Public License for more details.
21
    
22
    You should have received a copy of the GNU General Public License
23
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24
@endcond
25
26
"""
27
28
from pyclustering.nnet import *;
0 ignored issues
show
Unused Code introduced by
IntEnum was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
initial_type was imported with wildcard, but is not used.
Loading history...
29
30
from scipy.integrate import odeint;
0 ignored issues
show
Configuration introduced by
The import scipy.integrate could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
31
32
from pyclustering.utils import allocate_sync_ensembles;
33
34
import numpy;
0 ignored issues
show
Configuration introduced by
The import numpy could not be resolved.

This can be caused by one of the following:

1. Missing Dependencies

This error could indicate a configuration issue of Pylint. Make sure that your libraries are available by adding the necessary commands.

# .scrutinizer.yml
before_commands:
    - sudo pip install abc # Python2
    - sudo pip3 install abc # Python3
Tip: We are currently not using virtualenv to run pylint, when installing your modules make sure to use the command for the correct version.

2. Missing __init__.py files

This error could also result from missing __init__.py files in your module folders. Make sure that you place one file in each sub-folder.

Loading history...
35
import random;
36
37
class hhn_parameters:
38
    """!
39
    @brief Describes parameters of Hodgkin-Huxley Oscillatory Network.
40
    
41
    @see hhn_network
42
    
43
    """
44
    
45
    def __init__(self):
46
        """!
47
        @brief    Default constructor of parameters for Hodgkin-Huxley Oscillatory Network.
48
        @details  Constructor initializes parameters by default non-zero values that can be
49
                  used for simple simulation.
50
        """
51
        
52
        ## Intrinsic noise.
53
        self.nu      = random.random() * 2.0 - 1.0;
54
        
55
        ## Maximal conductivity for sodium current.
56
        self.gNa     = 120.0 * (1 + 0.02 * self.nu);
57
        
58
        ## Maximal conductivity for potassium current.
59
        self.gK      = 36.0 * (1 + 0.02 * self.nu);
60
        
61
        ## Maximal conductivity for leakage current.
62
        self.gL      = 0.3 * (1 + 0.02 * self.nu);
63
        
64
        
65
        ## Reverse potential of sodium current [mV].
66
        self.vNa     = 50.0;
67
        
68
        ## Reverse potential of potassium current [mV].
69
        self.vK      = -77.0;
70
        
71
        ## Reverse potantial of leakage current [mV].
72
        self.vL      = -54.4;
73
        
74
        ## Rest potential [mV].
75
        self.vRest   = -65.0;    
76
        
77
        
78
        ## External current [mV] for central element 1.
79
        self.Icn1    = 5.0;
80
        
81
        ## External current [mV] for central element 2.
82
        self.Icn2    = 30.0;
83
        
84
        
85
        ## Synaptic reversal potential [mV] for inhibitory effects.
86
        self.Vsyninh = -80.0;    
87
        
88
        ## Synaptic reversal potential [mV] for exciting effects.
89
        self.Vsynexc = 0.0;
90
        
91
        ## Alfa-parameter for alfa-function for inhibitory effect.
92
        self.alfa_inhibitory     = 6.0;
93
        
94
        ## Betta-parameter for alfa-function for inhibitory effect.
95
        self.betta_inhibitory    = 0.3;
96
        
97
        
98
        ## Alfa-parameter for alfa-function for excitatoty effect.
99
        self.alfa_excitatory     = 40.0;
100
        
101
        ## Betta-parameter for alfa-function for excitatoty effect.
102
        self.betta_excitatory    = 2.0;
103
        
104
        
105
        ## Strength of the synaptic connection from PN to CN1.
106
        self.w1 = 0.1;
107
        
108
        ## Strength of the synaptic connection from CN1 to PN.
109
        self.w2 = 9.0;
110
        
111
        ## Strength of the synaptic connection from CN2 to PN.
112
        self.w3 = 5.0;
113
        
114
        
115
        ## Period of time [ms] when high strength value of synaptic connection exists from CN2 to PN.
116
        self.deltah = 650.0;
117
        
118
        ## Threshold of the membrane potential that should exceeded by oscillator to be considered as an active.
119
        self.threshold = -10;
120
        
121
        ## Affects pulse counter.
122
        self.eps = 0.16;
123
124
125
class central_element:
126
    """!
127
    @brief Central element consist of two central neurons that are described by a little bit different dynamic than peripheral.
128
    
129
    @see hhn_network
130
    
131
    """
132
    
133
    def __init__(self):
134
        """!
135
        @brief Constructor of central element.
136
        
137
        """
138
        
139
        ## Membrane potential of cenral neuron (V).
140
        self.membrane_potential      = 0.0;
141
        
142
        ## Activation conductance of the sodium channel (m).
143
        self.active_cond_sodium      = 0.0;
144
        
145
        ## Inactivaton conductance of the sodium channel (h).
146
        self.inactive_cond_sodium    = 0.0;
147
        
148
        ## Inactivaton conductance of the sodium channel (h)
149
        self.active_cond_potassium   = 0.0;
150
        
151
        ## Times of pulse generation by central neuron.
152
        self.pulse_generation_time = None;
153
        
154
        ## Spike generation of central neuron.
155
        self.pulse_generation = False;
156
        
157
        ## Timestamps of generated pulses.
158
        self.pulse_generation_time = [];
159
    
160
    def __repr__(self):
161
        """!
162
        @brief Returns string that represents central element.
163
        
164
        """
165
        return "%s, %s" % (self.membrane_potential, self.pulse_generation_time);
166
167
168
class hhn_network(network):
169
    """!
170
    @brief Oscillatory Neural Network with central element based on Hodgkin-Huxley neuron model. Interaction between oscillators is performed via
171
           central element (no connection between oscillators that are called as peripheral). Peripheral oscillators receive external stimulus.
172
           Central element consist of two oscillators: the first is used for synchronization some ensemble of oscillators and the second controls
173
           synchronization of the first cental oscillator with verious ensembles.
174
    
175
    Example:
176
    @code
177
        # change period of time when high strength value of synaptic connection exists from CN2 to PN.
178
        params = hhn_parameters();
179
        params.deltah = 400;
180
        
181
        # create oscillatory network with stimulus
182
        net = hhn_network(6, [0, 0, 25, 25, 47, 47], params);
183
        
184
        # simulate network
185
        (t, dyn) = net.simulate(1200, 600);
186
        
187
        # draw network output during simulation
188
        draw_dynamics(t, dyn, x_title = "Time", y_title = "V", separate = True);
189
    @endcode
190
    
191
    """
192
    
193
    def __init__(self, num_osc, stimulus = None, parameters = None, type_conn = None, type_conn_represent = conn_represent.MATRIX):
194
        """!
195
        @brief Constructor of oscillatory network based on Hodgkin-Huxley meuron model.
196
        
197
        @param[in] num_osc (uint): Number of peripheral oscillators in the network.
198
        @param[in] stimulus (list): List of stimulus for oscillators, number of stimulus should be equal to number of peripheral oscillators.
199
        @param[in] parameters (hhn_parameters): Parameters of the network.
200
        @param[in] type_conn (conn_type): Type of connections between oscillators in the network (ignored for this type of network).
201
        @param[in] type_conn_represent (conn_represent): Internal representation of connection in the network: matrix or list.
202
        
203
        """
204
          
205
        super().__init__(num_osc, conn_type.NONE, type_conn_represent);
206
        
207
        self._membrane_dynamic_pointer = None;        # final result is stored here.
208
        
209
        self._membrane_potential        = [0.0] * self._num_osc;
210
        self._active_cond_sodium        = [0.0] * self._num_osc;
211
        self._inactive_cond_sodium      = [0.0] * self._num_osc;
212
        self._active_cond_potassium     = [0.0] * self._num_osc;
213
        self._link_activation_time      = [0.0] * self._num_osc;
214
        self._link_pulse_counter        = [0.0] * self._num_osc;
215
        self._link_deactivation_time    = [0.0] * self._num_osc;
216
        self._link_weight3              = [0.0] * self._num_osc;
217
        self._pulse_generation_time     = [ [] for i in range(self._num_osc) ];
218
        self._pulse_generation          = [False] * self._num_osc;
219
        
220
        self._noise = [random.random() * 2.0 - 1.0 for i in range(self._num_osc)];
221
        
222
        self._central_element = [central_element(), central_element()];
223
        
224
        if (stimulus is None):
225
            self._stimulus = [0.0] * self._num_osc;
226
        else:
227
            self._stimulus = stimulus;
228
        
229
        if (parameters is not None):
230
            self._params = parameters;
231
        else:
232
            self._params = hhn_parameters();
233
    
234
    
235
    def simulate(self, steps, time, solution = solve_type.RK4, collect_dynamic = True):
236
        """!
237
        @brief Performs static simulation of oscillatory network based on Hodgkin-Huxley neuron model.
238
        
239
        @param[in] steps (uint): Number steps of simulations during simulation.
240
        @param[in] time (double): Time of simulation.
241
        @param[in] solution (solve_type): Type of solver for differential equations.
242
        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.
243
        
244
        @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' = True, than return dynamic for the whole simulation time,
245
                otherwise returns only last values (last step of simulation) of dynamic.
246
        
247
        """
248
        
249
        return self.simulate_static(steps, time, solution, collect_dynamic);
250
    
251
    
252
    def simulate_static(self, steps, time, solution = solve_type.RK4, collect_dynamic = False):
253
        """!
254
        @brief Performs static simulation of oscillatory network based on Hodgkin-Huxley neuron model.
255
        
256
        @param[in] steps (uint): Number steps of simulations during simulation.
257
        @param[in] time (double): Time of simulation.
258
        @param[in] solution (solve_type): Type of solver for differential equations.
259
        @param[in] collect_dynamic (bool): If True - returns whole dynamic of oscillatory network, otherwise returns only last values of dynamics.
260
        
261
        @return (list) Dynamic of oscillatory network. If argument 'collect_dynamic' = True, than return dynamic for the whole simulation time,
262
                otherwise returns only last values (last step of simulation) of dynamic.
263
        
264
        """
265
        
266
        self._membrane_dynamic_pointer = None;
267
        
268
        # Check solver before simulation
269
        if (solution == solve_type.FAST):
270
            raise NameError("Solver FAST is not support due to low accuracy that leads to huge error.");
271
        elif (solution == solve_type.RKF45):
272
            raise NameError("Solver RKF45 is not support in python version.");
273
        
274
        dyn_memb = None;
275
        dyn_time = None;
276
        
277
        # Store only excitatory of the oscillator
278
        if (collect_dynamic == True):
279
            dyn_memb = [];
280
            dyn_time = [];
281
            
282
        step = time / steps;
283
        int_step = step / 10.0;
284
        
285
        for t in numpy.arange(step, time + step, step):
286
            # update states of oscillators
287
            memb = self._calculate_states(solution, t, step, int_step);
288
            
289
            # update states of oscillators
290
            if (collect_dynamic == True):
291
                dyn_memb.append(memb);
292
                dyn_time.append(t);
293
            else:
294
                dyn_memb = memb;
295
                dyn_time = t;
296
        
297
        self._membrane_dynamic_pointer = dyn_memb;
298
        return (dyn_time, dyn_memb);
299
    
300
    
301
    def _calculate_states(self, solution, t, step, int_step):
0 ignored issues
show
Unused Code introduced by
The argument solution seems to be unused.
Loading history...
302
        """!
303
        @brief Caclculates new state of each oscillator in the network. Returns only excitatory state of oscillators.
304
        
305
        @param[in] solution (solve_type): Type solver of the differential equations.
306
        @param[in] t (double): Current time of simulation.
307
        @param[in] step (uint): Step of solution at the end of which states of oscillators should be calculated.
308
        @param[in] int_step (double): Differentiation step that is used for solving differential equation.
309
        
310
        @return (list) New states of membrance potentials for peripheral oscillators and for cental elements as a list where
311
                the last two values correspond to central element 1 and 2.
312
                 
313
        """
314
        
315
        next_membrane           = [0.0] * self._num_osc;
316
        next_active_sodium      = [0.0] * self._num_osc;
317
        next_inactive_sodium    = [0.0] * self._num_osc;
318
        next_active_potassium   = [0.0] * self._num_osc;
319
        
320
        # Update states of oscillators
321
        for index in range (0, self._num_osc, 1):
322
            result = odeint(self.hnn_state, 
323
                            [ self._membrane_potential[index], self._active_cond_sodium[index], self._inactive_cond_sodium[index], self._active_cond_potassium[index] ], 
324
                            numpy.arange(t - step, t, int_step), 
325
                            (index , ));
326
                            
327
            [ next_membrane[index], next_active_sodium[index], next_inactive_sodium[index], next_active_potassium[index] ] = result[len(result) - 1][0:4];        
328
        
329
        next_cn_membrane            = [0.0, 0.0];
330
        next_cn_active_sodium       = [0.0, 0.0];
331
        next_cn_inactive_sodium     = [0.0, 0.0];
332
        next_cn_active_potassium    = [0.0, 0.0];
333
        
334
        # Update states of central elements
335
        for index in range(0, len(self._central_element)):
336
            result = odeint(self.hnn_state, 
337
                            [ self._central_element[index].membrane_potential, self._central_element[index].active_cond_sodium, self._central_element[index].inactive_cond_sodium, self._central_element[index].active_cond_potassium ], 
338
                            numpy.arange(t - step, t, int_step), 
339
                            (self._num_osc + index , ));
340
                            
341
            [ next_cn_membrane[index], next_cn_active_sodium[index], next_cn_inactive_sodium[index], next_cn_active_potassium[index] ] = result[len(result) - 1][0:4];
342
        
343
        # Noise generation
344
        self._noise = [ 1.0 + 0.01 * (random.random() * 2.0 - 1.0) for i in range(self._num_osc)];
345
        
346
        # Updating states of PNs
347
        self.__update_peripheral_neurons(t, step, next_membrane, next_active_sodium, next_inactive_sodium, next_active_potassium);
348
        
349
        # Updation states of CN
350
        self.__update_central_neurons(t, next_cn_membrane, next_cn_active_sodium, next_cn_inactive_sodium, next_cn_active_potassium);
351
        
352
        return next_membrane + next_cn_membrane;
353
    
354
    
355
    def __update_peripheral_neurons(self, t, step, next_membrane, next_active_sodium, next_inactive_sodium, next_active_potassium):
356
        """!
357
        @brief Update peripheral neurons in line with new values of current in channels.
358
        
359
        @param[in] t (doubles): Current time of simulation.
360
        @param[in] step (uint): Step (time duration) during simulation when states of oscillators should be calculated.
361
        @param[in] next_membrane (list): New values of membrane potentials for peripheral neurons.
362
        @Param[in] next_active_sodium (list): New values of activation conductances of the sodium channels for peripheral neurons.
363
        @param[in] next_inactive_sodium (list): New values of inactivaton conductances of the sodium channels for peripheral neurons.
364
        @param[in] next_active_potassium (list): New values of activation conductances of the potassium channel for peripheral neurons.
365
        
366
        """
367
        
368
        self._membrane_potential = next_membrane[:];
369
        self._active_cond_sodium = next_active_sodium[:];
370
        self._inactive_cond_sodium = next_inactive_sodium[:];
371
        self._active_cond_potassium = next_active_potassium[:];
372
        
373
        for index in range(0, self._num_osc):
374
            if (self._pulse_generation[index] is False):
375
                if (self._membrane_potential[index] > 0.0):
376
                    self._pulse_generation[index] = True;
377
                    self._pulse_generation_time[index].append(t);
378
            else:
379
                if (self._membrane_potential[index] < 0.0):
380
                    self._pulse_generation[index] = False;
381
            
382
            # Update connection from CN2 to PN
383
            if (self._link_weight3[index] == 0.0):
384
                if ( (self._membrane_potential[index] > self._params.threshold) and (self._membrane_potential[index] > self._params.threshold) ):
385
                    self._link_pulse_counter[index] += step;
386
                
387
                    if (self._link_pulse_counter[index] >= 1 / self._params.eps):
388
                        self._link_weight3[index] = self._params.w3;
389
                        self._link_activation_time[index] = t;
390
            else:
391
                if ( not ((self._link_activation_time[index] < t) and (t < self._link_activation_time[index] + self._params.deltah)) ):
392
                    self._link_weight3[index] = 0.0;
393
                    self._link_pulse_counter[index] = 0.0;
394
    
395
    
396
    def __update_central_neurons(self, t, next_cn_membrane, next_cn_active_sodium, next_cn_inactive_sodium, next_cn_active_potassium):
397
        """!
398
        @brief Update of central neurons in line with new values of current in channels.
399
        
400
        @param[in] t (doubles): Current time of simulation.
401
        @param[in] next_membrane (list): New values of membrane potentials for central neurons.
402
        @Param[in] next_active_sodium (list): New values of activation conductances of the sodium channels for central neurons.
403
        @param[in] next_inactive_sodium (list): New values of inactivaton conductances of the sodium channels for central neurons.
404
        @param[in] next_active_potassium (list): New values of activation conductances of the potassium channel for central neurons.
405
        
406
        """
407
        
408
        for index in range(0, len(self._central_element)):
409
            self._central_element[index].membrane_potential = next_cn_membrane[index];
410
            self._central_element[index].active_cond_sodium = next_cn_active_sodium[index];
411
            self._central_element[index].inactive_cond_sodium = next_cn_inactive_sodium[index];
412
            self._central_element[index].active_cond_potassium = next_cn_active_potassium[index];
413
            
414
            if (self._central_element[index].pulse_generation is False):
415
                if (self._central_element[index].membrane_potential > 0.0):
416
                    self._central_element[index].pulse_generation = True;
417
                    self._central_element[index].pulse_generation_time.append(t);
418
            else:
419
                if (self._central_element[index].membrane_potential < 0.0):
420
                    self._central_element[index].pulse_generation = False;
421
    
422
    
423
    def hnn_state(self, inputs, t, argv):
424
        """!
425
        @brief Returns new values of excitatory and inhibitory parts of oscillator and potential of oscillator.
426
        
427
        @param[in] inputs (list): States of oscillator for integration [v, m, h, n] (see description below).
428
        @param[in] t (double): Current time of simulation.
429
        @param[in] argv (tuple): Extra arguments that are not used for integration - index of oscillator.
430
        
431
        @return (list) new values of oscillator [v, m, h, n], where:
432
                v - membrane potantial of oscillator,
433
                m - activation conductance of the sodium channel,
434
                h - inactication conductance of the sodium channel,
435
                n - activation conductance of the potassium channel.
436
        
437
        """
438
        
439
        index = argv;
440
        
441
        v = inputs[0]; # membrane potential (v).
442
        m = inputs[1]; # activation conductance of the sodium channel (m).
443
        h = inputs[2]; # inactivaton conductance of the sodium channel (h).
444
        n = inputs[3]; # activation conductance of the potassium channel (n).
445
        
446
        # Calculate ion current
447
        # gNa * m[i]^3 * h * (v[i] - vNa) + gK * n[i]^4 * (v[i] - vK) + gL  (v[i] - vL)
448
        active_sodium_part = self._params.gNa * (m ** 3) * h * (v - self._params.vNa);
449
        inactive_sodium_part = self._params.gK * (n ** 4) * (v - self._params.vK);
450
        active_potassium_part = self._params.gL * (v - self._params.vL);
451
        
452
        Iion = active_sodium_part + inactive_sodium_part + active_potassium_part;
453
        
454
        Iext = 0.0;
455
        Isyn = 0.0;
456
        if (index < self._num_osc): 
457
            # PN - peripheral neuron - calculation of external current and synaptic current.
458
            Iext = self._stimulus[index] * self._noise[index];    # probably noise can be pre-defined for reducting compexity            
459
            
460
            memory_impact1 = 0.0;
461
            for i in range(0, len(self._central_element[0].pulse_generation_time)):
462
                # TODO: alfa function shouldn't be calculated here (long procedure)
463
                memory_impact1 += self.__alfa_function(t - self._central_element[0].pulse_generation_time[i], self._params.alfa_inhibitory, self._params.betta_inhibitory);
464
            
465
            memory_impact2 = 0.0;
466
            for i in range(0, len(self._central_element[1].pulse_generation_time)):
467
                # TODO: alfa function shouldn't be calculated here (long procedure)
468
                memory_impact2 += self.__alfa_function(t - self._central_element[1].pulse_generation_time[i], self._params.alfa_inhibitory, self._params.betta_inhibitory);        
469
    
470
            Isyn = self._params.w2 * (v - self._params.Vsyninh) * memory_impact1 + self._link_weight3[index] * (v - self._params.Vsyninh) * memory_impact2;            
471
        else:
472
            # CN - central element.
473
            central_index = index - self._num_osc;
474
            if (central_index == 0):
475
                Iext = self._params.Icn1;   # CN1
476
                
477
                memory_impact = 0.0;
478
                for index_oscillator in range(0, self._num_osc):
479
                    for index_generation in range(0, len(self._pulse_generation_time[index_oscillator])):
480
                        # TODO: alfa function shouldn't be calculated here (long procedure)
481
                        memory_impact += self.__alfa_function(t - self._pulse_generation_time[index_oscillator][index_generation], self._params.alfa_excitatory, self._params.betta_excitatory);
482
                 
483
                Isyn = self._params.w1 * (v - self._params.Vsynexc) * memory_impact;
484
                
485
            elif (central_index == 1):
486
                Iext = self._params.Icn2;   # CN2
487
                Isyn = 0.0;
488
                
489
            else:
490
                assert 0;
491
        
492
        
493
        # Membrane potential
494
        dv = -Iion + Iext - Isyn;
495
        
496
        # Calculate variables
497
        potential = v - self._params.vRest;
498
        am = (2.5 - 0.1 * potential) / (math.exp(2.5 - 0.1 * potential) - 1.0);
499
        ah = 0.07 * math.exp(-potential / 20.0);
500
        an = (0.1 - 0.01 * potential) / (math.exp(1.0 - 0.1 * potential) - 1.0);
501
        
502
        bm = 4.0 * math.exp(-potential / 18.0);
503
        bh = 1.0 / (math.exp(3.0 - 0.1 * potential) + 1.0);
504
        bn = 0.125 * math.exp(-potential / 80.0);
505
        
506
        dm = am * (1.0 - m) - bm * m;
507
        dh = ah * (1.0 - h) - bh * h;
508
        dn = an * (1.0 - n) - bn * n;
509
        
510
        return [dv, dm, dh, dn];
511
        
512
        
513
    def allocate_sync_ensembles(self, tolerance = 0.1):
514
        """!
515
        @brief Allocates clusters in line with ensembles of synchronous oscillators where each. Synchronous ensemble corresponds to only one cluster.
516
        
517
        @param[in] tolerance (double): maximum error for allocation of synchronous ensemble oscillators.
518
        
519
        @return (list) Grours (lists) of indexes of synchronous oscillators. For example [ [index_osc1, index_osc3], [index_osc2], [index_osc4, index_osc5] ].
520
        
521
        """
522
        
523
        ignore = set();
524
        
525
        ignore.add(self._num_osc);
526
        ignore.add(self._num_osc + 1);
527
        
528
        return allocate_sync_ensembles(self._membrane_dynamic_pointer, tolerance, 20.0, ignore);
529
    
530
    
531
    def __alfa_function(self, time, alfa, betta):
532
        """!
533
        @brief Calculates value of alfa-function for difference between spike generation time and current simulation time.
534
        
535
        @param[in] time (double): Difference between last spike generation time and current time.
536
        @param[in] alfa (double): Alfa parameter for alfa-function.
537
        @param[in] betta (double): Betta parameter for alfa-function.
538
        
539
        @return (double) Value of alfa-function.
540
        
541
        """
542
        
543
        return alfa * time * math.exp(-betta * time);
544