def test_state_variables(): ''' Test the setting and accessing of state variables. ''' G = NeuronGroup(10, 'v : volt') G.v = -70 * mV assert_raises(DimensionMismatchError, lambda: G.__setattr__('v', -70)) G.v_ = float(-70 * mV) # Numpy methods should be able to deal with state variables # (discarding units) assert_allclose(np.mean(G.v), float(-70 * mV)) # Getting the content should return a Quantity object which then natively # supports numpy functions that access a method assert_allclose(np.mean(G.v[:]), -70 * mV) # You should also be able to set variables with a string G.v = '-70*mV + i*mV' assert_allclose(G.v[0], -70 * mV) assert_allclose(G.v[9], -61 * mV) assert_allclose(G.v[:], -70 * mV + np.arange(10) * mV) # Calculating with state variables should work too assert all(G.v - G.v == 0) # And in-place modification should work as well G.v += 10 * mV G.v *= 2 # with unit checking assert_raises(DimensionMismatchError, lambda: G.v.__iadd__(3 * second)) assert_raises(DimensionMismatchError, lambda: G.v.__iadd__(3)) assert_raises(DimensionMismatchError, lambda: G.v.__imul__(3 * second))
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_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_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 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_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_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_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_linked_variable_correct(): ''' Test correct uses of linked variables. ''' tau = 10*ms G1 = NeuronGroup(10, 'dv/dt = -v / tau : volt') G1.v = 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) run(10*ms) assert_equal(mon1.v[:, :], mon2.v[:, :]) # Make sure that printing the variable values works assert len(str(G2.v)) > 0 assert len(repr(G2.v)) > 0 assert len(str(G2.v[:])) > 0 assert len(repr(G2.v[:])) > 0
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) run(10*ms) assert_equal(mon1.v[:, :], mon2.v[:, :]) # Make sure that printing the variable values works assert len(str(G2.v)) > 0 assert len(repr(G2.v)) > 0 assert len(str(G2.v[:])) > 0 assert len(repr(G2.v[:])) > 0
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_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_linked_subexpression(): ''' Test a subexpression referring to a linked variable. ''' G = NeuronGroup(2, 'dv/dt = 100*Hz : 1', threshold='v>1', reset='v=0') G.v = [0, .5] G2 = NeuronGroup(10, '''I = clip(x, 0, inf) : 1 x : 1 (linked) ''') G2.x = linked_var(G.v, index=np.array([0, 1]).repeat(5)) mon = StateMonitor(G2, 'I', record=True) run(5*ms) # Due to the linking, the first 5 and the second 5 recorded I vectors should # be identical assert all((all(mon[i].I == mon[0].I) for i in xrange(5))) assert all((all(mon[i+5].I == mon[5].I) for i in xrange(5)))
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_linked_subexpression_3(): ''' Test a linked variable referring to a subexpression with 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(10, '''I_l : 1 (linked) ''') G2.I_l = linked_var(G.I, index=np.array([0, 1]).repeat(5)) mon1 = StateMonitor(G, 'I', record=True) mon = StateMonitor(G2, 'I_l', record=True) run(5*ms) # Due to the linking, the first 5 and the second 5 recorded I vectors should # refer to the assert all((all(mon[i].I_l == mon1[0].I) for i in xrange(5))) assert all((all(mon[i+5].I_l == mon1[1].I) for i in xrange(5)))
def test_linked_subexpression_synapse(): ''' Test a complicated setup (not unlikely when using brian hears) ''' G = NeuronGroup(2, 'dv/dt = 100*Hz : 1', threshold='v>1', reset='v=0') G.v = [0, .5] G2 = NeuronGroup(10, '''I = clip(x, 0, inf) : 1 x : 1 (linked) ''') # This will not be able to include references to `I` as `I_pre` etc., since # the indirect indexing would have to change depending on the synapses G2.x = linked_var(G.v, index=np.array([0, 1]).repeat(5)) S = Synapses(G2, G2, '') S.connect('i==j') assert 'I' not in S.variables assert 'I_pre' not in S.variables assert 'I_post' not in S.variables assert 'x' not in S.variables assert 'x_pre' not in S.variables assert 'x_post' not in S.variables
def test_state_variable_access_strings(): for codeobj_class in codeobj_classes: G = NeuronGroup(10, 'v:volt', codeobj_class=codeobj_class) G.v = np.arange(10) * volt # 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']) # Setting with strings # -------------------- # String value referring to i G.v = '2*i*volt' assert_equal(G.v[:], 2*np.arange(10)*volt) # String value referring to i G.v[:5] = '3*i*volt' assert_equal(G.v[:], np.array([0, 3, 6, 9, 12, 10, 12, 14, 16, 18])*volt) G.v = np.arange(10) * volt # String value referring to a state variable G.v = '2*v' assert_equal(G.v[:], 2*np.arange(10)*volt) G.v[:5] = '2*v' assert_equal(G.v[:], np.array([0, 4, 8, 12, 16, 10, 12, 14, 16, 18])*volt) G.v = np.arange(10) * volt # String value referring to state variables, i, and an external variable ext = 5*volt G.v = 'v + ext + (N + i)*volt' assert_equal(G.v[:], 2*np.arange(10)*volt + 15*volt) G.v = np.arange(10) * volt G.v[:5] = 'v + ext + (N + i)*volt' assert_equal(G.v[:], np.array([15, 17, 19, 21, 23, 5, 6, 7, 8, 9])*volt) G.v = 'v + randn()*volt' # only check that it doesn't raise an error G.v[:5] = 'v + randn()*volt' # only check that it doesn't raise an error G.v = np.arange(10) * volt # String index using a random number G.v['rand() <= 1'] = 0*mV assert_equal(G.v[:], np.zeros(10)*volt) G.v = np.arange(10) * volt # String index referring to i and setting to a scalar value G.v['i>=5'] = 0*mV assert_equal(G.v[:], np.array([0, 1, 2, 3, 4, 0, 0, 0, 0, 0])*volt) # String index referring to a state variable G.v['v<3*volt'] = 0*mV assert_equal(G.v[:], np.array([0, 0, 0, 3, 4, 0, 0, 0, 0, 0])*volt) # String index referring to state variables, i, and an external variable ext = 2*volt G.v['v>=ext and i==(N-6)'] = 0*mV assert_equal(G.v[:], np.array([0, 0, 0, 3, 0, 0, 0, 0, 0, 0])*volt) G.v = np.arange(10) * volt # Strings for both condition and values G.v['i>=5'] = 'v*2' assert_equal(G.v[:], np.array([0, 1, 2, 3, 4, 10, 12, 14, 16, 18])*volt) G.v['v>=5*volt'] = 'i*volt' assert_equal(G.v[:], np.arange(10)*volt)
def test_state_variable_access_strings(): G = NeuronGroup(10, '''v : volt dv_ref/dt = -v_ref/(10*ms) : 1 (unless refractory)''', threshold='v_ref>1', reset='v_ref=1', refractory=1*ms) G.v = np.arange(10) * volt # 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']) # Setting with strings # -------------------- # String value referring to i G.v = '2*i*volt' assert_equal(G.v[:], 2*np.arange(10)*volt) # String value referring to i G.v[:5] = '3*i*volt' assert_equal(G.v[:], np.array([0, 3, 6, 9, 12, 10, 12, 14, 16, 18])*volt) G.v = np.arange(10) * volt # Conditional write variable G.v_ref = '2*i' assert_equal(G.v_ref[:], 2*np.arange(10)) # String value referring to a state variable G.v = '2*v' assert_equal(G.v[:], 2*np.arange(10)*volt) G.v[:5] = '2*v' assert_equal(G.v[:], np.array([0, 4, 8, 12, 16, 10, 12, 14, 16, 18])*volt) G.v = np.arange(10) * volt # String value referring to state variables, i, and an external variable ext = 5*volt G.v = 'v + ext + (N + i)*volt' assert_equal(G.v[:], 2*np.arange(10)*volt + 15*volt) G.v = np.arange(10) * volt G.v[:5] = 'v + ext + (N + i)*volt' assert_equal(G.v[:], np.array([15, 17, 19, 21, 23, 5, 6, 7, 8, 9])*volt) G.v = 'v + randn()*volt' # only check that it doesn't raise an error G.v[:5] = 'v + randn()*volt' # only check that it doesn't raise an error G.v = np.arange(10) * volt # String index using a random number G.v['rand() <= 1'] = 0*mV assert_equal(G.v[:], np.zeros(10)*volt) G.v = np.arange(10) * volt # String index referring to i and setting to a scalar value G.v['i>=5'] = 0*mV assert_equal(G.v[:], np.array([0, 1, 2, 3, 4, 0, 0, 0, 0, 0])*volt) # String index referring to a state variable G.v['v<3*volt'] = 0*mV assert_equal(G.v[:], np.array([0, 0, 0, 3, 4, 0, 0, 0, 0, 0])*volt) # String index referring to state variables, i, and an external variable ext = 2*volt G.v['v>=ext and i==(N-6)'] = 0*mV assert_equal(G.v[:], np.array([0, 0, 0, 3, 0, 0, 0, 0, 0, 0])*volt) G.v = np.arange(10) * volt # Strings for both condition and values G.v['i>=5'] = 'v*2' assert_equal(G.v[:], np.array([0, 1, 2, 3, 4, 10, 12, 14, 16, 18])*volt) G.v['v>=5*volt'] = 'i*volt' assert_equal(G.v[:], np.arange(10)*volt) G.v['i<=5'] = '(100 + rand())*volt' assert_equal(G.v[6:], np.arange(4)*volt + 6*volt) # unchanged assert all(G.v[:6] >= 100*volt) assert all(G.v[:6] <= 101*volt) assert np.var(G.v_[:6]) > 0
def test_state_variables(): ''' Test the setting and accessing of state variables. ''' for codeobj_class in codeobj_classes: G = NeuronGroup(10, 'v : volt', codeobj_class=codeobj_class) # The variable N should be always present assert G.N == 10 # But it should be read-only assert_raises(TypeError, lambda: G.__setattr__('N', 20)) assert_raises(TypeError, lambda: G.__setattr__('N_', 20)) G.v = -70*mV assert_raises(DimensionMismatchError, lambda: G.__setattr__('v', -70)) G.v_ = float(-70*mV) assert_allclose(G.v[:], -70*mV) G.v = -70*mV + np.arange(10)*mV assert_allclose(G.v[:], -70*mV + np.arange(10)*mV) G.v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * volt assert_allclose(G.v[:], np.arange(10) * volt) # incorrect size assert_raises(ValueError, lambda: G.__setattr__('v', [0, 1]*volt)) assert_raises(ValueError, lambda: G.__setattr__('v', np.arange(11)*volt)) G.v = -70*mV # Numpy methods should be able to deal with state variables # (discarding units) assert_allclose(np.mean(G.v), float(-70*mV)) # Getting the content should return a Quantity object which then natively # supports numpy functions that access a method assert_allclose(np.mean(G.v[:]), -70*mV) # You should also be able to set variables with a string G.v = '-70*mV + i*mV' assert_allclose(G.v[0], -70*mV) assert_allclose(G.v[9], -61*mV) assert_allclose(G.v[:], -70*mV + np.arange(10)*mV) # And it should raise an unit error if the units are incorrect assert_raises(DimensionMismatchError, lambda: G.__setattr__('v', '70 + i')) assert_raises(DimensionMismatchError, lambda: G.__setattr__('v', '70 + i*mV')) # Calculating with state variables should work too # With units assert all(G.v - G.v == 0) assert all(G.v - G.v[:] == 0*mV) assert all(G.v[:] - G.v == 0*mV) assert all(G.v + 70*mV == G.v[:] + 70*mV) assert all(70*mV + G.v == G.v[:] + 70*mV) assert all(G.v + G.v == 2*G.v) assert all(G.v / 2.0 == 0.5*G.v) assert all(1.0 / G.v == 1.0 / G.v[:]) assert_equal((-G.v)[:], -G.v[:]) assert_equal((+G.v)[:], G.v[:]) #Without units assert all(G.v_ - G.v_ == 0) assert all(G.v_ - G.v_[:] == 0) assert all(G.v_[:] - G.v_ == 0) assert all(G.v_ + float(70*mV) == G.v_[:] + float(70*mV)) assert all(float(70*mV) + G.v_ == G.v_[:] + float(70*mV)) assert all(G.v_ + G.v_ == 2*G.v_) assert all(G.v_ / 2.0 == 0.5*G.v_) assert all(1.0 / G.v_ == 1.0 / G.v_[:]) assert_equal((-G.v)[:], -G.v[:]) assert_equal((+G.v)[:], G.v[:]) # And in-place modification should work as well G.v += 10*mV G.v -= 10*mV G.v *= 2 G.v /= 2.0 # with unit checking assert_raises(DimensionMismatchError, lambda: G.v.__iadd__(3*second)) assert_raises(DimensionMismatchError, lambda: G.v.__iadd__(3)) assert_raises(DimensionMismatchError, lambda: G.v.__imul__(3*second)) # in-place modification with strings should not work assert_raises(TypeError, lambda: G.v.__iadd__('string')) assert_raises(TypeError, lambda: G.v.__imul__('string')) assert_raises(TypeError, lambda: G.v.__idiv__('string')) assert_raises(TypeError, lambda: G.v.__isub__('string'))