def __init__(self, filterbank, targetvar, *args, **kwds): self.targetvar = targetvar self.filterbank = filterbank filterbank.buffer_init() # Sanitize the clock - does it have the right dt value? if 'clock' in kwds: if int(1/kwds['clock'].dt)!=int(filterbank.samplerate): raise ValueError('Clock should have 1/dt=samplerate') kwds['clock'] = Clock(dt=float(kwds['clock'].dt)*second) else: kwds['clock'] = Clock(dt=1*second/float(filterbank.samplerate)) buffersize = kwds.pop('buffersize', 32) if not isinstance(buffersize, int): buffersize = int(buffersize*self.samplerate) self.buffersize = buffersize self.buffer_pointer = buffersize self.buffer_start = -buffersize NeuronGroup.__init__(self, filterbank.nchannels, *args, **kwds) @network_operation(when=(self.clock, 'start')) def apply_filterbank_output(): if self.buffer_pointer>=self.buffersize: self.buffer_pointer = 0 self.buffer_start += self.buffersize self.buffer = self.filterbank.buffer_fetch(self.buffer_start, self.buffer_start+self.buffersize) setattr(self, targetvar, self.buffer[self.buffer_pointer, :]) self.buffer_pointer += 1 self.contained_objects.append(apply_filterbank_output)
def test_state_variable_access(): G = NeuronGroup(10, 'v:volt') G.v = np.arange(10) * volt assert_equal(np.asarray(G.v[:]), np.arange(10)) assert have_same_dimensions(G.v[:], volt) assert_equal(np.asarray(G.v[:]), G.v_[:]) # Accessing single elements, slices and arrays assert G.v[5] == 5 * volt assert G.v_[5] == 5 assert_equal(G.v[:5], np.arange(5) * volt) assert_equal(G.v_[:5], np.arange(5)) assert_equal(G.v[[0, 5]], [0, 5] * volt) assert_equal(G.v_[[0, 5]], np.array([0, 5])) # Illegal indexing assert_raises(IndexError, lambda: G.v[0, 0]) assert_raises(IndexError, lambda: G.v_[0, 0]) assert_raises(TypeError, lambda: G.v[object()]) assert_raises(TypeError, lambda: G.v_[object()]) # Indexing with strings assert G.v['i==2'] == G.v[2] assert G.v_['i==2'] == G.v_[2] assert_equal(G.v['v >= 3*volt'], G.v[3:]) assert_equal(G.v_['v >= 3*volt'], G.v_[3:]) # Should also check for units assert_raises(DimensionMismatchError, lambda: G.v['v >= 3']) assert_raises(DimensionMismatchError, lambda: G.v['v >= 3*second'])
def test_ipython_html(): G = NeuronGroup(10, '''dv/dt = -(v + Inp) / tau : volt Inp = sin(2*pi*freq*t) : volt freq : Hz''') # Test that HTML representation in IPython does not raise errors assert len(G._repr_html_())
def test_variableview_calculations(): # Check that you can directly calculate with "variable views" G = NeuronGroup(10, '''x : 1 y : volt''') G.x = np.arange(10) G.y = np.arange(10)[::-1]*mV assert_allclose(G.x * G.y, np.arange(10)*np.arange(10)[::-1]*mV) assert_allclose(-G.x, -np.arange(10)) assert_allclose(-G.y, -np.arange(10)[::-1]*mV) assert_allclose(3 * G.x, 3 * np.arange(10)) assert_allclose(3 * G.y, 3 *np.arange(10)[::-1]*mV) assert_allclose(G.x * 3, 3 * np.arange(10)) assert_allclose(G.y * 3, 3 *np.arange(10)[::-1]*mV) assert_allclose(G.x / 2.0, np.arange(10)/2.0) assert_allclose(G.y / 2, np.arange(10)[::-1]*mV/2) assert_allclose(G.x + 2, 2 + np.arange(10)) assert_allclose(G.y + 2*mV, 2*mV + np.arange(10)[::-1]*mV) assert_allclose(2 + G.x, 2 + np.arange(10)) assert_allclose(2*mV + G.y, 2*mV + np.arange(10)[::-1]*mV) assert_allclose(G.x - 2, np.arange(10) - 2) assert_allclose(G.y - 2*mV, np.arange(10)[::-1]*mV - 2*mV) assert_allclose(2 - G.x, 2 - np.arange(10)) assert_allclose(2*mV - G.y, 2*mV - np.arange(10)[::-1]*mV) # incorrect units assert_raises(DimensionMismatchError, lambda: G.x + G.y) assert_raises(DimensionMismatchError, lambda: G.x[:] + G.y) assert_raises(DimensionMismatchError, lambda: G.x + G.y[:]) assert_raises(DimensionMismatchError, lambda: G.x + 3*mV) assert_raises(DimensionMismatchError, lambda: 3*mV + G.x) assert_raises(DimensionMismatchError, lambda: G.y + 3) assert_raises(DimensionMismatchError, lambda: 3 + G.y)
def test_creation(): ''' A basic test that creating a NeuronGroup works. ''' for codeobj_class in codeobj_classes: G = NeuronGroup(42, model='dv/dt = -v/(10*ms) : 1', reset='v=0', threshold='v>1', codeobj_class=codeobj_class) assert len(G) == 42 # Test some error conditions # -------------------------- # Model equations as first argument (no number of neurons) assert_raises(TypeError, lambda: NeuronGroup('dv/dt = 5*Hz : 1', 1)) # Not a number as first argument assert_raises(TypeError, lambda: NeuronGroup(object(), 'dv/dt = 5*Hz : 1')) # Illegal number assert_raises(ValueError, lambda: NeuronGroup(0, 'dv/dt = 5*Hz : 1')) # neither string nor Equations object as model description assert_raises(TypeError, lambda: NeuronGroup(1, object()))
def test_state_variable_access(): for codeobj_class in codeobj_classes: G = NeuronGroup(10, 'v:volt', codeobj_class=codeobj_class) G.v = np.arange(10) * volt assert_equal(np.asarray(G.v[:]), np.arange(10)) assert have_same_dimensions(G.v[:], volt) assert_equal(np.asarray(G.v[:]), G.v_[:]) # Accessing single elements, slices and arrays assert G.v[5] == 5 * volt assert G.v_[5] == 5 assert_equal(G.v[:5], np.arange(5) * volt) assert_equal(G.v_[:5], np.arange(5)) assert_equal(G.v[[0, 5]], [0, 5] * volt) assert_equal(G.v_[[0, 5]], np.array([0, 5])) # Illegal indexing assert_raises(IndexError, lambda: G.v[0, 0]) assert_raises(IndexError, lambda: G.v_[0, 0]) assert_raises(TypeError, lambda: G.v[object()]) assert_raises(TypeError, lambda: G.v_[object()]) # A string representation should not raise any error assert len(str(G.v)) assert len(repr(G.v)) assert len(str(G.v_)) assert len(repr(G.v_))
def __init__(self, filterbank, targetvar, *args, **kwds): self.targetvar = targetvar self.filterbank = filterbank self.buffer = None filterbank.buffer_init() # Sanitize the clock - does it have the right dt value? if 'clock' in kwds: if int(1/kwds['clock'].dt)!=int(filterbank.samplerate): raise ValueError('Clock should have 1/dt=samplerate') kwds['clock'] = Clock(dt=float(kwds['clock'].dt)*second) else: kwds['clock'] = Clock(dt=1*second/float(filterbank.samplerate)) buffersize = kwds.pop('buffersize', 32) if not isinstance(buffersize, int): buffersize = int(buffersize*self.samplerate) self.buffersize = buffersize self.buffer_pointer = buffersize self.buffer_start = -buffersize NeuronGroup.__init__(self, filterbank.nchannels, *args, **kwds) @network_operation(clock=self.clock, when='start') def apply_filterbank_output(): if self.buffer_pointer>=self.buffersize: self.buffer_pointer = 0 self.buffer_start += self.buffersize self.buffer = self.filterbank.buffer_fetch(self.buffer_start, self.buffer_start+self.buffersize) setattr(self, targetvar, self.buffer[self.buffer_pointer, :]) self.buffer_pointer += 1 self.contained_objects.append(apply_filterbank_output)
def test_scalar_parameter_access(): for codeobj_class in codeobj_classes: G = NeuronGroup(10, '''dv/dt = freq : 1 freq : Hz (shared) number : 1 (shared) array : 1''', codeobj_class=codeobj_class) # Try setting a scalar variable G.freq = 100*Hz assert_equal(G.freq[:], 100*Hz) G.freq[:] = 200*Hz assert_equal(G.freq[:], 200*Hz) G.freq = 'freq - 50*Hz + number*Hz' assert_equal(G.freq[:], 150*Hz) G.freq[:] = '50*Hz' assert_equal(G.freq[:], 50*Hz) # Check the second method of accessing that works assert_equal(np.asanyarray(G.freq), 50*Hz) # Check error messages assert_raises(IndexError, lambda: G.freq[0]) assert_raises(IndexError, lambda: G.freq[1]) assert_raises(IndexError, lambda: G.freq[0:1]) assert_raises(IndexError, lambda: G.freq['i>5']) assert_raises(ValueError, lambda: G.freq.set_item(slice(None), [0, 1]*Hz)) assert_raises(IndexError, lambda: G.freq.set_item(0, 100*Hz)) assert_raises(IndexError, lambda: G.freq.set_item(1, 100*Hz)) assert_raises(IndexError, lambda: G.freq.set_item('i>5', 100*Hz))
def test_subexpression(): G = NeuronGroup(10, '''dv/dt = freq : 1 freq : Hz array : 1 expr = 2*freq + array*Hz : Hz''') G.freq = '10*i*Hz' G.array = 5 assert_equal(G.expr[:], 2*10*np.arange(10)*Hz + 5*Hz)
def test_linked_synapses(): ''' Test linking to a synaptic variable (should raise an error). ''' G = NeuronGroup(10, '') S = Synapses(G, G, 'w:1', connect=True) G2 = NeuronGroup(100, 'x : 1 (linked)') assert_raises(NotImplementedError, lambda: setattr(G2, 'x', linked_var(S, 'w')))
def test_indices(): G = NeuronGroup(10, 'v : 1') G.v = 'i' ext_var = 5 assert_equal(G.indices[:], G.i[:]) assert_equal(G.indices[5:], G.indices['i >= 5']) assert_equal(G.indices[5:], G.indices['i >= ext_var']) assert_equal(G.indices['v >= 5'], np.nonzero(G.v >= 5)[0])
def test_variables(): ''' Test the correct creation of the variables dictionary. ''' G = NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1') assert 'v' in G.variables and 't' in G.variables and 'dt' in G.variables G = NeuronGroup(1, 'dv/dt = -v/tau + xi*tau**-0.5: 1') assert not 'tau' in G.variables and 'xi' in G.variables
def test_unit_errors(): ''' Test that units are checked for a complete namespace. ''' # Unit error in model equations assert_raises(DimensionMismatchError, lambda: NeuronGroup(1, 'dv/dt = -v : 1')) assert_raises(DimensionMismatchError, lambda: NeuronGroup(1, 'dv/dt = -v/(10*ms) + 2*mV: 1'))
def test_linked_variable_repeat(): ''' Test a "repeat"-like connection between two groups of different size ''' G1 = NeuronGroup(5, 'w : 1') G2 = NeuronGroup(10, 'v : 1 (linked)') G2.v = linked_var(G1.w, index=np.arange(5).repeat(2)) G1.w = np.arange(5) * 0.1 assert_equal(G2.v[:], np.arange(5).repeat(2) * 0.1)
def test_threshold_reset(): ''' Test that threshold and reset work in the expected way. ''' # Membrane potential does not change by itself G = NeuronGroup(3, 'dv/dt = 0 / second : 1', threshold='v > 1', reset='v=0.5') G.v = np.array([0, 1, 2]) run(defaultclock.dt) assert_equal(G.v[:], np.array([0, 1, 0.5]))
def test_linked_subgroup2(): ''' Test linking a variable from a subgroup with indexing ''' G1 = NeuronGroup(10, 'x : 1') G1.x = np.arange(10) * 0.1 G2 = G1[3:8] G3 = NeuronGroup(10, 'y:1 (linked)') G3.y = linked_var(G2.x, index=np.arange(5).repeat(2)) assert_equal(G3.y[:], (np.arange(5)+3).repeat(2)*0.1)
def test_linked_var_in_reset_size_1(): G1 = NeuronGroup(1, 'x:1') G2 = NeuronGroup(1, '''x_linked : 1 (linked) y:1''', threshold='y>1', reset='y=0; x_linked += 1') G2.x_linked = linked_var(G1, 'x') G2.y = 1.1 # In this context, x_linked should not be considered as a scalar variable # and therefore the reset statement should be allowed run(3*defaultclock.dt) assert_equal(G1.x[:], 1)
def test_linked_variable_indexed(): ''' Test linking a variable with an index specified as an array ''' G = NeuronGroup(10, '''x : 1 y : 1 (linked)''') G.x = np.arange(10)*0.1 G.y = linked_var(G.x, index=np.arange(10)[::-1]) # G.y should refer to an inverted version of G.x assert_equal(G.y[:], np.arange(10)[::-1]*0.1)
def test_group_variable_set_conditional_copy_to_host(): G = NeuronGroup(1, 'v : 1') # uses group_variable_set_conditional template G.v['i < 1'] = '50' # connect template runs on host, requiring G.v on host after the group_variable_set # template call above (this tests that data is copied from device to host) S = Synapses(G, G) S.connect(condition='v_pre == 50') run(0 * second) assert len(S) == 1, len(S)
def test_linked_subgroup(): ''' Test linking a variable from a subgroup ''' G1 = NeuronGroup(10, 'x : 1') G1.x = np.arange(10) * 0.1 G2 = G1[3:8] G3 = NeuronGroup(5, 'y:1 (linked)') G3.y = linked_var(G2.x) assert_equal(G3.y[:], (np.arange(5)+3)*0.1)
def test_custom_events(): G = NeuronGroup(2, '''event_time1 : second event_time2 : second''', events={'event1': 't>=i*ms and t<i*ms+dt', 'event2': 't>=(i+1)*ms and t<(i+1)*ms+dt'}) G.run_on_event('event1', 'event_time1 = t') G.run_on_event('event2', 'event_time2 = t') net = Network(G) net.run(2.1*ms) assert_allclose(G.event_time1[:], [0, 1]*ms) assert_allclose(G.event_time2[:], [1, 2]*ms)
def test_random_vector_values(): # Make sure that the new "loop-invariant optimisation" does not pull out # the random number generation and therefore makes all neurons receiving # the same values tau = 10*ms G = NeuronGroup(100, 'dv/dt = -v / tau + xi*tau**-0.5: 1') G.v[:] = 'rand()' assert np.var(G.v[:]) > 0 G.v[:] = 0 net = Network(G) net.run(defaultclock.dt) assert np.var(G.v[:]) > 0
def test_referred_scalar_variable(): ''' Test the correct handling of referred scalar variables in subexpressions ''' G = NeuronGroup(10, '''out = sin(2*pi*t*freq) + x: 1 x : 1 freq : Hz (shared)''') G.freq = 1*Hz G.x = np.arange(10) G2 = NeuronGroup(10, '') G2.variables.add_reference('out', G) run(.25*second) assert_allclose(G2.out[:], np.arange(10)+1)
def test_linked_var_in_reset_incorrect(): # Raise an error if a scalar variable (linked variable from a group of size # 1 is set in a reset statement of a group with size > 1) G1 = NeuronGroup(1, 'x:1') G2 = NeuronGroup(2, '''x_linked : 1 (linked) y:1''', threshold='y>1', reset='y=0; x_linked += 1') G2.x_linked = linked_var(G1, 'x') G2.y = 1.1 net = Network(G1, G2) # It is not well-defined what x_linked +=1 means in this context # (as for any other shared variable) assert_raises(SyntaxError, lambda: net.run(0*ms))
def test_aliasing_in_statements(): ''' Test an issue around variables aliasing other variables (#259) ''' runner_code = '''x_1 = x_0 x_0 = -1''' g = NeuronGroup(1, model='''x_0 : 1 x_1 : 1 ''', codeobj_class=NumpyCodeObject) custom_code_obj = g.custom_operation(runner_code) net = Network(g, custom_code_obj) net.run(defaultclock.dt) assert_equal(g.x_0_[:], np.array([-1])) assert_equal(g.x_1_[:], np.array([0]))
def test_linked_variable_scalar(): ''' Test linked variable from a size 1 group. ''' G1 = NeuronGroup(1, 'dx/dt = -x / (10*ms) : 1') G2 = NeuronGroup(10, '''dy/dt = (-y + x) / (20*ms) : 1 x : 1 (linked)''') G1.x = 1 G2.y = np.linspace(0, 1, 10) G2.x = linked_var(G1.x) mon = StateMonitor(G2, 'y', record=True) net = Network(G1, G2, mon) net.run(10*ms)
def test_variables(): ''' Test the correct creation of the variables dictionary. ''' G = NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1') assert 'v' in G.variables and 't' in G.variables and 'dt' in G.variables assert 'not_refractory' not in G.variables and 'lastspike' not in G.variables G = NeuronGroup(1, 'dv/dt = -v/tau + xi*tau**-0.5: 1') assert not 'tau' in G.variables and 'xi' in G.variables # NeuronGroup with refractoriness G = NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1', refractory=5*ms) assert 'not_refractory' in G.variables and 'lastspike' in G.variables
def test_linked_variable_correct(): ''' Test correct uses of linked variables. ''' tau = 10*ms G1 = NeuronGroup(10, 'dv/dt = -v / tau : volt') G1.v = np.linspace(0*mV, 20*mV, 10) G2 = NeuronGroup(10, 'v : volt (linked)') G2.v = linked_var(G1.v) mon1 = StateMonitor(G1, 'v', record=True) mon2 = StateMonitor(G2, 'v', record=True) net = Network(G1, G2, mon1, mon2) net.run(10*ms) assert_equal(mon1.v[:, :], mon2.v[:, :])
def test_get_states(): G = NeuronGroup(10, '''v : volt x : 1 subexpr = x + v/volt : 1 subexpr2 = x*volt + v : volt''') G.v = 'i*volt' G.x = '10*i' states_units = G.get_states(['v', 'x', 'subexpr', 'subexpr2'], units=True) states = G.get_states(['v', 'x', 'subexpr', 'subexpr2'], units=False) assert len(states_units.keys()) == len(states.keys()) == 4 assert_equal(states_units['v'], np.arange(10)*volt) assert_equal(states_units['x'], 10*np.arange(10)) assert_equal(states_units['subexpr'], 11*np.arange(10)) assert_equal(states_units['subexpr2'], 11*np.arange(10)*volt) assert_equal(states['v'], np.arange(10)) assert_equal(states['x'], 10*np.arange(10)) assert_equal(states['subexpr'], 11*np.arange(10)) assert_equal(states['subexpr2'], 11*np.arange(10)) all_states = G.get_states(units=True) assert set(all_states.keys()) == {'v', 'x', 'N', 't', 'dt', 'i'} all_states = G.get_states(units=True, subexpressions=True) assert set(all_states.keys()) == {'v', 'x', 'N', 't', 'dt', 'i', 'subexpr', 'subexpr2'}
def test_incorrect_custom_event_definition(): # Incorrect event name assert_raises(TypeError, lambda: NeuronGroup(1, '', events={'1event': 'True'})) # duplicate definition of 'spike' event assert_raises(ValueError, lambda: NeuronGroup(1, '', threshold='True', events={'spike': 'False'})) # not a threshold G = NeuronGroup(1, '', events={'my_event': 10*mV}) assert_raises(TypeError, lambda: Network(G).run(0*ms)) # schedule for a non-existing event G = NeuronGroup(1, '', threshold='False', events={'my_event': 'True'}) assert_raises(ValueError, lambda: G.set_event_schedule('another_event')) # code for a non-existing event assert_raises(ValueError, lambda: G.run_on_event('another_event', ''))
def test_unknown_state_variables(): # Test how setting attribute names that do not correspond to a state # variable are handled G = NeuronGroup(10, 'v : 1') assert_raises(AttributeError, lambda: setattr(G, 'unknown', 42)) # Creating a new private attribute should be fine G._unknown = 42 assert G._unknown == 42 # Explicitly create the attribute G.add_attribute('unknown') G.unknown = 42 assert G.unknown == 42
def test_incomplete_namespace(): ''' Test that the namespace does not have to be complete at creation time. ''' # This uses tau which is not defined yet (explicit namespace) G = NeuronGroup(1, 'dv/dt = -v/tau : 1', namespace={}) G.namespace['tau'] = 10*ms net = Network(G) net.run(0*ms) # This uses tau which is not defined yet (implicit namespace) G = NeuronGroup(1, 'dv/dt = -v/tau : 1') tau = 10*ms net = Network(G) net.run(0*ms)
def test_linked_double_linked3(): ''' Linked to a linked variable, first with indices, second without indices ''' G1 = NeuronGroup(5, 'x : 1') G2 = NeuronGroup(10, 'y : 1 (linked)') G2.y = linked_var(G1.x, index=np.arange(5).repeat(2)) G3 = NeuronGroup(10, 'z: 1 (linked)') G3.z = linked_var(G2.y) G1.x = np.arange(5)*0.1 assert_equal(G3.z[:], np.arange(5).repeat(2)*0.1)
def test_linked_double_linked4(): ''' Linked to a linked variable, both use indices ''' G1 = NeuronGroup(5, 'x : 1') G2 = NeuronGroup(10, 'y : 1 (linked)') G2.y = linked_var(G1.x, index=np.arange(5).repeat(2)) G3 = NeuronGroup(10, 'z: 1 (linked)') G3.z = linked_var(G2.y, index=np.arange(10)[::-1]) G1.x = np.arange(5)*0.1 assert_equal(G3.z[:], np.arange(5).repeat(2)[::-1]*0.1)
def test_linked_double_linked1(): ''' Linked to a linked variable, without indices ''' G1 = NeuronGroup(10, 'x : 1') G2 = NeuronGroup(10, 'y : 1 (linked)') G2.y = linked_var(G1.x) G3 = NeuronGroup(10, 'z: 1 (linked)') G3.z = linked_var(G2.y) G1.x = np.arange(10) assert_equal(G3.z[:], np.arange(10))
def test_aliasing_in_statements(): ''' Test an issue around variables aliasing other variables (#259) ''' if prefs.codegen.target != 'numpy': raise SkipTest('numpy-only test') runner_code = '''x_1 = x_0 x_0 = -1''' g = NeuronGroup(1, model='''x_0 : 1 x_1 : 1 ''') g.run_regularly(runner_code) net = Network(g) net.run(defaultclock.dt) assert_equal(g.x_0_[:], np.array([-1])) assert_equal(g.x_1_[:], np.array([0]))
def test_namespace_errors(): # model equations use unknown identifier G = NeuronGroup(1, 'dv/dt = -v/tau : 1') net = Network(G) assert_raises(KeyError, lambda: net.run(1*ms)) # reset uses unknown identifier G = NeuronGroup(1, 'dv/dt = -v/tau : 1', threshold='False', reset='v = v_r') net = Network(G) assert_raises(KeyError, lambda: net.run(1*ms)) # threshold uses unknown identifier G = NeuronGroup(1, 'dv/dt = -v/tau : 1', threshold='v > v_th') net = Network(G) assert_raises(KeyError, lambda: net.run(1*ms))
def test_get_set_random_generator_state(): group = NeuronGroup(10, 'dv/dt = -v/(10*ms) + (10*ms)**-0.5*xi : 1', method='euler') group.v = 'rand()' run(10 * ms) assert np.var(group.v) > 0 # very basic test for randomness ;) old_v = np.array(group.v) random_state = get_device().get_random_state() group.v = 'rand()' run(10 * ms) assert np.var(group.v - old_v) > 0 # just checking for *some* difference old_v = np.array(group.v) get_device().set_random_state(random_state) group.v = 'rand()' run(10 * ms) assert_equal(group.v, old_v)
def test_linked_subexpression_2(): ''' Test a linked variable referring to a subexpression without indices ''' G = NeuronGroup(2, '''dv/dt = 100*Hz : 1 I = clip(v, 0, inf) : 1''', threshold='v>1', reset='v=0') G.v = [0, .5] G2 = NeuronGroup(2, '''I_l : 1 (linked) ''') G2.I_l = linked_var(G.I) mon1 = StateMonitor(G, 'I', record=True) mon = StateMonitor(G2, 'I_l', record=True) run(5*ms) assert all(mon[0].I_l == mon1[0].I) assert all(mon[1].I_l == mon1[1].I)
def test_stochastic_variable(): ''' Test that a NeuronGroup with a stochastic variable can be simulated. Only makes sure no error occurs. ''' tau = 10 * ms G = NeuronGroup(1, 'dv/dt = -v/tau + xi*tau**-0.5: 1') run(defaultclock.dt)
def test_scalar_subexpression(): G = NeuronGroup(10, '''dv/dt = freq : 1 freq : Hz (shared) number : 1 (shared) array : 1 sub = freq + number*Hz : Hz (shared)''') G.freq = 100*Hz G.number = 50 assert G.sub[:] == 150*Hz assert_raises(SyntaxError, lambda: NeuronGroup(10, '''dv/dt = freq : 1 freq : Hz (shared) array : 1 sub = freq + array*Hz : Hz (shared)''')) # A scalar subexpresion cannot refer to implicitly vectorized functions assert_raises(SyntaxError, lambda: NeuronGroup(10, 'sub = rand() : 1 (shared)'))
def test_subexpression_with_constant(): g = 2 G = NeuronGroup(1, '''x : 1 I = x*g : 1''') G.x = 1 assert_equal(G.I[:], np.array([2])) # Subexpressions that refer to external variables are tricky, see github # issue #313 for details # Comparisons assert G.I == 2 assert G.I >= 1 assert G.I > 1 assert G.I < 3 assert G.I <= 3 assert G.I != 3 # arithmetic operations assert G.I + 1 == 3 assert 1 + G.I == 3 assert G.I * 1 == 2 assert 1 * G.I == 2 assert G.I - 1 == 1 assert 3 - G.I == 1 assert G.I / 1 == 2 assert G.I // 1 == 2.0 assert 1.0 / G.I == 0.5 assert 1 // G.I == 0 assert +G.I == 2 assert -G.I == -2 # other operations assert len(G.I) == 1 # These will not work assert_raises(ValueError, lambda: np.array(G.I)) assert_raises(ValueError, lambda: np.mean(G.I)) # But these should assert_equal(np.array(G.I[:]), G.I[:]) assert np.mean(G.I[:]) == 2 # This will work but display a text, advising to use G.I[:] instead of # G.I assert(len(str(G.I))) assert(len(repr(G.I)))
def test_integer_variables_and_mod(): ''' Test that integer operations and variable definitions work. ''' n = 10 eqs = ''' dv/dt = (a+b+j+k)/second : 1 j = i%n : integer k = i/n : integer a = v%(i+1) : 1 b = v%(2*v) : 1 ''' G = NeuronGroup(100, eqs) G.v = np.random.rand(len(G)) run(1*ms) assert_equal(G.j[:], G.i[:]%n) assert_equal(G.k[:], G.i[:]/n) assert_equal(G.a[:], G.v[:]%(G.i[:]+1))
def test_namespace_warnings(): G = NeuronGroup(1, '''x : 1 y : 1''') # conflicting variable in namespace y = 5 with catch_logs() as l: G.x = 'y' assert len(l) == 1 assert l[0][1].endswith('.resolution_conflict') # conflicting variables with special meaning i = 5 N = 3 with catch_logs() as l: G.x = 'i / N' assert len(l) == 2 assert l[0][1].endswith('.resolution_conflict') assert l[1][1].endswith('.resolution_conflict')