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_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_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_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')
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) # We don't test anything for now, except that it runs without raising an # error run(10*ms) # Make sure that printing the variable values works assert len(str(G2.x)) > 0 assert len(repr(G2.x)) > 0 assert len(str(G2.x[:])) > 0 assert len(repr(G2.x[:])) > 0
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_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_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_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_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_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_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_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_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(KeyError, lambda: np.array(G.I)) assert_raises(KeyError, 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_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_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_linked_variable_indexed_incorrect(): ''' Test errors when providing incorrect index arrays ''' G = NeuronGroup(10, '''x : 1 y : 1 (linked)''') G.x = np.arange(10) * 0.1 assert_raises( TypeError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10) * 1.0))) assert_raises( TypeError, lambda: setattr( G, 'y', linked_var(G.x, index=np.arange(10).reshape(5, 2)))) assert_raises(TypeError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(5)))) assert_raises( ValueError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10) - 1))) assert_raises( ValueError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10) + 1)))
def test_linked_variable_indexed_incorrect(): ''' Test errors when providing incorrect index arrays ''' G = NeuronGroup(10, '''x : 1 y : 1 (linked)''') G.x = np.arange(10)*0.1 assert_raises(TypeError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10)*1.0))) assert_raises(TypeError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10).reshape(5, 2)))) assert_raises(TypeError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(5)))) assert_raises(ValueError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10)-1))) assert_raises(ValueError, lambda: setattr(G, 'y', linked_var(G.x, index=np.arange(10)+1)))
def test_namespace_warnings(): G = NeuronGroup(1, '''x : 1 y : 1''', # unique names to get warnings every time: name='neurongroup_'+str(uuid.uuid4()).replace('-', '_')) # conflicting variable in namespace y = 5 with catch_logs() as l: G.x = 'y' assert len(l) == 1, 'got %s as warnings' % str(l) assert l[0][1].endswith('.resolution_conflict') del y # conflicting variables with special meaning i = 5 N = 3 with catch_logs() as l: G.x = 'i / N' assert len(l) == 2, 'got %s as warnings' % str(l) assert l[0][1].endswith('.resolution_conflict') assert l[1][1].endswith('.resolution_conflict') del i del N # conflicting variables in equations y = 5*Hz G = NeuronGroup(1, '''y : Hz dx/dt = y : 1''', # unique names to get warnings every time: name='neurongroup_'+str(uuid.uuid4()).replace('-', '_')) net = Network(G) with catch_logs() as l: net.run(0*ms) assert len(l) == 1, 'got %s as warnings' % str(l) assert l[0][1].endswith('.resolution_conflict') del y i = 5 # i is referring to the neuron number: G = NeuronGroup(1, '''dx/dt = i*Hz : 1''', # unique names to get warnings every time: name='neurongroup_'+str(uuid.uuid4()).replace('-', '_')) net = Network(G) with catch_logs() as l: net.run(0*ms) assert len(l) == 1, 'got %s as warnings' % str(l) assert l[0][1].endswith('.resolution_conflict') del i # Variables that are used internally but not in equations should not raise # a warning N = 3 i = 5 dt = 1*ms G = NeuronGroup(1, '''dx/dt = x/(10*ms) : 1''', # unique names to get warnings every time: name='neurongroup_'+str(uuid.uuid4()).replace('-', '_')) net = Network(G) with catch_logs() as l: net.run(0*ms) assert len(l) == 0, 'got %s as warnings' % str(l)