sim-ballena 0.1.0__tar.gz → 0.1.2__tar.gz

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.

Potentially problematic release.


This version of sim-ballena might be problematic. Click here for more details.

@@ -4,9 +4,11 @@ version = 4
4
4
 
5
5
  [[package]]
6
6
  name = "SimBallenaSNN"
7
- version = "0.1.0"
7
+ version = "0.1.2"
8
8
  dependencies = [
9
9
  "pyo3",
10
+ "rand",
11
+ "rand_distr",
10
12
  ]
11
13
 
12
14
  [[package]]
@@ -15,6 +17,24 @@ version = "1.5.0"
15
17
  source = "registry+https://github.com/rust-lang/crates.io-index"
16
18
  checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
17
19
 
20
+ [[package]]
21
+ name = "cfg-if"
22
+ version = "1.0.4"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
25
+
26
+ [[package]]
27
+ name = "getrandom"
28
+ version = "0.3.4"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
31
+ dependencies = [
32
+ "cfg-if",
33
+ "libc",
34
+ "r-efi",
35
+ "wasip2",
36
+ ]
37
+
18
38
  [[package]]
19
39
  name = "heck"
20
40
  version = "0.5.0"
@@ -36,6 +56,12 @@ version = "0.2.180"
36
56
  source = "registry+https://github.com/rust-lang/crates.io-index"
37
57
  checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
38
58
 
59
+ [[package]]
60
+ name = "libm"
61
+ version = "0.2.16"
62
+ source = "registry+https://github.com/rust-lang/crates.io-index"
63
+ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
64
+
39
65
  [[package]]
40
66
  name = "memoffset"
41
67
  version = "0.9.1"
@@ -45,6 +71,16 @@ dependencies = [
45
71
  "autocfg",
46
72
  ]
47
73
 
74
+ [[package]]
75
+ name = "num-traits"
76
+ version = "0.2.19"
77
+ source = "registry+https://github.com/rust-lang/crates.io-index"
78
+ checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
79
+ dependencies = [
80
+ "autocfg",
81
+ "libm",
82
+ ]
83
+
48
84
  [[package]]
49
85
  name = "once_cell"
50
86
  version = "1.21.3"
@@ -57,6 +93,15 @@ version = "1.13.0"
57
93
  source = "registry+https://github.com/rust-lang/crates.io-index"
58
94
  checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950"
59
95
 
96
+ [[package]]
97
+ name = "ppv-lite86"
98
+ version = "0.2.21"
99
+ source = "registry+https://github.com/rust-lang/crates.io-index"
100
+ checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
101
+ dependencies = [
102
+ "zerocopy",
103
+ ]
104
+
60
105
  [[package]]
61
106
  name = "proc-macro2"
62
107
  version = "1.0.105"
@@ -136,6 +181,51 @@ dependencies = [
136
181
  "proc-macro2",
137
182
  ]
138
183
 
184
+ [[package]]
185
+ name = "r-efi"
186
+ version = "5.3.0"
187
+ source = "registry+https://github.com/rust-lang/crates.io-index"
188
+ checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
189
+
190
+ [[package]]
191
+ name = "rand"
192
+ version = "0.9.2"
193
+ source = "registry+https://github.com/rust-lang/crates.io-index"
194
+ checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
195
+ dependencies = [
196
+ "rand_chacha",
197
+ "rand_core",
198
+ ]
199
+
200
+ [[package]]
201
+ name = "rand_chacha"
202
+ version = "0.9.0"
203
+ source = "registry+https://github.com/rust-lang/crates.io-index"
204
+ checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
205
+ dependencies = [
206
+ "ppv-lite86",
207
+ "rand_core",
208
+ ]
209
+
210
+ [[package]]
211
+ name = "rand_core"
212
+ version = "0.9.5"
213
+ source = "registry+https://github.com/rust-lang/crates.io-index"
214
+ checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
215
+ dependencies = [
216
+ "getrandom",
217
+ ]
218
+
219
+ [[package]]
220
+ name = "rand_distr"
221
+ version = "0.5.1"
222
+ source = "registry+https://github.com/rust-lang/crates.io-index"
223
+ checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463"
224
+ dependencies = [
225
+ "num-traits",
226
+ "rand",
227
+ ]
228
+
139
229
  [[package]]
