braintools 0.0.2__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- braintools/__init__.py +27 -0
- braintools/functional/__init__.py +25 -0
- braintools/functional/_activations.py +733 -0
- braintools/functional/_normalization.py +62 -0
- braintools/functional/_spikes.py +90 -0
- braintools/init/__init__.py +26 -0
- braintools/init/_base.py +36 -0
- braintools/init/_generic.py +205 -0
- braintools/init/_random_inits.py +489 -0
- braintools/init/_regular_inits.py +109 -0
- braintools/input/__init__.py +27 -0
- braintools/input/currents.py +380 -0
- braintools/input/currents_test.py +111 -0
- braintools/metric/__init__.py +46 -0
- braintools/metric/_classification.py +569 -0
- braintools/metric/_classification_test.py +625 -0
- braintools/metric/_correlation.py +302 -0
- braintools/metric/_correlation_test.py +124 -0
- braintools/metric/_fenchel_young.py +67 -0
- braintools/metric/_fenchel_young_test.py +55 -0
- braintools/metric/_firings.py +85 -0
- braintools/metric/_firings_test.py +41 -0
- braintools/metric/_lfp.py +139 -0
- braintools/metric/_ranking.py +163 -0
- braintools/metric/_ranking_test.py +242 -0
- braintools/metric/_regression.py +425 -0
- braintools/metric/_regression_test.py +133 -0
- braintools/metric/_smoothing.py +46 -0
- braintools/metric/_smoothing_test.py +43 -0
- braintools/metric/_util.py +25 -0
- braintools/optim/__init__.py +23 -0
- braintools/optim/_lr_scheduler.py +482 -0
- braintools/optim/_sgd_optimizer.py +1130 -0
- braintools-0.0.2.dist-info/LICENSE +202 -0
- braintools-0.0.2.dist-info/METADATA +93 -0
- braintools-0.0.2.dist-info/RECORD +38 -0
- braintools-0.0.2.dist-info/WHEEL +6 -0
- braintools-0.0.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# Copyright 2024- BrainPy Ecosystem Limited. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
|
|
16
|
+
# -*- coding: utf-8 -*-
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
import braincore as bc
|
|
20
|
+
import jax.lax
|
|
21
|
+
import jax.numpy as jnp
|
|
22
|
+
import numpy as np
|
|
23
|
+
|
|
24
|
+
__all__ = [
|
|
25
|
+
'section_input',
|
|
26
|
+
'constant_input',
|
|
27
|
+
'spike_input',
|
|
28
|
+
'ramp_input',
|
|
29
|
+
'wiener_process',
|
|
30
|
+
'ou_process',
|
|
31
|
+
'sinusoidal_input',
|
|
32
|
+
'square_input',
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def section_input(values, durations, dt=None, return_length=False):
|
|
37
|
+
"""Format an input current with different sections.
|
|
38
|
+
|
|
39
|
+
For example:
|
|
40
|
+
|
|
41
|
+
If you want to get an input where the size is 0 bwteen 0-100 ms,
|
|
42
|
+
and the size is 1. between 100-200 ms.
|
|
43
|
+
|
|
44
|
+
>>> section_input(values=[0, 1],
|
|
45
|
+
>>> durations=[100, 100])
|
|
46
|
+
|
|
47
|
+
Parameters
|
|
48
|
+
----------
|
|
49
|
+
values : list, np.ndarray
|
|
50
|
+
The current values for each period duration.
|
|
51
|
+
durations : list, np.ndarray
|
|
52
|
+
The duration for each period.
|
|
53
|
+
dt : float
|
|
54
|
+
Default is None.
|
|
55
|
+
return_length : bool
|
|
56
|
+
Return the final duration length.
|
|
57
|
+
|
|
58
|
+
Returns
|
|
59
|
+
-------
|
|
60
|
+
current_and_duration
|
|
61
|
+
"""
|
|
62
|
+
if len(durations) != len(values):
|
|
63
|
+
raise ValueError(f'"values" and "durations" must be the same length, while '
|
|
64
|
+
f'we got {len(values)} != {len(durations)}.')
|
|
65
|
+
|
|
66
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
67
|
+
|
|
68
|
+
# get input current shape, and duration
|
|
69
|
+
I_duration = sum(durations)
|
|
70
|
+
I_shape = ()
|
|
71
|
+
for val in values:
|
|
72
|
+
shape = jnp.shape(val)
|
|
73
|
+
if len(shape) > len(I_shape):
|
|
74
|
+
I_shape = shape
|
|
75
|
+
|
|
76
|
+
# get the current
|
|
77
|
+
start = 0
|
|
78
|
+
I_current = jnp.zeros((int(np.ceil(I_duration / dt)),) + I_shape, dtype=bc.environ.dftype())
|
|
79
|
+
for c_size, duration in zip(values, durations):
|
|
80
|
+
length = int(duration / dt)
|
|
81
|
+
I_current = I_current.at[start: start + length].set(c_size)
|
|
82
|
+
start += length
|
|
83
|
+
|
|
84
|
+
if return_length:
|
|
85
|
+
return I_current, I_duration
|
|
86
|
+
else:
|
|
87
|
+
return I_current
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def constant_input(I_and_duration, dt=None):
|
|
91
|
+
"""Format constant input in durations.
|
|
92
|
+
|
|
93
|
+
For example:
|
|
94
|
+
|
|
95
|
+
If you want to get an input where the size is 0 bwteen 0-100 ms,
|
|
96
|
+
and the size is 1. between 100-200 ms.
|
|
97
|
+
|
|
98
|
+
>>> import brainpy.math as bm
|
|
99
|
+
>>> constant_input([(0, 100), (1, 100)])
|
|
100
|
+
>>> constant_input([(bm.zeros(100), 100), (bm.random.rand(100), 100)])
|
|
101
|
+
|
|
102
|
+
Parameters
|
|
103
|
+
----------
|
|
104
|
+
I_and_duration : list
|
|
105
|
+
This parameter receives the current size and the current
|
|
106
|
+
duration pairs, like `[(Isize1, duration1), (Isize2, duration2)]`.
|
|
107
|
+
dt : float
|
|
108
|
+
Default is None.
|
|
109
|
+
|
|
110
|
+
Returns
|
|
111
|
+
-------
|
|
112
|
+
current_and_duration : tuple
|
|
113
|
+
(The formatted current, total duration)
|
|
114
|
+
"""
|
|
115
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
116
|
+
|
|
117
|
+
# get input current dimension, shape, and duration
|
|
118
|
+
I_duration = 0.
|
|
119
|
+
I_shape = ()
|
|
120
|
+
for I in I_and_duration:
|
|
121
|
+
I_duration += I[1]
|
|
122
|
+
shape = jnp.shape(I[0])
|
|
123
|
+
if len(shape) > len(I_shape):
|
|
124
|
+
I_shape = shape
|
|
125
|
+
|
|
126
|
+
# get the current
|
|
127
|
+
start = 0
|
|
128
|
+
I_current = jnp.zeros((int(np.ceil(I_duration / dt)),) + I_shape, dtype=bc.environ.dftype())
|
|
129
|
+
for c_size, duration in I_and_duration:
|
|
130
|
+
length = int(duration / dt)
|
|
131
|
+
I_current = I_current.at[start: start + length].set(c_size)
|
|
132
|
+
start += length
|
|
133
|
+
return I_current, I_duration
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def spike_input(sp_times, sp_lens, sp_sizes, duration, dt=None):
|
|
138
|
+
"""Format current input like a series of short-time spikes.
|
|
139
|
+
|
|
140
|
+
For example:
|
|
141
|
+
|
|
142
|
+
If you want to generate a spike train at 10 ms, 20 ms, 30 ms, 200 ms, 300 ms,
|
|
143
|
+
and each spike lasts 1 ms and the spike current is 0.5, then you can use the
|
|
144
|
+
following funtions:
|
|
145
|
+
|
|
146
|
+
>>> spike_input(sp_times=[10, 20, 30, 200, 300],
|
|
147
|
+
>>> sp_lens=1., # can be a list to specify the spike length at each point
|
|
148
|
+
>>> sp_sizes=0.5, # can be a list to specify the current size at each point
|
|
149
|
+
>>> duration=400.)
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
sp_times : list, tuple
|
|
154
|
+
The spike time-points. Must be an iterable object.
|
|
155
|
+
sp_lens : int, float, list, tuple
|
|
156
|
+
The length of each point-current, mimicking the spike durations.
|
|
157
|
+
sp_sizes : int, float, list, tuple
|
|
158
|
+
The current sizes.
|
|
159
|
+
duration : int, float
|
|
160
|
+
The total current duration.
|
|
161
|
+
dt : float
|
|
162
|
+
The default is None.
|
|
163
|
+
|
|
164
|
+
Returns
|
|
165
|
+
-------
|
|
166
|
+
current : bm.ndarray
|
|
167
|
+
The formatted input current.
|
|
168
|
+
"""
|
|
169
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
170
|
+
assert isinstance(sp_times, (list, tuple))
|
|
171
|
+
if isinstance(sp_lens, (float, int)):
|
|
172
|
+
sp_lens = [sp_lens] * len(sp_times)
|
|
173
|
+
if isinstance(sp_sizes, (float, int)):
|
|
174
|
+
sp_sizes = [sp_sizes] * len(sp_times)
|
|
175
|
+
|
|
176
|
+
current = jnp.zeros(int(np.ceil(duration / dt)), dtype=bc.environ.dftype())
|
|
177
|
+
for time, dur, size in zip(sp_times, sp_lens, sp_sizes):
|
|
178
|
+
pp = int(time / dt)
|
|
179
|
+
p_len = int(dur / dt)
|
|
180
|
+
current = current.at[pp: pp + p_len].set(size)
|
|
181
|
+
return current
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def ramp_input(c_start, c_end, duration, t_start=0, t_end=None, dt=None):
|
|
185
|
+
"""Get the gradually changed input current.
|
|
186
|
+
|
|
187
|
+
Parameters
|
|
188
|
+
----------
|
|
189
|
+
c_start : float
|
|
190
|
+
The minimum (or maximum) current size.
|
|
191
|
+
c_end : float
|
|
192
|
+
The maximum (or minimum) current size.
|
|
193
|
+
duration : int, float
|
|
194
|
+
The total duration.
|
|
195
|
+
t_start : float
|
|
196
|
+
The ramped current start time-point.
|
|
197
|
+
t_end : float
|
|
198
|
+
The ramped current end time-point. Default is the None.
|
|
199
|
+
dt : float, int, optional
|
|
200
|
+
The numerical precision.
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
current : bm.ndarray
|
|
205
|
+
The formatted current
|
|
206
|
+
"""
|
|
207
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
208
|
+
t_end = duration if t_end is None else t_end
|
|
209
|
+
|
|
210
|
+
current = jnp.zeros(int(np.ceil(duration / dt)), dtype=bc.environ.dftype())
|
|
211
|
+
p1 = int(np.ceil(t_start / dt))
|
|
212
|
+
p2 = int(np.ceil(t_end / dt))
|
|
213
|
+
cc = jnp.array(jnp.linspace(c_start, c_end, p2 - p1))
|
|
214
|
+
current = current.at[p1: p2].set(cc)
|
|
215
|
+
return current
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
def wiener_process(duration, dt=None, n=1, t_start=0., t_end=None, seed=None):
|
|
220
|
+
"""Stimulus sampled from a Wiener process, i.e.
|
|
221
|
+
drawn from standard normal distribution N(0, sqrt(dt)).
|
|
222
|
+
|
|
223
|
+
Parameters
|
|
224
|
+
----------
|
|
225
|
+
duration: float
|
|
226
|
+
The input duration.
|
|
227
|
+
dt: float
|
|
228
|
+
The numerical precision.
|
|
229
|
+
n: int
|
|
230
|
+
The variable number.
|
|
231
|
+
t_start: float
|
|
232
|
+
The start time.
|
|
233
|
+
t_end: float
|
|
234
|
+
The end time.
|
|
235
|
+
seed: int
|
|
236
|
+
The noise seed.
|
|
237
|
+
"""
|
|
238
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
239
|
+
t_end = duration if t_end is None else t_end
|
|
240
|
+
i_start = int(t_start / dt)
|
|
241
|
+
i_end = int(t_end / dt)
|
|
242
|
+
noises = bc.random.standard_normal((i_end - i_start, n)) * jnp.sqrt(dt)
|
|
243
|
+
currents = jnp.zeros((int(duration / dt), n), dtype=bc.environ.dftype())
|
|
244
|
+
currents = currents.at[i_start: i_end].set(noises)
|
|
245
|
+
return currents
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def ou_process(mean, sigma, tau, duration, dt=None, n=1, t_start=0., t_end=None, seed=None):
|
|
249
|
+
r"""Ornstein–Uhlenbeck input.
|
|
250
|
+
|
|
251
|
+
.. math::
|
|
252
|
+
|
|
253
|
+
dX = (mu - X)/\tau * dt + \sigma*dW
|
|
254
|
+
|
|
255
|
+
Parameters
|
|
256
|
+
----------
|
|
257
|
+
mean: float
|
|
258
|
+
Drift of the OU process.
|
|
259
|
+
sigma: float
|
|
260
|
+
Standard deviation of the Wiener process, i.e. strength of the noise.
|
|
261
|
+
tau: float
|
|
262
|
+
Timescale of the OU process, in ms.
|
|
263
|
+
duration: float
|
|
264
|
+
The input duration.
|
|
265
|
+
dt: float
|
|
266
|
+
The numerical precision.
|
|
267
|
+
n: int
|
|
268
|
+
The variable number.
|
|
269
|
+
t_start: float
|
|
270
|
+
The start time.
|
|
271
|
+
t_end: float
|
|
272
|
+
The end time.
|
|
273
|
+
seed: optional, int
|
|
274
|
+
The random seed.
|
|
275
|
+
"""
|
|
276
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
277
|
+
dt_sqrt = jnp.sqrt(dt)
|
|
278
|
+
t_end = duration if t_end is None else t_end
|
|
279
|
+
i_start = int(t_start / dt)
|
|
280
|
+
i_end = int(t_end / dt)
|
|
281
|
+
|
|
282
|
+
def _f(x, key):
|
|
283
|
+
x = x + dt * ((mean - x) / tau) + sigma * dt_sqrt * bc.random.rand(n, key=key)
|
|
284
|
+
return x, x
|
|
285
|
+
|
|
286
|
+
_, noises = jax.lax.scan(_f, jnp.full(n, mean, dtype=bc.environ.dftype()), bc.random.split_keys(i_end - i_start))
|
|
287
|
+
currents = jnp.zeros((int(duration / dt), n), dtype=bc.environ.dftype())
|
|
288
|
+
return currents.at[i_start: i_end].set(noises)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
def sinusoidal_input(amplitude, frequency, duration, dt=None, t_start=0., t_end=None, bias=False):
|
|
292
|
+
"""Sinusoidal input.
|
|
293
|
+
|
|
294
|
+
Parameters
|
|
295
|
+
----------
|
|
296
|
+
amplitude: float
|
|
297
|
+
Amplitude of the sinusoid.
|
|
298
|
+
frequency: float
|
|
299
|
+
Frequency of the sinus oscillation, in Hz
|
|
300
|
+
duration: float
|
|
301
|
+
The input duration.
|
|
302
|
+
t_start: float
|
|
303
|
+
The start time.
|
|
304
|
+
t_end: float
|
|
305
|
+
The end time.
|
|
306
|
+
dt: float
|
|
307
|
+
The numerical precision.
|
|
308
|
+
bias: bool
|
|
309
|
+
Whether the sinusoid oscillates around 0 (False), or
|
|
310
|
+
has a positive DC bias, thus non-negative (True).
|
|
311
|
+
"""
|
|
312
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
313
|
+
if t_end is None:
|
|
314
|
+
t_end = duration
|
|
315
|
+
times = jnp.arange(0, t_end - t_start, dt)
|
|
316
|
+
start_i = int(t_start / dt)
|
|
317
|
+
end_i = int(t_end / dt)
|
|
318
|
+
sin_inputs = amplitude * jnp.sin(2 * jnp.pi * times * (frequency / 1000.0))
|
|
319
|
+
if bias: sin_inputs += amplitude
|
|
320
|
+
currents = jnp.zeros(int(duration / dt), dtype=bc.environ.dftype())
|
|
321
|
+
return currents.at[start_i:end_i].set(sin_inputs)
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def _square(t, duty=0.5):
|
|
325
|
+
t, w = np.asarray(t), np.asarray(duty)
|
|
326
|
+
w = np.asarray(w + (t - t))
|
|
327
|
+
t = np.asarray(t + (w - w))
|
|
328
|
+
if t.dtype.char in 'fFdD':
|
|
329
|
+
ytype = t.dtype.char
|
|
330
|
+
else:
|
|
331
|
+
ytype = 'd'
|
|
332
|
+
|
|
333
|
+
y = np.zeros(t.shape, ytype)
|
|
334
|
+
|
|
335
|
+
# width must be between 0 and 1 inclusive
|
|
336
|
+
mask1 = (w > 1) | (w < 0)
|
|
337
|
+
np.place(y, mask1, np.nan)
|
|
338
|
+
|
|
339
|
+
# on the interval 0 to duty*2*pi function is 1
|
|
340
|
+
tmod = np.mod(t, 2 * np.pi)
|
|
341
|
+
mask2 = (1 - mask1) & (tmod < w * 2 * np.pi)
|
|
342
|
+
np.place(y, mask2, 1)
|
|
343
|
+
|
|
344
|
+
# on the interval duty*2*pi to 2*pi function is
|
|
345
|
+
# (pi*(w+1)-tmod) / (pi*(1-w))
|
|
346
|
+
mask3 = (1 - mask1) & (1 - mask2)
|
|
347
|
+
np.place(y, mask3, -1)
|
|
348
|
+
return y
|
|
349
|
+
|
|
350
|
+
|
|
351
|
+
def square_input(amplitude, frequency, duration, dt=None, bias=False, t_start=0., t_end=None):
|
|
352
|
+
"""Oscillatory square input.
|
|
353
|
+
|
|
354
|
+
Parameters
|
|
355
|
+
----------
|
|
356
|
+
amplitude: float
|
|
357
|
+
Amplitude of the square oscillation.
|
|
358
|
+
frequency: float
|
|
359
|
+
Frequency of the square oscillation, in Hz.
|
|
360
|
+
duration: float
|
|
361
|
+
The input duration.
|
|
362
|
+
t_start: float
|
|
363
|
+
The start time.
|
|
364
|
+
t_end: float
|
|
365
|
+
The end time.
|
|
366
|
+
dt: float
|
|
367
|
+
The numerical precision.
|
|
368
|
+
bias: bool
|
|
369
|
+
Whether the sinusoid oscillates around 0 (False), or
|
|
370
|
+
has a positive DC bias, thus non-negative (True).
|
|
371
|
+
"""
|
|
372
|
+
dt = bc.environ.get_dt() if dt is None else dt
|
|
373
|
+
if t_end is None: t_end = duration
|
|
374
|
+
times = np.arange(0, t_end - t_start, dt)
|
|
375
|
+
sin_inputs = amplitude * _square(2 * np.pi * times * (frequency / 1000.0))
|
|
376
|
+
if bias: sin_inputs += amplitude
|
|
377
|
+
currents = jnp.zeros(int(duration / dt), dtype=bc.environ.dftype())
|
|
378
|
+
start_i = int(t_start / dt)
|
|
379
|
+
end_i = int(t_end / dt)
|
|
380
|
+
return currents.at[start_i:end_i].set(sin_inputs)
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Copyright 2024- BrainPy Ecosystem Limited. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
|
|
16
|
+
# -*- coding: utf-8 -*-
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
from unittest import TestCase
|
|
20
|
+
|
|
21
|
+
import braincore as bc
|
|
22
|
+
import jax.numpy as jnp
|
|
23
|
+
import numpy as np
|
|
24
|
+
|
|
25
|
+
import braintools as bt
|
|
26
|
+
try:
|
|
27
|
+
import matplotlib.pyplot as plt
|
|
28
|
+
except (ImportError, ModuleNotFoundError):
|
|
29
|
+
plt = None
|
|
30
|
+
|
|
31
|
+
block = False
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def show(current, duration, title=''):
|
|
35
|
+
if plt is not None:
|
|
36
|
+
ts = np.arange(0, duration, bc.environ.get_dt())
|
|
37
|
+
plt.plot(ts, current)
|
|
38
|
+
plt.title(title)
|
|
39
|
+
plt.xlabel('Time [ms]')
|
|
40
|
+
plt.ylabel('Current Value')
|
|
41
|
+
plt.show(block=block)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class TestCurrents(TestCase):
|
|
45
|
+
def test_section_input(self):
|
|
46
|
+
current1, duration = bt.input.section_input(values=[0, 1., 0.],
|
|
47
|
+
durations=[100, 300, 100],
|
|
48
|
+
return_length=True,
|
|
49
|
+
dt=0.1)
|
|
50
|
+
show(current1, duration, 'values=[0, 1, 0], durations=[100, 300, 100]')
|
|
51
|
+
|
|
52
|
+
def test_constant_input(self):
|
|
53
|
+
current2, duration = bt.input.constant_input([(0, 100), (1, 300), (0, 100)])
|
|
54
|
+
show(current2, duration, '[(0, 100), (1, 300), (0, 100)]')
|
|
55
|
+
|
|
56
|
+
def test_spike_input(self):
|
|
57
|
+
current3 = bt.input.spike_input(
|
|
58
|
+
sp_times=[10, 20, 30, 200, 300],
|
|
59
|
+
sp_lens=1., # can be a list to specify the spike length at each point
|
|
60
|
+
sp_sizes=0.5, # can be a list to specify the spike current size at each point
|
|
61
|
+
duration=400.)
|
|
62
|
+
|
|
63
|
+
show(current3, 400, 'Spike Input Example')
|
|
64
|
+
|
|
65
|
+
def test_ramp_input(self):
|
|
66
|
+
duration = 500
|
|
67
|
+
current4 = bt.input.ramp_input(0, 1, duration)
|
|
68
|
+
|
|
69
|
+
show(current4, duration, r'$c_{start}$=0, $c_{end}$=%d, duration, '
|
|
70
|
+
r'$t_{start}$=0, $t_{end}$=None' % (duration))
|
|
71
|
+
|
|
72
|
+
def test_ramp_input2(self):
|
|
73
|
+
duration, t_start, t_end = 500, 100, 400
|
|
74
|
+
current5 = bt.input.ramp_input(0, 1, duration, t_start, t_end)
|
|
75
|
+
|
|
76
|
+
show(current5, duration, r'$c_{start}$=0, $c_{end}$=1, duration=%d, '
|
|
77
|
+
r'$t_{start}$=%d, $t_{end}$=%d' % (duration, t_start, t_end))
|
|
78
|
+
|
|
79
|
+
def test_wiener_process(self):
|
|
80
|
+
duration = 200
|
|
81
|
+
current6 = bt.input.wiener_process(duration, n=2, t_start=10., t_end=180.)
|
|
82
|
+
show(current6, duration, 'Wiener Process')
|
|
83
|
+
|
|
84
|
+
def test_ou_process(self):
|
|
85
|
+
duration = 200
|
|
86
|
+
current7 = bt.input.ou_process(mean=1., sigma=0.1, tau=10., duration=duration, n=2, t_start=10., t_end=180.)
|
|
87
|
+
show(current7, duration, 'Ornstein-Uhlenbeck Process')
|
|
88
|
+
|
|
89
|
+
def test_sinusoidal_input(self):
|
|
90
|
+
duration = 2000
|
|
91
|
+
current8 = bt.input.sinusoidal_input(amplitude=1., frequency=2.0, duration=duration, t_start=100., )
|
|
92
|
+
show(current8, duration, 'Sinusoidal Input')
|
|
93
|
+
|
|
94
|
+
def test_square_input(self):
|
|
95
|
+
duration = 2000
|
|
96
|
+
current9 = bt.input.square_input(amplitude=1., frequency=2.0,
|
|
97
|
+
duration=duration, t_start=100)
|
|
98
|
+
show(current9, duration, 'Square Input')
|
|
99
|
+
|
|
100
|
+
def test_general1(self):
|
|
101
|
+
I1 = bt.input.section_input(values=[0, 1, 2], durations=[10, 20, 30], dt=0.1)
|
|
102
|
+
I2 = bt.input.section_input(values=[0, 1, 2], durations=[10, 20, 30], dt=0.01)
|
|
103
|
+
self.assertTrue(I1.shape[0] == 600)
|
|
104
|
+
self.assertTrue(I2.shape[0] == 6000)
|
|
105
|
+
|
|
106
|
+
def test_general2(self):
|
|
107
|
+
bc.random.seed(123)
|
|
108
|
+
current = bt.input.section_input(values=[0, jnp.ones(10), bc.random.random((3, 10))],
|
|
109
|
+
durations=[100, 300, 100])
|
|
110
|
+
self.assertTrue(current.shape == (5000, 3, 10))
|
|
111
|
+
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Copyright 2024- BrainPy Ecosystem Limited. All Rights Reserved.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
|
|
16
|
+
from ._classification import *
|
|
17
|
+
from ._classification import __all__ as _classification_all
|
|
18
|
+
from ._correlation import *
|
|
19
|
+
from ._correlation import __all__ as _correlation_all
|
|
20
|
+
from ._fenchel_young import *
|
|
21
|
+
from ._fenchel_young import __all__ as _fenchel_young_all
|
|
22
|
+
from ._firings import *
|
|
23
|
+
from ._firings import __all__ as _firings_all
|
|
24
|
+
from ._lfp import *
|
|
25
|
+
from ._lfp import __all__ as _lfp_all
|
|
26
|
+
from ._ranking import *
|
|
27
|
+
from ._ranking import __all__ as _ranking_all
|
|
28
|
+
from ._regression import *
|
|
29
|
+
from ._regression import __all__ as _regression_all
|
|
30
|
+
from ._smoothing import *
|
|
31
|
+
from ._smoothing import __all__ as _smoothing_all
|
|
32
|
+
|
|
33
|
+
__all__ = (
|
|
34
|
+
_classification_all
|
|
35
|
+
+ _correlation_all
|
|
36
|
+
+ _fenchel_young_all
|
|
37
|
+
+ _firings_all
|
|
38
|
+
+ _lfp_all
|
|
39
|
+
+ _ranking_all
|
|
40
|
+
+ _regression_all
|
|
41
|
+
+ _smoothing_all
|
|
42
|
+
)
|
|
43
|
+
del (_classification_all, _correlation_all,
|
|
44
|
+
_fenchel_young_all, _firings_all,
|
|
45
|
+
_lfp_all, _ranking_all,
|
|
46
|
+
_regression_all, _smoothing_all)
|