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_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'))