140
230
  name = "rustversion"
141
231
  version = "1.0.22"
@@ -170,3 +260,38 @@ name = "unindent"
170
260
  version = "0.2.4"
171
261
  source = "registry+https://github.com/rust-lang/crates.io-index"
172
262
  checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
263
+
264
+ [[package]]
265
+ name = "wasip2"
266
+ version = "1.0.2+wasi-0.2.9"
267
+ source = "registry+https://github.com/rust-lang/crates.io-index"
268
+ checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5"
269
+ dependencies = [
270
+ "wit-bindgen",
271
+ ]
272
+
273
+ [[package]]
274
+ name = "wit-bindgen"
275
+ version = "0.51.0"
276
+ source = "registry+https://github.com/rust-lang/crates.io-index"
277
+ checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
278
+
279
+ [[package]]
280
+ name = "zerocopy"
281
+ version = "0.8.36"
282
+ source = "registry+https://github.com/rust-lang/crates.io-index"
283
+ checksum = "dafd85c832c1b68bbb4ec0c72c7f6f4fc5179627d2bc7c26b30e4c0cc11e76cc"
284
+ dependencies = [
285
+ "zerocopy-derive",
286
+ ]
287
+
288
+ [[package]]
289
+ name = "zerocopy-derive"
290
+ version = "0.8.36"
291
+ source = "registry+https://github.com/rust-lang/crates.io-index"
292
+ checksum = "7cb7e4e8436d9db52fbd6625dbf2f45243ab84994a72882ec8227b99e72b439a"
293
+ dependencies = [
294
+ "proc-macro2",
295
+ "quote",
296
+ "syn",
297
+ ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "SimBallenaSNN"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  edition = "2024"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -10,3 +10,5 @@ crate-type = ["cdylib"]
10
10
 
11
11
  [dependencies]
12
12
  pyo3 = "0.27.0"
13
+ rand = "0.9.2"
14
+ rand_distr = "0.5.1"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sim_ballena
3
- Version: 0.1.0
3
+ Version: 0.1.2
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -0,0 +1,132 @@
1
+ use pyo3::prelude::*;
2
+ use pyo3::exceptions::PyValueError;
3
+ use crate::utils::vec_of_tuples;
4
+ use rand_distr::{Exp, Distribution};
5
+
6
+ /* ================ */
7
+ /* === INSTANCE === */
8
+ /* ================ */
9
+
10
+ #[pyclass]
11
+ pub struct Instance{
12
+ spikes: Vec<(f64,usize)>
13
+ }
14
+
15
+ #[pymethods]
16
+ impl Instance{
17
+ #[new]
18
+ fn new(obj: &Bound<'_,PyAny>)->PyResult<Self>{
19
+ let mut spikes = match vec_of_tuples::<f64>(obj){
20
+ Ok(v) => v,
21
+ Err(e) => return Err(e)
22
+ };
23
+
24
+ spikes.sort_by(|a,b|a.0.partial_cmp(&b.0).unwrap());
25
+
26
+ Ok(Self{spikes})
27
+ }
28
+
29
+ fn __str__(&self)->String{
30
+ format!("Input(count={})",self.spikes.len())
31
+ }
32
+
33
+ fn __repr__(&self)->String{
34
+ self.__str__()
35
+ }
36
+
37
+ pub fn get(&self)->&Vec<(f64,usize)>{
38
+ &self.spikes
39
+ }
40
+ }
41
+
42
+ impl Instance{
43
+ pub fn from_poisson(spikes:Vec<(f64,usize)>)->Self{
44
+ Self{spikes}
45
+ }
46
+ }
47
+
48
+ /* ================= */
49
+ /* ==== POISSON ==== */
50
+ /* ================= */
51
+
52
+ #[pyclass]
53
+ pub struct PoissonGenerator{
54
+ max_time : f64,
55
+ spike_times : Vec<Vec<f64>>,
56
+ }
57
+
58
+ #[pymethods]
59
+ impl PoissonGenerator{
60
+ #[new]
61
+ fn new(rates: Vec<f64>, max_time:f64)->Self{
62
+ let mut spike_times:Vec<Vec<f64>> = Vec::new();
63
+ for rate in rates{
64
+ spike_times.push( Self::poisson_process(rate, max_time) );
65
+ }
66
+ Self{max_time, spike_times}
67
+ }
68
+
69
+ fn to_instance(&self)->Instance{
70
+ let mut all_spikes:Vec<(f64,usize)> = Vec::new();
71
+ for (ch,spikes) in self.spike_times.iter().enumerate(){
72
+ let instance_view:Vec<(f64,usize)> = spikes.iter().map(|t|(*t,ch)).collect();
73
+ all_spikes.extend( instance_view );
74
+ }
75
+ Instance::from_poisson( all_spikes )
76
+ }
77
+
78
+ fn get_spikes(&self)->Vec<Vec<f64>>{
79
+ self.spike_times.clone()
80
+ }
81
+
82
+ fn concat<'py>(mut this:PyRefMut<'py, Self>, other:&PoissonGenerator)->PyResult<PyRefMut<'py,Self>>{
83
+
84
+ // check both generators have same dimentions
85
+ let mut spikes_other = other.get_spikes();
86
+ if spikes_other.len() != this.spike_times.len(){
87
+ return Err(PyValueError::new_err("PoissonGenerator must have the same number of inputs"))
88
+ }
89
+ // offset
90
+ for ch in spikes_other.iter_mut(){
91
+ for spk in ch.iter_mut(){
92
+ *spk += this.max_time;
93
+ }
94
+ }
95
+ // concat
96
+ for ch_idx in 0..spikes_other.len(){
97
+ this.spike_times[ch_idx].extend( spikes_other[ch_idx].clone() );
98
+ }
99
+ this.max_time += other.get_max_time();
100
+ Ok(this)
101
+ }
102
+
103
+ fn __str__(&self)->String{
104
+ format!("PoissonGenerator(n_inputs:{}, max_time:{})", self.spike_times.len(), self.max_time)
105
+ }
106
+
107
+ fn __repr__(&self)->String{
108
+ self.__str__()
109
+ }
110
+
111
+ }
112
+
113
+ impl PoissonGenerator{
114
+ fn poisson_process(rate:f64, max_time:f64)->Vec<f64>{
115
+ let mut rng = rand::rng();
116
+ let poi = Exp::new(rate).unwrap();
117
+
118
+ let mut spikes:Vec<f64> = Vec::new();
119
+ let mut t = poi.sample( &mut rng );
120
+ while t<max_time{
121
+ spikes.push(t);
122
+ t += poi.sample( &mut rng );
123
+ }
124
+ spikes
125
+ }
126
+
127
+ pub fn get_max_time(&self)->f64{
128
+ self.max_time
129
+ }
130
+
131
+
132
+ }
@@ -14,6 +14,7 @@ fn sim_ballena(m: &Bound<'_, PyModule>) -> PyResult<()> {
14
14
  m.add_class::<neurons::Lif>()?;
15
15
  m.add_class::<networks::Network>()?;
16
16
  m.add_class::<instances::Instance>()?;
17
+ m.add_class::<instances::PoissonGenerator>()?;
17
18
  // m.add_function( wrap_pyfunction!(networks::network,m)? )?;
18
19
 
19
20
  Ok(())
@@ -268,6 +268,10 @@ impl Network{
268
268
  simulate(self, instance, max_time)
269
269
  }
270
270
 
271
+ /* ===================== */
272
+ /* COPY GETTERS */
273
+ /* ===================== */
274
+
271
275
  }
272
276
 
273
277
 
@@ -160,6 +160,7 @@ impl Lif{
160
160
 
161
161
  /* reset state */
162
162
  pub fn reset_state(&mut self){
163
- self.voltage = self.v_rest;
163
+ self.voltage = self.v_rest;
164
+ self.last_spike = None;
164
165
  }
165
166
  }
@@ -142,7 +142,7 @@ pub fn simulate(network:&mut Network, instance: PyRef<'_, Instance>, max_time:f6
142
142
  Some(syn) => syn,
143
143
  None => continue
144
144
  };
145
-
145
+
146
146
  // Only save measures if the event has been procceced
147
147
  // and the neuron changed and needs to be tracked
148
148
  let mut track_voltage : HashSet<usize> = HashSet::new();
@@ -226,22 +226,6 @@ pub fn simulate(network:&mut Network, instance: PyRef<'_, Instance>, max_time:f6
226
226
  .v_rest_list( v_rest_list )
227
227
  .tau_list( tau_list );
228
228
 
229
-
230
- // voltages
231
- // let neurons = network.get_neurons();
232
- // let voltage_markers:Vec<Vec<VoltageMarker>> = outputs.iter().map(|&o|neurons.get(o).unwrap().get_voltage_markers()).collect();
233
-
234
-
235
- // let mut res = Response::new( outputs.clone() );
236
- // res.set_max_time(max_time);
237
- // res.set_voltage_markers(voltage_markers);
238
- // res.set_tau_list( tau_list );
239
- // res.set_v_rest_list( v_rest_list );
240
-
241
- // spikes
242
- // let spikes:Vec<Vec<f64>> = outputs.iter().map(|&o|neurons.get(o).unwrap().get_spikes()).collect();
243
- // res.set_spikes( spikes );
244
-
245
229
  // reset all neuron states
246
230
  for neu in neurons{{
247
231
  neu.reset_state();
@@ -0,0 +1,49 @@
1
+ import sim_ballena as ballena
2
+ import matplotlib.pyplot as plt
3
+
4
+
5
+ net = (ballena.Network( ballena.Lif().tau(5).t_refractory(0).repeat(2) )
6
+ .synapses_net([])
7
+ .weights_net([])
8
+ .outputs([0,1])
9
+ .mode(['VOLTAGES','SPIKES']))
10
+
11
+
12
+
13
+ # ==========
14
+ # STEP 1
15
+ # ==========
16
+ net = net.synapses_in([(0,0),(0,1),(1,0),(1,1)])
17
+ net = net.weights_in([16,0,-16,0])
18
+
19
+ times = [ (1, 0), (5, 1) ]
20
+ instance = ballena.Instance( times )
21
+ res = net.simulate( instance, 10 )
22
+
23
+ time = res.time()
24
+ volt = res.voltages()
25
+ plt.figure(figsize=(10,4))
26
+ plt.subplot(121)
27
+ plt.plot( time, volt[0], label='true')
28
+ plt.subplot(122)
29
+ plt.plot( time, volt[1], label='false')
30
+ plt.show()
31
+
32
+ # ==========
33
+ # STEP 1
34
+ # ==========
35
+ net = net.weights_in([16,0,-16,0])
36
+
37
+ times = [ (1, 0), (5, 1) ]
38
+ instance = ballena.Instance( times )
39
+ res = net.simulate( instance, 10 )
40
+
41
+ time = res.time()
42
+ volt = res.voltages()
43
+ plt.figure(figsize=(10,4))
44
+ plt.subplot(121)
45
+ plt.plot( time, volt[0], label='true')
46
+ plt.subplot(122)
47
+ plt.plot( time, volt[1], label='false')
48
+ plt.show()
49
+
@@ -2,21 +2,43 @@
2
2
  "cells": [
3
3
  {
4
4
  "cell_type": "code",
5
- "execution_count": 10,
5
+ "execution_count": 1,
6
6
  "metadata": {},
7
- "outputs": [],
7
+ "outputs": [
8
+ {
9
+ "name": "stdout",
10
+ "output_type": "stream",
11
+ "text": [
12
+ "\n",
13
+ " -- N E S T --\n",
14
+ " Copyright (C) 2004 The NEST Initiative\n",
15
+ "\n",
16
+ " Version: 3.9.0\n",
17
+ " Built: Sep 26 2025 04:43:22\n",
18
+ "\n",
19
+ " This program is provided AS IS and comes with\n",
20
+ " NO WARRANTY. See the file LICENSE for details.\n",
21
+ "\n",
22
+ " Problems or suggestions?\n",
23
+ " Visit https://www.nest-simulator.org\n",
24
+ "\n",
25
+ " Type 'nest.help()' to find out more about NEST.\n",
26
+ "\n"
27
+ ]
28
+ }
29
+ ],
8
30
  "source": [
9
31
  "import nest\n",
10
32
  "import matplotlib.pyplot as plt\n",
11
33
  "\n",
12
34
  "import sim_ballena as ballena\n",
13
35
  "import time\n",
14
- "import numpy as np"
36
+ "import numpy as np\n"
15
37
  ]
16
38
  },
17
39
  {
18
40
  "cell_type": "code",
19
- "execution_count": null,
41
+ "execution_count": 2,
20
42
  "metadata": {},
21
43
  "outputs": [],
22
44
  "source": [
@@ -35,7 +57,7 @@
35
57
  },
36
58
  {
37
59
  "cell_type": "code",
38
- "execution_count": 13,
60
+ "execution_count": 3,
39
61
  "metadata": {},
40
62
  "outputs": [],
41
63
  "source": [
@@ -101,7 +123,7 @@
101
123
  },
102
124
  {
103
125
  "cell_type": "code",
104
- "execution_count": 14,
126
+ "execution_count": 4,
105
127
  "metadata": {},
106
128
  "outputs": [
107
129
  {
@@ -127,7 +149,7 @@
127
149
  },
128
150
  {
129
151
  "cell_type": "code",
130
- "execution_count": 15,
152
+ "execution_count": 5,
131
153
  "metadata": {},
132
154
  "outputs": [],
133
155
  "source": [
@@ -183,50 +205,73 @@
183
205
  },
184
206
  {
185
207
  "cell_type": "code",
186
- "execution_count": 21,
208
+ "execution_count": 6,
187
209
  "metadata": {},
188
- "outputs": [
189
- {
190
- "data": {
191
- "text/plain": [
192
- "<Instance at 0x74fcd1e09380>"
193
- ]
194
- },
195
- "execution_count": 21,
196
- "metadata": {},
197
- "output_type": "execute_result"
198
- }
199
- ],
210
+ "outputs": [],
200
211
  "source": [
201
- "inputs = spike_generator(100,0.01,100)\n",
202
- "inputs = ballena.Instance( inputs )\n",
203
- "inputs"
212
+ "# inputs = spike_generator(100,0.01,100)\n",
213
+ "\n",
214
+ "# t_ballena = simulate_ballena_fast(inputs, w=4, tau=4, max_time=100, epochs=5000)\n",
215
+ "# t_nest = simulate_nest_fast(inputs, w=4, tau=4, max_time=100, epochs=5000)\n",
216
+ "\n",
217
+ "# print('t_ballena', t_ballena)\n",
218
+ "# print('t_nest', t_nest)\n",
219
+ "# print(f'ballena es {t_nest/t_ballena} veces mas rapido')"
204
220
  ]
205
221
  },
206
222
  {
207
223
  "cell_type": "code",
208
224
  "execution_count": null,
209
225
  "metadata": {},
226
+ "outputs": [],
227
+ "source": [
228
+ "poisson = ballena.PoissonGenerator( [200,100,50], 0.05 )"
229
+ ]
230
+ },
231
+ {
232
+ "cell_type": "code",
233
+ "execution_count": 8,
234
+ "metadata": {},
210
235
  "outputs": [
211
236
  {
212
237
  "name": "stdout",
213
238
  "output_type": "stream",
214
239
  "text": [
215
- "t_ballena 0.7835497856140137\n",
216
- "t_nest 7.289111375808716\n",
217
- "ballena es 9.302678029701386 veces mas rapido\n"
240
+ "[11, 3, 1]\n"
218
241
  ]
242
+ },
243
+ {
244
+ "data": {
245
+ "text/plain": [
246
+ "[]"
247
+ ]
248
+ },
249
+ "execution_count": 8,
250
+ "metadata": {},
251
+ "output_type": "execute_result"
252
+ },
253
+ {
254
+ "data": {
255
+ "image/png": "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juLi4hM4EQCQSpK/Z6SpqSlGjx6d4q0BgJNM3ndGDh48GK+//nrn12+88UY0NTXFGWecEePGjYtly5bFW2+9Fffdd19ERKxcuTImTJgQ5513XnzwwQdxzz33xNNPPx2///3ve+8sAIB+K+8Y2bZtW1xyySWdXy9dujQiIhYsWBDr1q2Lffv2xe7duztfb29vj5tuuineeuutGDZsWHzxi1+Mp556qsv3AAAGr+N6gPVEOdoHYACAk8fR/vz2b9MAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUaAfu299o9i/K2bYvytm+K99o8G7QxwLE6W/3fFCACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAklXeMPPvss3H55ZdHZWVlFBQUxMaNG494zObNm+OCCy6I4uLiOPvss2PdunXHMCoAMBDlHSOHDh2K6urqWLVq1VGtf+ONN2LOnDlxySWXRFNTU9x4441x3XXXxZNPPpn3sADAwFOY7wGzZ8+O2bNnH/X61atXx4QJE2LFihUREXHOOefEc889F3feeWfMmjUr37cHAAaYPn9mpLGxMWpra7vsmzVrVjQ2NvZ4TFtbW+RyuS4bADAw9XmMNDc3R3l5eZd95eXlkcvl4v333+/2mLq6uigrK+vcqqqq+npMACCRk/LTNMuWLYvW1tbObc+ePalHAgD6SN7PjOSroqIiWlpauuxraWmJ0tLSOPXUU7s9pri4OIqLi/t6NADgJNDnd0ZqamqioaGhy776+vqoqanp67cGAPqBvGPk4MGD0dTUFE1NTRHx74/uNjU1xe7duyPi33/EMn/+/M71119/ffz973+P73znO/Hqq6/GL37xi3jggQfi29/+du+cAQDQr+UdI9u2bYspU6bElClTIiJi6dKlMWXKlLj99tsjImLfvn2dYRIRMWHChNi0aVPU19dHdXV1rFixIu655x4f6wUAIuIYnhmZOXNmZFnW4+vd/e2qM2fOjB07duT7VgDAIHBSfpoGABg8xAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEiqIMuyLPUQR5LL5aKsrCxaW1ujtLQ09TgAwFE42p/f7owAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQlBgBAJISIwBAUmIEAEhKjAAASYkRACApMQIAJCVGAICkxAgAkJQYAQCSEiMAQFJiBABISowAAEmJEQAgKTECACQlRgCApMQIAJCUGAEAkhIjAEBSYgQASEqMAABJiREAICkxAgAkJUYAgKTECACQ1DHFyKpVq2L8+PFRUlIS06dPj61bt/a4dt26dVFQUNBlKykpOeaBAYCBJe8Y2bBhQyxdujSWL18eL774YlRXV8esWbNi//79PR5TWloa+/bt69x27dp1XEMDAANH3jFyxx13xKJFi2LhwoVx7rnnxurVq2PYsGGxdu3aHo8pKCiIioqKzq28vPy4hgYABo68YqS9vT22b98etbW1//kGQ4ZEbW1tNDY29njcwYMH46yzzoqqqqr42te+Fi+//PKnvk9bW1vkcrkuGwAwMOUVI++8804cPnz4E3c2ysvLo7m5udtjvvCFL8TatWvj0Ucfjd/85jfR0dERF198cbz55ps9vk9dXV2UlZV1blVVVfmMCQD0I33+aZqampqYP39+TJ48OWbMmBEPP/xwfPazn43/+7//6/GYZcuWRWtra+e2Z8+evh4TAEikMJ/FI0eOjKFDh0ZLS0uX/S0tLVFRUXFU3+OUU06JKVOmxOuvv97jmuLi4iguLs5nNACgn8rrzkhRUVFMnTo1GhoaOvd1dHREQ0ND1NTUHNX3OHz4cLz00ksxevTo/CYFAAakvO6MREQsXbo0FixYEBdeeGFMmzYtVq5cGYcOHYqFCxdGRMT8+fNjzJgxUVdXFxERP/jBD+Kiiy6Ks88+O9599934yU9+Ert27Yrrrruud88EAOiX8o6Rq666Kt5+++24/fbbo7m5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",
256
+ "text/plain": [
257
+ "<Figure size 640x480 with 1 Axes>"
258
+ ]
259
+ },
260
+ "metadata": {},
261
+ "output_type": "display_data"
219
262
  }
220
263
  ],
221
264
  "source": [
222
- "inputs = spike_generator(100,0.01,100)\n",
265
+ "poisson = ballena.PoissonGenerator( [200,100,50], 0.05 )\n",
223
266
  "\n",
224
- "t_ballena = simulate_ballena_fast(inputs, w=4, tau=4, max_time=100, epochs=5000)\n",
225
- "t_nest = simulate_nest_fast(inputs, w=4, tau=4, max_time=100, epochs=5000)\n",
226
267
  "\n",
227
- "print('t_ballena', t_ballena)\n",
228
- "print('t_nest', t_nest)\n",
229
- "print(f'ballena es {t_nest/t_ballena} veces mas rapido')"
268
+ "spikes = poisson.get_spikes()\n",
269
+ "print( [len(spk) for spk in spikes] )\n",
270
+ "\n",
271
+ "for idx,ch in enumerate(spikes):\n",
272
+ " plt.vlines(ch, idx-0.2, idx+0.2)\n",
273
+ " \n",
274
+ "plt.plot()"
230
275
  ]
231
276
  }
232
277
  ],
@@ -1,36 +0,0 @@
1
- use pyo3::prelude::*;
2
- use crate::utils::vec_of_tuples;
3
-
4
- #[pyclass]
5
- pub struct Instance{
6
- spikes: Vec<(f64,usize)>
7
- }
8
-
9
- #[pymethods]
10
- impl Instance{
11
- #[new]
12
- fn new(obj: &Bound<'_,PyAny>)->PyResult<Self>{
13
- let mut spikes = match vec_of_tuples::<f64>(obj){
14
- Ok(v) => v,
15
- Err(e) => return Err(e)
16
- };
17
-
18
-
19
- spikes.sort_by(|a,b|a.0.partial_cmp(&b.0).unwrap());
20
-
21
- Ok(Self{spikes})
22
- }
23
-
24
- fn __str__(&self)->String{
25
- format!("Input(count={})",self.spikes.len())
26
- }
27
-
28
- fn __repr__(&self)->String{
29
- self.__str__()
30
- }
31
-
32
- pub fn get(&self)->&Vec<(f64,usize)>{
33
- &self.spikes
34
- }
35
- }
36
-
@@ -1,81 +0,0 @@
1
- import sim_ballena as ballena
2
- import matplotlib.pyplot as plt
3
- import random
4
- import time
5
-
6
- inputs = ballena.Instance( [(40*t/100,0) for t in range(1,100)] )
7
- n = [ballena.Lif().tau(10).t_refractory(0.001)]
8
- syn_in = [(0,0)]
9
- syn_net = []
10
- w_in = [4]
11
- w_net = []
12
- outputs = [0]
13
-
14
- # ========================
15
- # RED QUE GRABA VOLTAJES
16
- # ========================
17
- net = (ballena.Network(n)
18
- .synapses_in(syn_in)
19
- .synapses_net(syn_net)
20
- .weights_in(w_in)
21
- .weights_net(w_net)
22
- .outputs(outputs)
23
- .mode(['VOLTAGES','SPIKES']))
24
-
25
- start = time.time()
26
- for _ in range(5000):
27
- res = net.simulate( inputs, 40 )
28
- print(f"{time.time()-start}")
29
-
30
- # ========================
31
- # RED QUE NO GRABA
32
- # ========================
33
- net = (ballena.Network(n)
34
- .synapses_in(syn_in)
35
- .synapses_net(syn_net)
36
- .weights_in(w_in)
37
- .weights_net(w_net)
38
- .outputs(outputs)
39
- .mode(['SPIKES']))
40
-
41
- start = time.time()
42
- for _ in range(5000):
43
- res = net.simulate( inputs, 40 )
44
- print(f"{time.time()-start}")
45
-
46
-
47
-
48
-
49
-
50
- # inputs_ = [(t/4,0) for t in range(1,40)]
51
- # inputs = ballena.Instance(inputs_)
52
-
53
- # n = [ballena.Lif().tau(10).t_refractory(2),
54
- # ballena.Lif().tau(20)]
55
- # syn_in = [(0,0)]
56
- # syn_net = [(0,1)]
57
- # w_in = [4]
58
- # w_net = [9]
59
- # outputs = [0,1]
60
-
61
- # net = (ballena.Network(n)
62
- # .synapses_in(syn_in)
63
- # .synapses_net(syn_net)
64
- # .weights_in(w_in)
65
- # .weights_net(w_net)
66
- # .outputs(outputs)
67
- # .mode(['VOLTAGES','SPIKES']))
68
-
69
- # res = net.simulate( inputs, 11 )
70
-
71
- # time = res.time()
72
- # volt = res.voltages()
73
-
74
- # print( res.spikes() )
75
-
76
- # plt.plot( time,volt[0], label=f'neu {outputs[0]}' )
77
- # plt.plot( time,volt[1], label=f'neu {outputs[1]}' )
78
- # plt.vlines(res.spikes()[0], -70, -55, linestyles='dashed', colors='red')
79
- # plt.legend()
80
- # plt.grid()
81
- # plt.show()
File without changes
File without changes
File without changes
File without changes