Ejemplo n.º 1
0
def test_loop():
    '''
    Somewhat realistic test with a loop of magic networks
    '''
    def run_simulation():
        G = NeuronGroup(10, 'dv/dt = -v / (10*ms) : 1',
                        reset='v=0', threshold='v>1')
        G.v = np.linspace(0, 1, 10)
        run(1*ms)
        # We return potentially problematic references to a VariableView
        return G.v

    # First run
    with catch_logs(log_level=logging.INFO) as l:
        v = run_simulation()
        assert v[0] == 0 and 0 < v[-1] < 1
        # Check the debug messages for the number of included objects
        magic_objects = [msg[2] for msg in l
                         if msg[1] == 'brian2.core.magic.magic_objects'][0]
        assert '4 objects' in magic_objects


    # Second run
    with catch_logs(log_level=logging.INFO) as l:
        v = run_simulation()
        assert v[0] == 0 and 0 < v[-1] < 1
        # Check the debug messages for the number of included objects
        magic_objects = [msg[2] for msg in l
                         if msg[1] == 'brian2.core.magic.magic_objects'][0]
        assert '4 objects' in magic_objects
Ejemplo n.º 2
0
def test_locally_constant_check():
    default_dt = defaultclock.dt
    # The linear state update can handle additive time-dependent functions
    # (e.g. a TimedArray) but only if it can be safely assumed that the function
    # is constant over a single time check
    ta0 = TimedArray(np.array([1]), dt=default_dt)  # ok
    ta1 = TimedArray(np.array([1]), dt=2*default_dt)  # ok
    ta2 = TimedArray(np.array([1]), dt=default_dt/2)  # not ok
    ta3 = TimedArray(np.array([1]), dt=default_dt*1.5)  # not ok

    for ta_func, ok in zip([ta0, ta1, ta2, ta3], [True, True, False, False]):
        # additive
        G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + ta(t)*Hz : 1',
                        method='linear', namespace={'ta': ta_func})
        net = Network(G)
        if ok:
            # This should work
            net.run(0*ms)
        else:
            # This should not
            with catch_logs():
                assert_raises(UnsupportedEquationsException, lambda: net.run(0*ms))

        # multiplicative
        G = NeuronGroup(1, 'dv/dt = -v*ta(t)/(10*ms) : 1',
                        method='linear', namespace={'ta': ta_func})
        net = Network(G)
        if ok:
            # This should work
            net.run(0*ms)
        else:
            # This should not
            with catch_logs():
                assert_raises(UnsupportedEquationsException, lambda: net.run(0*ms))

    # If the argument is more than just "t", we cannot guarantee that it is
    # actually locally constant
    G = NeuronGroup(1, 'dv/dt = -v*ta(t/2.0)/(10*ms) : 1',
                        method='linear', namespace={'ta': ta0})
    net = Network(G)
    assert_raises(UnsupportedEquationsException, lambda: net.run(0*ms))

    # Arbitrary functions are not constant over a time step
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + sin(2*pi*100*Hz*t)*Hz : 1',
                    method='linear')
    net = Network(G)
    assert_raises(UnsupportedEquationsException, lambda: net.run(0*ms))

    # Neither is "t" itself
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + t/second**2 : 1', method='linear')
    net = Network(G)
    assert_raises(UnsupportedEquationsException, lambda: net.run(0*ms))

    # But if the argument is not referring to t, all should be well
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + sin(2*pi*100*Hz*5*second)*Hz : 1',
                    method='linear')
    net = Network(G)
    net.run(0*ms)
Ejemplo n.º 3
0
def test_locally_constant_check():
    default_dt = defaultclock.dt
    # The linear state update can handle additive time-dependent functions
    # (e.g. a TimedArray) but only if it can be safely assumed that the function
    # is constant over a single time check
    ta0 = TimedArray(np.array([1]), dt=default_dt)  # ok
    ta1 = TimedArray(np.array([1]), dt=2*default_dt)  # ok
    ta2 = TimedArray(np.array([1]), dt=default_dt/2)  # not ok
    ta3 = TimedArray(np.array([1]), dt=default_dt*1.5)  # not ok

    for ta_func, ok in zip([ta0, ta1, ta2, ta3], [True, True, False, False]):
        # additive
        G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + ta(t)*Hz : 1',
                        method='linear', namespace={'ta': ta_func})
        net = Network(G)
        if ok:
            # This should work
            net.run(0*ms)
        else:
            # This should not
            with catch_logs():
                assert_raises(ValueError, lambda: net.run(0*ms))

        # multiplicative
        G = NeuronGroup(1, 'dv/dt = -v*ta(t)/(10*ms) : 1',
                        method='linear', namespace={'ta': ta_func})
        net = Network(G)
        if ok:
            # This should work
            net.run(0*ms)
        else:
            # This should not
            with catch_logs():
                assert_raises(ValueError, lambda: net.run(0*ms))

    # If the argument is more than just "t", we cannot guarantee that it is
    # actually locally constant
    G = NeuronGroup(1, 'dv/dt = -v*ta(t/2.0)/(10*ms) : 1',
                        method='linear', namespace={'ta': ta0})
    net = Network(G)
    assert_raises(ValueError, lambda: net.run(0*ms))

    # Arbitrary functions are not constant over a time step
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + sin(2*pi*100*Hz*t)*Hz : 1',
                    method='linear')
    net = Network(G)
    assert_raises(ValueError, lambda: net.run(0*ms))

    # Neither is "t" itself
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + t/second**2 : 1', method='linear')
    net = Network(G)
    assert_raises(ValueError, lambda: net.run(0*ms))

    # But if the argument is not referring to t, all should be well
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + sin(2*pi*100*Hz*5*second)*Hz : 1',
                    method='linear')
    net = Network(G)
    net.run(0*ms)
Ejemplo n.º 4
0
def test_set_interval_warning():
    clock = Clock(dt=0.1*ms)
    with catch_logs() as logs:
        clock.set_interval(0*second, 1000*second)  # no problem
    assert len(logs) == 0
    with catch_logs() as logs:
        clock.set_interval(0*second, 10000000000*second)  # too long
    assert len(logs) == 1
    assert logs[0][1].endswith('many_timesteps')
Ejemplo n.º 5
0
def test_schedule_warning():
    previous_device = get_device()
    from uuid import uuid4
    # TestDevice1 supports arbitrary schedules, TestDevice2 does not
    class TestDevice1(Device):
        # These functions are needed during the setup of the defaultclock
        def get_value(self, var):
            return np.array([0.0001])
        def add_array(self, var):
            pass
        def init_with_zeros(self, var, dtype):
            pass
        def fill_with_array(self, var, arr):
            pass
    class TestDevice2(TestDevice1):
        def __init__(self):
            super(TestDevice2, self).__init__()
            self.network_schedule = ['start', 'groups', 'synapses',
                                     'thresholds', 'resets', 'end']

    # Unique names are important for getting the warnings again for multiple
    # runs of the test suite
    name1 = 'testdevice_' + str(uuid4())
    name2 = 'testdevice_' + str(uuid4())
    all_devices[name1] = TestDevice1()
    all_devices[name2] = TestDevice2()

    set_device(name1)
    assert schedule_propagation_offset() == 0*ms
    net = Network()
    assert schedule_propagation_offset(net) == 0*ms

    # Any schedule should work
    net.schedule = list(reversed(net.schedule))
    with catch_logs() as l:
        net.run(0*ms)
        assert len(l) == 0, 'did not expect a warning'

    assert schedule_propagation_offset(net) == defaultclock.dt

    set_device(name2)
    assert schedule_propagation_offset() == defaultclock.dt

    # Using the correct schedule should work
    net.schedule = ['start', 'groups', 'synapses', 'thresholds', 'resets', 'end']
    with catch_logs() as l:
        net.run(0*ms)
        assert len(l) == 0, 'did not expect a warning'
    assert schedule_propagation_offset(net) == defaultclock.dt

    # Using another (e.g. the default) schedule should raise a warning
    net.schedule = None
    with catch_logs() as l:
        net.run(0*ms)
        assert len(l) == 1 and l[0][1].endswith('schedule_conflict')
    reset_device(previous_device)
Ejemplo n.º 6
0
def test_schedule_warning():
    previous_device = get_device()
    from uuid import uuid4

    # TestDevice1 supports arbitrary schedules, TestDevice2 does not
    class TestDevice1(Device):
        # These functions are needed during the setup of the defaultclock
        def get_value(self, var):
            return np.array([0.0001])

        def add_array(self, var):
            pass

        def init_with_zeros(self, var, dtype):
            pass

        def fill_with_array(self, var, arr):
            pass

    class TestDevice2(TestDevice1):
        def __init__(self):
            super(TestDevice2, self).__init__()
            self.network_schedule = [
                'start', 'groups', 'synapses', 'thresholds', 'resets', 'end'
            ]

    # Unique names are important for getting the warnings again for multiple
    # runs of the test suite
    name1 = 'testdevice_' + str(uuid4())
    name2 = 'testdevice_' + str(uuid4())
    all_devices[name1] = TestDevice1()
    all_devices[name2] = TestDevice2()

    set_device(name1)
    net = Network()
    # Any schedule should work
    net.schedule = list(reversed(net.schedule))
    with catch_logs() as l:
        net.run(0 * ms)
        assert len(l) == 0, 'did not expect a warning'

    set_device(name2)
    # Using the correct schedule should work
    net.schedule = [
        'start', 'groups', 'synapses', 'thresholds', 'resets', 'end'
    ]
    with catch_logs() as l:
        net.run(0 * ms)
        assert len(l) == 0, 'did not expect a warning'

    # Using another (e.g. the default) schedule should raise a warning
    net.schedule = None
    with catch_logs() as l:
        net.run(0 * ms)
        assert len(l) == 1 and l[0][1].endswith('schedule_conflict')
    reset_device(previous_device)
Ejemplo n.º 7
0
def test_resolution_warnings():
    '''
    Test that certain calls to resolve generate a warning.
    '''
    I = 3 * mV
    tau = 5 * ms
    another_I = 5 * mV
    # Only specifying part of the namespace
    expr = Expression('-(v + I) / tau', namespace={'I' : another_I},
                      exhaustive=False)
    
    # make sure this triggers a warning (the 'I' in the namespace shadows the
    # I variable defined above
    with catch_logs() as logs:
        namespace = expr.resolve(['v'])
        assert len(logs) == 1
        assert logs[0][0] == 'WARNING' 
        assert logs[0][1].endswith('resolution_conflict')
        assert namespace['I'] == another_I and namespace['tau'] == tau
    
    freq = 300 * Hz
    t = 5 * second
    # This expression treats t as a special variable and is not actually using
    # the t above!
    expr = Expression('sin(2 * 3.141 * freq * t)')
    with catch_logs() as logs:
        namespace = expr.resolve([])
        assert len(logs) == 1
        assert logs[0][0] == 'WARNING' 
        assert logs[0][1].endswith('resolution_conflict')            
        assert namespace['freq'] == freq and not 't' in namespace

    I = 3 * mV
    tau = 5 * ms    
    expr = Expression('-(v + I)/ tau')
    # If we claim that I is an internal variable, it shadows the variable
    # defined in the local namespace -- this should trigger a warning
    with catch_logs() as logs:
        namespace = expr.resolve(['v', 'I'])
        assert len(logs) == 1
        assert logs[0][0] == 'WARNING' 
        assert logs[0][1].endswith('resolution_conflict')
        assert namespace['tau'] == tau and not 'I' in namespace
    
    # A more extreme example: I is defined above, but also in the namespace and
    # is claimed to be an internal variable
    expr = Expression('-(v + I)/ tau', namespace={'I': 5 * mV},
                      exhaustive=False)
    with catch_logs() as logs:
        namespace = expr.resolve(['v', 'I'])
        assert len(logs) == 1
        assert logs[0][0] == 'WARNING' 
        assert logs[0][1].endswith('resolution_conflict')
        assert namespace['tau'] == tau and not 'I' in namespace
Ejemplo n.º 8
0
def test_warning_internal_variables():
    group1 = SimpleGroup(namespace=None,
                         variables={'N': Constant('N', Unit(1), 5)})
    group2 = SimpleGroup(namespace=None,
                         variables={'N': Constant('N', Unit(1), 7)})
    with catch_logs() as l:
        group1.resolve_all(['N'], run_namespace={'N': 5})  # should not raise a warning
        assert len(l) == 0, 'got warnings: %s' % str(l)
    with catch_logs() as l:
        group2.resolve_all(['N'], run_namespace={'N': 5})  # should raise a warning
        assert len(l) == 1, 'got warnings: %s' % str(l)
        assert l[0][1].endswith('.resolution_conflict')
Ejemplo n.º 9
0
def test_warning_internal_variables():
    group1 = SimpleGroup(namespace=None,
                         variables={'N': Constant('N', 5)})
    group2 = SimpleGroup(namespace=None,
                         variables={'N': Constant('N', 7)})
    with catch_logs() as l:
        group1.resolve_all(['N'], run_namespace={'N': 5})  # should not raise a warning
        assert len(l) == 0, 'got warnings: %s' % str(l)
    with catch_logs() as l:
        group2.resolve_all(['N'], run_namespace={'N': 5})  # should raise a warning
        assert len(l) == 1, 'got warnings: %s' % str(l)
        assert l[0][1].endswith('.resolution_conflict')
Ejemplo n.º 10
0
def test_explicit_namespace():
    ''' Test resolution with an explicitly provided namespace '''
    group = SimpleGroup(namespace={'variable': 42}, variables={})

    # Explicitly provided
    with catch_logs() as l:
        assert group._resolve('variable', {}).get_value_with_unit() == 42
        assert len(l) == 0

    # Value from an explicit run namespace
    with catch_logs() as l:
        assert group._resolve('yet_another_var',
                              run_namespace={'yet_another_var': 17}).get_value_with_unit() == 17
        assert len(l) == 0
Ejemplo n.º 11
0
def test_explicit_namespace():
    ''' Test resolution with an explicitly provided namespace '''
    group = SimpleGroup(namespace={'variable': 42}, variables={})

    # Explicitly provided
    with catch_logs() as l:
        assert group._resolve('variable', {}).get_value_with_unit() == 42
        assert len(l) == 0

    # Value from an explicit run namespace
    with catch_logs() as l:
        assert group._resolve('yet_another_var',
                              run_namespace={'yet_another_var': 17}).get_value_with_unit() == 17
        assert len(l) == 0
Ejemplo n.º 12
0
def test_semantics_floor_division():
    # See Brian2 github issues #815 and #661
    G = NeuronGroup(11,
                    '''a : integer
                           b : integer
                           x : 1
                           y : 1
                           fvalue : 1
                           ivalue : integer''',
                    dtype={
                        'a': np.int32,
                        'b': np.int64,
                        'x': np.float,
                        'y': np.double
                    })
    int_values = np.arange(-5, 6)
    float_values = np.arange(-5.0, 6.0, dtype=np.double)
    G.ivalue = int_values
    G.fvalue = float_values
    with catch_logs() as l:
        G.run_regularly('''
        a = ivalue//3
        b = ivalue//3
        x = fvalue//3
        y = fvalue//3
        ''')
        run(defaultclock.dt)
    # XXX: brian2 test adapted here for 1 warning
    assert len(l) == 1
    assert_equal(G.a[:], int_values // 3)
    assert_equal(G.b[:], int_values // 3)
    assert_allclose(G.x[:], float_values // 3)
    assert_allclose(G.y[:], float_values // 3)
Ejemplo n.º 13
0
def test_math_functions(func):
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code.
    '''
    test_array = np.array([-1, -0.5, 0, 0.5, 1])

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Calculate the result directly
        numpy_result = func(test_array)

        # Calculate the result in a somewhat complicated way by using a
        # subexpression in a NeuronGroup
        if func.__name__ == 'absolute':
            # we want to use the name abs instead of absolute
            func_name = 'abs'
        else:
            func_name = func.__name__
        G = NeuronGroup(
            len(test_array), '''func = {func}(variable) : 1
                           variable : 1'''.format(func=func_name))
        G.variable = test_array
        mon = StateMonitor(G, 'func', record=True)
        net = Network(G, mon)
        net.run(defaultclock.dt)

        assert_allclose(
            numpy_result,
            mon.func_.flatten(),
            err_msg='Function %s did not return the correct values' %
            func.__name__)
Ejemplo n.º 14
0
def test_math_functions_short():
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code. Test only a few functions
    '''
    default_dt = defaultclock.dt
    test_array = np.array([-1, -0.5, 0, 0.5, 1])

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Functions with a single argument
        for func in [exp, np.sqrt]:

            # Calculate the result directly
            numpy_result = func(test_array)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            if func.__name__ == 'absolute':
                # we want to use the name abs instead of absolute
                func_name = 'abs'
            else:
                func_name = func.__name__
            G = NeuronGroup(
                len(test_array), '''func = {func}(variable) : 1
                               variable : 1'''.format(func=func_name))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(
                numpy_result,
                mon.func_.flatten(),
                err_msg='Function %s did not return the correct values' %
                func.__name__)

        # Functions/operators
        scalar = 3
        # TODO: We are not testing the modulo operator here since it does
        #       not work for double values in C
        for func, operator in [(np.power, '**')]:

            # Calculate the result directly
            numpy_result = func(test_array, scalar)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            G = NeuronGroup(
                len(test_array), '''func = variable {op} scalar : 1
                               variable : 1'''.format(op=operator))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(
                numpy_result,
                mon.func_.flatten(),
                err_msg='Function %s did not return the correct values' %
                func.__name__)
Ejemplo n.º 15
0
def test_missing_refractory_warning():
    # Forgotten refractory argument
    with catch_logs() as l:
        group = NeuronGroup(1, 'dv/dt = -v / (10*ms) : 1 (unless refractory)',
                            threshold='v > 1', reset='v = 0')
    assert len(l) == 1
    assert l[0][0] == 'WARNING' and l[0][1].endswith('no_refractory')
Ejemplo n.º 16
0
def test_check_for_invalid_values_linear_integrator():
    # A differential equation that cannot be solved by the linear
    # integrator should return nan values to warn the user, and not silently
    # return incorrect values. See discussion on
    # https://github.com/brian-team/brian2/issues/626
    a = 0.0 / ms
    b = 1.0 / ms
    c = -0.5 / ms
    d = -0.1 / ms
    eqs = '''
    dx/dt = a * x + b * y : 1
    dy/dt = c * x + d * y : 1
    '''
    G = NeuronGroup(1, eqs, threshold='x > 100', reset='x = 0', method='exact')
    G.x = 1
    BrianLogger._log_messages.clear(
    )  # because the log message is set to be shown only once
    with catch_logs() as clog:
        try:
            run(1 * ms)
            # this check allows for the possibility that we improve the linear
            # integrator in the future so that it can handle this equation
            if numpy.isnan(G.x[0]):
                assert 'invalid_values' in repr(clog)
            else:
                assert G.x[0] != 0
        except UnsupportedEquationsException:
            pass
Ejemplo n.º 17
0
def test_missing_refractory_warning():
    # Forgotten refractory argument
    with catch_logs() as l:
        group = NeuronGroup(1, 'dv/dt = -v / (10*ms) : 1 (unless refractory)',
                            threshold='v > 1', reset='v = 0')
    assert len(l) == 1
    assert l[0][0] == 'WARNING' and l[0][1].endswith('no_refractory')
Ejemplo n.º 18
0
def test_compiler_error():
    # In particular on OSX with clang in a conda environment, compilation might fail.
    # Switching to a system gcc might help in such cases. Make sure that the error
    # message mentions that.
    old_CC = os.environ.get('CC', None)
    old_CXX = os.environ.get('CXX', None)
    os.environ.update({
        'CC': 'non-existing-compiler',
        'CXX': 'non-existing-compiler++'
    })
    try:
        with catch_logs() as l:
            assert not CythonCodeObject.is_available()
        assert len(l) > 0  # There are additional warnings about compiler flags
        last_warning = l[-1]
        assert last_warning[1].endswith('.failed_compile_test')
        assert 'CC' in last_warning[2] and 'CXX' in last_warning[2]

    finally:
        if old_CC:
            os.environ['CC'] = old_CC
        else:
            del os.environ['CC']
        if old_CXX:
            os.environ['CXX'] = old_CXX
        else:
            del os.environ['CXX']
Ejemplo n.º 19
0
def test_math_functions(func, needs_c99_support):
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code.
    '''
    if not get_device() == RuntimeDevice or prefs.codegen.target != 'numpy':
        if needs_c99_support and not compiler_supports_c99():
            pytest.skip('Support for function "{}" needs a compiler with C99 '
                        'support.')
    test_array = np.array([-1, -0.5, 0, 0.5, 1])

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Calculate the result directly
        numpy_result = func(test_array)

        # Calculate the result in a somewhat complicated way by using a
        # subexpression in a NeuronGroup
        if func.__name__ == 'absolute':
            # we want to use the name abs instead of absolute
            func_name = 'abs'
        else:
            func_name = func.__name__
        G = NeuronGroup(
            len(test_array), '''func = {func}(variable) : 1
                           variable : 1'''.format(func=func_name))
        G.variable = test_array
        mon = StateMonitor(G, 'func', record=True)
        net = Network(G, mon)
        net.run(defaultclock.dt)

        assert_allclose(
            numpy_result,
            mon.func_.flatten(),
            err_msg='Function %s did not return the correct values' %
            func.__name__)
Ejemplo n.º 20
0
def test_transmission_scalar_delay_different_clocks():

    inp = SpikeGeneratorGroup(
        2,
        [0, 1],
        [0, 1] * ms,
        dt=0.5 * ms,
        # give the group a unique name to always
        # get a 'fresh' warning
        name='sg_%d' % uuid.uuid4())
    target = NeuronGroup(2, 'v:1', dt=0.1 * ms)
    S = Synapses(inp, target, pre='v+=1', delay=0.5 * ms, connect='i==j')
    mon = StateMonitor(target, 'v', record=True)
    net = Network(inp, target, S, mon)

    # We should get a warning when using inconsistent dts
    with catch_logs() as l:
        net.run(2 * ms)
        assert len(l) == 1, 'expected a warning, got %d' % len(l)
        assert l[0][1].endswith('synapses_dt_mismatch')

    assert_equal(mon[0].v[mon.t < 0.5 * ms], 0)
    assert_equal(mon[0].v[mon.t >= 0.5 * ms], 1)
    assert_equal(mon[1].v[mon.t < 1.5 * ms], 0)
    assert_equal(mon[1].v[mon.t >= 1.5 * ms], 1)
Ejemplo n.º 21
0
def test_dependency_check():
    def create_net():
        G = NeuronGroup(10, 'v: 1', threshold='False')
        dependent_objects = [
                             StateMonitor(G, 'v', record=True),
                             SpikeMonitor(G),
                             PopulationRateMonitor(G),
                             Synapses(G, G, pre='v+=1', connect=True)
                             ]
        return dependent_objects

    dependent_objects = create_net()
    # Trying to simulate the monitors/synapses without the group should fail
    for obj in dependent_objects:
        assert_raises(ValueError, lambda: Network(obj).run(0*ms))

    # simulation with a magic network should work when we have an explicit
    # reference to one of the objects, but the object should be inactive and
    # we should get a warning
    assert all(obj.active for obj in dependent_objects)
    for obj in dependent_objects:  # obj is our explicit reference
        with catch_logs() as l:
            run(0*ms)
            dependency_warnings = [msg[2] for msg in l
                                   if msg[1] == 'brian2.core.magic.dependency_warning']
            assert len(dependency_warnings) == 1
        assert not obj.active
Ejemplo n.º 22
0
def test_synapses_access_subgroups_problematic():
    G1 = NeuronGroup(5, 'x:1')
    G2 = NeuronGroup(10, 'y:1')
    SG1 = G1[2:5]
    SG2 = G2[4:9]
    S = Synapses(G1, G2, 'w:1')
    S.connect()

    # Note that "j" is not ambiguous, because the equivalent in the target group
    # is called "i" (this previously raised a warning)
    tests = [
        ((SG1, slice(None)), 'i', 1),
        ((SG1, slice(None)), 'i + N_pre', 2),
        ((SG1, slice(None)), 'N_pre', 1),
        ((slice(None), SG2), 'j', 0),
        ((slice(None), SG2), 'N_post', 1),
        ((slice(None), SG2), 'N', 1),
        ((SG1, SG2), 'i', 1),
        ((SG1, SG2), 'i + j', 1),
        ((SG1, SG2), 'N_pre', 1),
        ((SG1, SG2), 'j', 0),
        ((SG1, SG2), 'N_post', 1),
        ((SG1, SG2), 'N', 1),
        # These should not raise a warning
        ((SG1, SG2), 'w', 0),
        ((SG1, SG2), 'x_pre', 0),
        ((SG1, SG2), 'y_post', 0),
        ((SG1, SG2), 'y', 0)
        ]
    for item, value, n_warnings in tests:
        with catch_logs() as l:
            S.w.__setitem__(item, value)
            assert len(l) == n_warnings, 'expected %d, got %d warnings' % (n_warnings, len(l))
            assert all([entry[1].endswith('ambiguous_string_expression')
                        for entry in l])
Ejemplo n.º 23
0
def test_math_functions():
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code.
    '''
    default_dt = defaultclock.dt
    test_array = np.array([-1, -0.5, 0, 0.5, 1])
    def int_(x):
        return array(x, dtype=int)
    int_.__name__ = 'int'

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Functions with a single argument
        for func in [cos, tan, sinh, cosh, tanh,
                     arcsin, arccos, arctan,
                     log, log10,
                     exp, np.sqrt,
                     np.ceil, np.floor, np.sign, int_]:

            # Calculate the result directly
            numpy_result = func(test_array)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            if func.__name__ == 'absolute':
                # we want to use the name abs instead of absolute
                func_name = 'abs'
            else:
                func_name = func.__name__
            G = NeuronGroup(len(test_array),
                            '''func = {func}(variable) : 1
                               variable : 1'''.format(func=func_name))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(numpy_result, mon.func_.flatten(),
                            err_msg='Function %s did not return the correct values' % func.__name__)

        # Functions/operators
        scalar = 3
        for func, operator in [(np.power, '**'), (np.mod, '%')]:

            # Calculate the result directly
            numpy_result = func(test_array, scalar)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            G = NeuronGroup(len(test_array),
                            '''func = variable {op} scalar : 1
                               variable : 1'''.format(op=operator))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(numpy_result, mon.func_.flatten(),
                            err_msg='Function %s did not return the correct values' % func.__name__)
Ejemplo n.º 24
0
def test_multiple_noise_variables_deterministic_noise():
    # The "random" values are always 0.5
    @implementation('cpp',
                    '''
                    double randn(int vectorisation_idx)
                    {
                        return 0.5;
                    }
                    ''')
    @implementation('cython',
                    '''
                    cdef double randn(int vectorisation_idx):
                        return 0.5
                    ''')
    @check_units(N=Unit(1), result=Unit(1))
    def fake_randn(N):
        return 0.5*ones(N)

    old_randn = DEFAULT_FUNCTIONS['randn']
    DEFAULT_FUNCTIONS['randn'] = fake_randn

    all_eqs = ['''dx/dt = y : 1
                          dy/dt = -y / (10*ms) + dt**-.5*0.5*ms**-1.5 + dt**-.5*0.5*ms**-1.5: Hz
                     ''',
                     '''dx/dt = y + dt**-.5*0.5*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + dt**-.5*0.5 * ms**-1.5 : Hz
                ''']
    all_eqs_noise = ['''dx/dt = y : 1
                          dy/dt = -y / (10*ms) + xi_1 * ms**-1.5 + xi_2 * ms**-1.5: Hz
                     ''',
                     '''dx/dt = y + xi_1*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + xi_2 * ms**-1.5 : Hz
                     ''']
    for eqs, eqs_noise in zip(all_eqs, all_eqs_noise):
        G = NeuronGroup(2, eqs, method='euler')
        G.x = [5,  17]
        G.y = [25, 5 ] * Hz
        mon = StateMonitor(G, ['x', 'y'], record=True)
        net = Network(G, mon)
        net.run(10*ms)
        no_noise_x, no_noise_y = mon.x[:], mon.y[:]

        for method_name, method in [('euler', euler), ('milstein', milstein)]:
            # Note that for milstein, the check for diagonal noise will fail, but
            # it should still work since the two noise variables really do only
            # present a single variable
            with catch_logs('WARNING'):
                G = NeuronGroup(2, eqs_noise, method=method)
                G.x = [5,  17]
                G.y = [25, 5 ] * Hz
                mon = StateMonitor(G, ['x', 'y'], record=True)
                net = Network(G, mon)
                # We run it deterministically, but still we'd detect major errors (e.g.
                # non-stochastic terms that are added twice, see #330
                net.run(10*ms, namespace={'noise_factor': 0})
            assert_allclose(mon.x[:], no_noise_x,
                            err_msg='Method %s gave incorrect results' % method_name)
            assert_allclose(mon.y[:], no_noise_y,
                            err_msg='Method %s gave incorrect results' % method_name)
Ejemplo n.º 25
0
def test_explicit_namespace():
    ''' Test resolution with an explicitly provided namespace '''
    
    explicit_namespace = {'variable': 'explicit_var',
                          'randn': 'explicit_randn'}
    # Explicitly provided 
    namespace = create_namespace( explicit_namespace)
    
    
    with catch_logs() as l:
        assert namespace['variable'] == 'explicit_var'
        assert len(l) == 0
    
    with catch_logs() as l:
        # The explicitly provided namespace should not overwrite functions
        assert isinstance(namespace['randn'], RandnFunction)        
        _assert_one_warning(l)
Ejemplo n.º 26
0
def test_warning():
    from brian2.core.functions import DEFAULT_FUNCTIONS
    from brian2.units.stdunits import cm as brian_cm
    # Name in external namespace clashes with unit/function name
    exp = 23
    cm = 42
    group = SimpleGroup(namespace=None, variables={})
    with catch_logs() as l:
        resolved = group.resolve_all(['exp'])['exp']
        assert resolved == DEFAULT_FUNCTIONS['exp']
        assert len(l) == 1, 'got warnings: %s' % str(l)
        assert l[0][1].endswith('.resolution_conflict')
    with catch_logs() as l:
        resolved = group.resolve_all(['cm'])['cm']
        assert resolved.get_value_with_unit() == brian_cm
        assert len(l) == 1, 'got warnings: %s' % str(l)
        assert l[0][1].endswith('.resolution_conflict')
Ejemplo n.º 27
0
def test_warning():
    from brian2.core.functions import DEFAULT_FUNCTIONS
    from brian2.units.stdunits import cm as brian_cm
    # Name in external namespace clashes with unit/function name
    exp = 23
    cm = 42
    group = SimpleGroup(namespace=None, variables={})
    with catch_logs() as l:
        resolved = group.resolve_all(['exp'])['exp']
        assert resolved == DEFAULT_FUNCTIONS['exp']
        assert len(l) == 1, 'got warnings: %s' % str(l)
        assert l[0][1].endswith('.resolution_conflict')
    with catch_logs() as l:
        resolved = group.resolve_all(['cm'])['cm']
        assert resolved.get_value_with_unit() == brian_cm
        assert len(l) == 1, 'got warnings: %s' % str(l)
        assert l[0][1].endswith('.resolution_conflict')
Ejemplo n.º 28
0
def test_warning():
    from brian2.core.functions import DEFAULT_FUNCTIONS
    from brian2.units.stdunits import cm as brian_cm
    # Name in external namespace clashes with unit/function name
    exp = 23
    cm = 42
    namespace = create_namespace()
    local_ns = get_local_namespace(level=0)
    with catch_logs() as l:
        resolved = namespace.resolve('exp', ('implicit namespace', local_ns))
        assert resolved == DEFAULT_FUNCTIONS['exp']
        assert len(l) == 1
        assert l[0][1].endswith('.resolution_conflict')
    with catch_logs() as l:
        resolved = namespace.resolve('cm', ('implicit namespace', local_ns))
        assert resolved == brian_cm
        assert len(l) == 1
        assert l[0][1].endswith('.resolution_conflict')
Ejemplo n.º 29
0
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')
Ejemplo n.º 30
0
def test_delete_directory():
    set_device('cpp_standalone', build_on_run=True, directory=None)
    group = NeuronGroup(10, 'dv/dt = -v / (10*ms) : volt', method='exact')
    group.v = np.arange(10) * mV  # uses the static array mechanism
    run(defaultclock.dt)
    # Add a new file
    dummy_file = os.path.join(device.project_dir, 'results', 'dummy.txt')
    open(dummy_file, 'w').flush()
    assert os.path.isfile(dummy_file)
    with catch_logs() as logs:
        device.delete(directory=True)
    assert len(logs) == 1
    assert os.path.isfile(dummy_file)
    with catch_logs() as logs:
        device.delete(directory=True, force=True)
    assert len(logs) == 0
    # everything should be deleted
    assert not os.path.exists(device.project_dir)
Ejemplo n.º 31
0
def test_explicit_namespace():
    ''' Test resolution with an explicitly provided namespace '''

    explicit_namespace = {
        'variable': 'explicit_var',
        'randn': 'explicit_randn'
    }
    # Explicitly provided
    namespace = create_namespace(explicit_namespace)

    with catch_logs() as l:
        assert namespace['variable'] == 'explicit_var'
        assert len(l) == 0

    with catch_logs() as l:
        # The explicitly provided namespace should not overwrite functions
        assert isinstance(namespace['randn'], RandnFunction)
        _assert_one_warning(l)
Ejemplo n.º 32
0
def test_no_synapses():
    # Synaptic pathway but no synapses
    G1 = NeuronGroup(1, '', threshold='True')
    G2 = NeuronGroup(1, 'v:1')
    S = Synapses(G1, G2, pre='v+=1', name='synapses_'+str(uuid.uuid4()).replace('-', '_'))
    net = Network(G1, G2, S)
    with catch_logs() as l:
        net.run(defaultclock.dt)
        assert len(l) == 1, 'expected 1 warning, got %d' % len(l)
        assert l[0][1].endswith('.no_synapses')
Ejemplo n.º 33
0
def test_explicit_namespace():
    ''' Test resolution with an explicitly provided namespace '''
    
    explicit_namespace = {'variable': 'explicit_var'}
    # Explicitly provided 
    namespace = create_namespace( explicit_namespace)

    with catch_logs() as l:
        assert namespace['variable'] == 'explicit_var'
        assert len(l) == 0
Ejemplo n.º 34
0
def test_multiple_noise_variables_deterministic_noise(
        fake_randn_randn_fixture):
    all_eqs = [
        '''dx/dt = y : 1
                          dy/dt = -y / (10*ms) + dt**-.5*0.5*ms**-1.5 + dt**-.5*0.5*ms**-1.5: Hz
                     ''', '''dx/dt = y + dt**-.5*0.5*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + dt**-.5*0.5 * ms**-1.5 : Hz
                '''
    ]
    all_eqs_noise = [
        '''dx/dt = y : 1
                          dy/dt = -y / (10*ms) + xi_1 * ms**-1.5 + xi_2 * ms**-1.5: Hz
                     ''', '''dx/dt = y + xi_1*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + xi_2 * ms**-1.5 : Hz
                     '''
    ]

    monitors_no_noise = []
    monitors = []
    for eqs, eqs_noise in zip(all_eqs, all_eqs_noise):
        G = NeuronGroup(2, eqs, method='euler')
        G.x = [5, 17]
        G.y = [25, 5] * Hz
        mon = StateMonitor(G, ['x', 'y'], record=True)
        net = Network(G, mon)
        net.run(10 * ms)
        monitors_no_noise.append(mon)
        monitors.append(dict())

        for method_name, method in [('euler', euler), ('heun', heun)]:
            with catch_logs('WARNING'):
                G = NeuronGroup(2, eqs_noise, method=method)
                G.x = [5, 17]
                G.y = [25, 5] * Hz
                mon = StateMonitor(G, ['x', 'y'], record=True)
                net = Network(G, mon)
                net.run(10 * ms)
                monitors[-1][method_name] = mon

    device.build(direct_call=False, **device.build_options)

    for i in range(len(all_eqs)):
        mon = monitors_no_noise[i]
        no_noise_x, no_noise_y = mon.x[:], mon.y[:]
        for method_name in ['euler', 'heun']:
            mon = monitors[i][method_name]
            assert_allclose(
                mon.x[:],
                no_noise_x,
                err_msg=f'Method {method_name} gave incorrect results')
            assert_allclose(
                mon.y[:],
                no_noise_y,
                err_msg=f'Method {method_name} gave incorrect results')
Ejemplo n.º 35
0
def test_multiple_noise_variables_deterministic_noise():
    # The "random" values are always 0.5
    @implementation('cpp',
                    '''
                    double randn(int vectorisation_idx)
                    {
                        return 0.5;
                    }
                    ''')
    @implementation('cython',
                    '''
                    cdef double randn(int vectorisation_idx):
                        return 0.5
                    ''')
    @check_units(N=Unit(1), result=Unit(1))
    def fake_randn(N):
        return 0.5*ones(N)

    old_randn = DEFAULT_FUNCTIONS['randn']
    DEFAULT_FUNCTIONS['randn'] = fake_randn

    all_eqs = ['''dx/dt = y : 1
                          dy/dt = -y / (10*ms) + dt**-.5*0.5*ms**-1.5 + dt**-.5*0.5*ms**-1.5: Hz
                     ''',
                     '''dx/dt = y + dt**-.5*0.5*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + dt**-.5*0.5 * ms**-1.5 : Hz
                ''']
    all_eqs_noise = ['''dx/dt = y : 1
                          dy/dt = -y / (10*ms) + xi_1 * ms**-1.5 + xi_2 * ms**-1.5: Hz
                     ''',
                     '''dx/dt = y + xi_1*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + xi_2 * ms**-1.5 : Hz
                     ''']
    for eqs, eqs_noise in zip(all_eqs, all_eqs_noise):
        G = NeuronGroup(2, eqs, method='euler')
        G.x = [5,  17]
        G.y = [25, 5 ] * Hz
        mon = StateMonitor(G, ['x', 'y'], record=True)
        net = Network(G, mon)
        net.run(10*ms)
        no_noise_x, no_noise_y = mon.x[:], mon.y[:]

        for method_name, method in [('euler', euler), ('heun', heun)]:
            with catch_logs('WARNING'):
                G = NeuronGroup(2, eqs_noise, method=method)
                G.x = [5,  17]
                G.y = [25, 5 ] * Hz
                mon = StateMonitor(G, ['x', 'y'], record=True)
                net = Network(G, mon)
                net.run(10*ms)
            assert_allclose(mon.x[:], no_noise_x,
                            err_msg='Method %s gave incorrect results' % method_name)
            assert_allclose(mon.y[:], no_noise_y,
                            err_msg='Method %s gave incorrect results' % method_name)
Ejemplo n.º 36
0
def test_math_functions_short():
    '''
    Test that math functions give the same result, regardless of whether used
    directly or in generated Python or C++ code. Test only a few functions
    '''
    default_dt = defaultclock.dt
    test_array = np.array([-1, -0.5, 0, 0.5, 1])

    with catch_logs() as _:  # Let's suppress warnings about illegal values
        # Functions with a single argument
        for func in [exp, np.sqrt]:

            # Calculate the result directly
            numpy_result = func(test_array)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            if func.__name__ == 'absolute':
                # we want to use the name abs instead of absolute
                func_name = 'abs'
            else:
                func_name = func.__name__
            G = NeuronGroup(len(test_array),
                            '''func = {func}(variable) : 1
                               variable : 1'''.format(func=func_name))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(numpy_result, mon.func_.flatten(),
                            err_msg='Function %s did not return the correct values' % func.__name__)

        # Functions/operators
        scalar = 3
        # TODO: We are not testing the modulo operator here since it does
        #       not work for double values in C
        for func, operator in [(np.power, '**')]:

            # Calculate the result directly
            numpy_result = func(test_array, scalar)

            # Calculate the result in a somewhat complicated way by using a
            # subexpression in a NeuronGroup
            G = NeuronGroup(len(test_array),
                            '''func = variable {op} scalar : 1
                               variable : 1'''.format(op=operator))
            G.variable = test_array
            mon = StateMonitor(G, 'func', record=True)
            net = Network(G, mon)
            net.run(default_dt)

            assert_allclose(numpy_result, mon.func_.flatten(),
                            err_msg='Function %s did not return the correct values' % func.__name__)
Ejemplo n.º 37
0
def test_schedule_warning():
    previous_device = get_device()
    from uuid import uuid4
    # TestDevice1 supports arbitrary schedules, TestDevice2 does not
    class TestDevice1(Device):
        pass
    class TestDevice2(Device):
        def __init__(self):
            super(TestDevice2, self).__init__()
            self.network_schedule = ['start', 'groups', 'synapses',
                                     'thresholds', 'resets', 'end']

    # Unique names are important for getting the warnings again for multiple
    # runs of the test suite
    name1 = 'testdevice_' + str(uuid4())
    name2 = 'testdevice_' + str(uuid4())
    all_devices[name1] = TestDevice1()
    all_devices[name2] = TestDevice2()

    set_device(name1)
    net = Network()
    # Any schedule should work
    net.schedule = list(reversed(net.schedule))
    with catch_logs() as l:
        net.run(0*ms)
        assert len(l) == 0, 'did not expect a warning'

    set_device(name2)
    # Using the correct schedule should work
    net.schedule = ['start', 'groups', 'synapses', 'thresholds', 'resets', 'end']
    with catch_logs() as l:
        net.run(0*ms)
        assert len(l) == 0, 'did not expect a warning'

    # Using another (e.g. the default) schedule should raise a warning
    net.schedule = None
    with catch_logs() as l:
        net.run(0*ms)
        assert len(l) == 1 and l[0][1].endswith('schedule_conflict')
    set_device(previous_device)
Ejemplo n.º 38
0
def test_state_variables_group_as_index_problematic():
    G = NeuronGroup(10, 'v : 1')
    SG = G[4:9]
    G.v = 1
    tests = [('i', 1), ('N', 1), ('N + i', 2), ('v', 0)]
    for value, n_warnings in tests:
        with catch_logs() as l:
            G.v.__setitem__(SG, value)
            assert len(l) == n_warnings, 'expected %d, got %d warnings' % (
                n_warnings, len(l))
            assert all([
                entry[1].endswith('ambiguous_string_expression') for entry in l
            ])
Ejemplo n.º 39
0
def test_no_synapses():
    # Synaptic pathway but no synapses
    G1 = NeuronGroup(1, '', threshold='True')
    G2 = NeuronGroup(1, 'v:1')
    S = Synapses(G1,
                 G2,
                 pre='v+=1',
                 name='synapses_' + str(uuid.uuid4()).replace('-', '_'))
    net = Network(G1, G2, S)
    with catch_logs() as l:
        net.run(defaultclock.dt)
        assert len(l) == 1, 'expected 1 warning, got %d' % len(l)
        assert l[0][1].endswith('.no_synapses')
Ejemplo n.º 40
0
def test_poissongroup_namespace():
    rate_const = 0*Hz
    P = PoissonGroup(1, rates='rate_const', namespace={'rate_const':
                                                       1/defaultclock.dt},
                     name='poissongroup_%s' % (uuid.uuid4().hex))
    P2 = PoissonGroup(1, rates='rate_const')
    mon = SpikeMonitor(P)
    mon2 = SpikeMonitor(P2)
    with catch_logs() as l:
        run(2*defaultclock.dt)
        assert len(l) == 1
        assert l[0][1].endswith('resolution_conflict')
    assert mon.num_spikes == 2
    assert mon2.num_spikes == 0
Ejemplo n.º 41
0
def test_multiple_noise_variables_extended():
    # Some actual simulations with multiple noise variables
    eqs = '''dx/dt = y : 1
             dy/dt = - 1*ms**-1*y - 40*ms**-2*x : Hz
            '''
    all_eqs_noise = [
        '''dx/dt = y : 1
                        dy/dt = noise_factor*ms**-1.5*xi_1 + noise_factor*ms**-1.5*xi_2
                           - 1*ms**-1*y - 40*ms**-2*x : Hz
                     ''', '''dx/dt = y + noise_factor*ms**-0.5*xi_1: 1
                        dy/dt = noise_factor*ms**-1.5*xi_2
                            - 1*ms**-1*y - 40*ms**-2*x : Hz
                     '''
    ]
    G = NeuronGroup(2, eqs, method='euler')
    G.x = [0.5, 1]
    G.y = [0, 0.5] * Hz
    mon1 = StateMonitor(G, ['x', 'y'], record=True)
    net = Network(G, mon1)
    net.run(10 * ms)

    monitors = []
    for eqs_noise in all_eqs_noise:
        monitors.append(dict())
        for method_name, method in [('euler', euler), ('heun', heun)]:
            with catch_logs('WARNING'):
                G = NeuronGroup(2, eqs_noise, method=method)
                G.x = [0.5, 1]
                G.y = [0, 0.5] * Hz
                mon = StateMonitor(G, ['x', 'y'], record=True)
                net = Network(G, mon)
                # We run it deterministically, but still we'd detect major errors (e.g.
                # non-stochastic terms that are added twice, see #330
                net.run(10 * ms, namespace={'noise_factor': 0})
                monitors[-1][method_name] = mon

    device.build(direct_call=False, **device.build_options)

    no_noise_x, no_noise_y = mon1.x[:], mon1.y[:]
    for i in range(len(all_eqs_noise)):
        for method_name in ['euler', 'heun']:
            mon = monitors[i][method_name]
            assert_allclose(
                mon.x[:],
                no_noise_x,
                err_msg=f'Method {method_name} gave incorrect results')
            assert_allclose(
                mon.y[:],
                no_noise_y,
                err_msg=f'Method {method_name} gave incorrect results')
Ejemplo n.º 42
0
def test_poissongroup_namespace():
    rate_const = 0*Hz
    P = PoissonGroup(1, rates='rate_const', namespace={'rate_const':
                                                       1/defaultclock.dt},
                     name='poissongroup_%s' % (uuid.uuid4().hex))
    P2 = PoissonGroup(1, rates='rate_const')
    mon = SpikeMonitor(P)
    mon2 = SpikeMonitor(P2)
    with catch_logs() as l:
        run(2*defaultclock.dt)
        assert len(l) == 1
        assert l[0][1].endswith('resolution_conflict')
    assert mon.num_spikes == 2
    assert mon2.num_spikes == 0
Ejemplo n.º 43
0
def test_state_variables_group_as_index_problematic():
    G = NeuronGroup(10, 'v : 1')
    SG = G[4:9]
    G.v = 1
    tests = [('i', 1),
             ('N', 1),
             ('N + i', 2),
             ('v', 0)]
    for value, n_warnings in tests:
        with catch_logs() as l:
            G.v.__setitem__(SG, value)
            assert len(l) == n_warnings, 'expected %d, got %d warnings' % (n_warnings, len(l))
            assert all([entry[1].endswith('ambiguous_string_expression')
                        for entry in l])
Ejemplo n.º 44
0
def test_spikegenerator_extreme_period():
    '''
    Basic test for `SpikeGeneratorGroup`.
    '''
    indices = np.array([0, 1, 2])
    times = np.array([0, 1, 2]) * ms
    SG = SpikeGeneratorGroup(5, indices, times, period=1e6 * second)
    s_mon = SpikeMonitor(SG)
    with catch_logs() as l:
        run(10 * ms)

    assert_equal(s_mon.i, np.array([0, 1, 2]))
    assert_allclose(s_mon.t, [0, 1, 2] * ms)
    assert len(l) == 1 and l[0][1].endswith('spikegenerator_long_period')
Ejemplo n.º 45
0
def test_spikegenerator_extreme_period():
    '''
    Basic test for `SpikeGeneratorGroup`.
    '''
    indices = np.array([0, 1, 2])
    times   = np.array([0, 1, 2]) * ms
    SG = SpikeGeneratorGroup(5, indices, times, period=1e6*second)
    s_mon = SpikeMonitor(SG)
    with catch_logs() as l:
        run(10*ms)

    assert_equal(s_mon.i, np.array([0, 1, 2]))
    assert_allclose(s_mon.t, [0, 1, 2]*ms)
    assert len(l) == 1 and l[0][1].endswith('spikegenerator_long_period')
Ejemplo n.º 46
0
def test_spikegenerator_multiple_runs():
    indices = np.zeros(5)
    times = np.arange(5) * ms
    spike_gen = SpikeGeneratorGroup(1, indices, times)  # all good
    spike_mon = SpikeMonitor(spike_gen)
    run(5 * ms)
    # Setting the same spike times again should not do anything, since they are
    # before the start of the current simulation
    spike_gen.set_spikes(indices, times)
    # however, a warning should be raised
    with catch_logs() as l:
        run(5 * ms)
        device.build(direct_call=False, **device.build_options)
    assert len(l) == 1 and l[0][1].endswith('ignored_spikes')
    assert spike_mon.num_spikes == 5
Ejemplo n.º 47
0
def test_spikegenerator_multiple_runs():
    indices = np.zeros(5)
    times = np.arange(5)*ms
    spike_gen = SpikeGeneratorGroup(1, indices, times)  # all good
    spike_mon = SpikeMonitor(spike_gen)
    run(5*ms)
    # Setting the same spike times again should not do anything, since they are
    # before the start of the current simulation
    spike_gen.set_spikes(indices, times)
    # however, a warning should be raised
    with catch_logs() as l:
        run(5*ms)
        device.build(direct_call=False, **device.build_options)
    assert len(l) == 1 and l[0][1].endswith('ignored_spikes')
    assert spike_mon.num_spikes == 5
Ejemplo n.º 48
0
def test_profile_warning():
    # Test that profiling info is not 0
    set_device('cuda_standalone', directory=None)

    prefs.devices.cuda_standalone.profile = True

    G = NeuronGroup(1, 'v:1', threshold='True')

    BrianLogger._log_messages.clear()
    with catch_logs() as logs:
        run(defaultclock.dt, profile=True)

    assert len(logs) == 1, len(logs)
    assert logs[0][0] == 'WARNING'
    assert logs[0][1] == 'brian2.devices.cuda_standalone'
Ejemplo n.º 49
0
def test_magic_weak_reference():
    '''
    Test that holding a weak reference to an object does not make it get
    simulated.'''

    G1 = NeuronGroup(1, 'v:1')

    # this object should not be included
    G2 = weakref.ref(NeuronGroup(1, 'v:1'))

    with catch_logs(log_level=logging.DEBUG) as l:
        run(1*ms)
        # Check the debug messages for the number of included objects
        magic_objects = [msg[2] for msg in l
                         if msg[1] == 'brian2.core.magic.magic_objects'][0]
        assert '2 objects' in magic_objects, 'Unexpected log message: %s' % magic_objects
Ejemplo n.º 50
0
def test_magic_unused_object():
    '''Test that creating unused objects does not affect the magic system.'''
    def create_group():
        # Produce two objects but return only one
        G1 = NeuronGroup(1, 'v:1')  # no Thresholder or Resetter
        G2 = NeuronGroup(1, 'v:1') # This object should be garbage collected
        return G1

    G = create_group()
    with catch_logs(log_level=logging.INFO) as l:
        run(1*ms)

        # Check the debug messages for the number of included objects
        magic_objects = [msg[2] for msg in l
                         if msg[1] == 'brian2.core.magic.magic_objects'][0]
        assert '2 objects' in magic_objects, 'Unexpected log message: %s' % magic_objects
Ejemplo n.º 51
0
def test_transmission_scalar_delay_different_clocks():

    inp = SpikeGeneratorGroup(2, [0, 1], [0, 1]*ms, dt=0.5*ms,
                              # give the group a unique name to always
                              # get a 'fresh' warning
                              name='sg_%d' % uuid.uuid4())
    target = NeuronGroup(2, 'v:1', dt=0.1*ms)
    S = Synapses(inp, target, pre='v+=1', delay=0.5*ms, connect='i==j')
    mon = StateMonitor(target, 'v', record=True)
    net = Network(inp, target, S, mon)

    # We should get a warning when using inconsistent dts
    with catch_logs() as l:
        net.run(2*ms)
        assert len(l) == 1, 'expected a warning, got %d' % len(l)
        assert l[0][1].endswith('synapses_dt_mismatch')

    assert_equal(mon[0].v[mon.t<0.5*ms], 0)
    assert_equal(mon[0].v[mon.t>=0.5*ms], 1)
    assert_equal(mon[1].v[mon.t<1.5*ms], 0)
    assert_equal(mon[1].v[mon.t>=1.5*ms], 1)
Ejemplo n.º 52
0
def test_multiple_noise_variables_deterministic_noise():

    DEFAULT_FUNCTIONS["randn"] = fake_randn

    all_eqs = [
        """dx/dt = y : 1
                          dy/dt = -y / (10*ms) + dt**-.5*0.5*ms**-1.5 + dt**-.5*0.5*ms**-1.5: Hz
                     """,
        """dx/dt = y + dt**-.5*0.5*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + dt**-.5*0.5 * ms**-1.5 : Hz
                """,
    ]
    all_eqs_noise = [
        """dx/dt = y : 1
                          dy/dt = -y / (10*ms) + xi_1 * ms**-1.5 + xi_2 * ms**-1.5: Hz
                     """,
        """dx/dt = y + xi_1*ms**-0.5: 1
                        dy/dt = -y / (10*ms) + xi_2 * ms**-1.5 : Hz
                     """,
    ]
    for eqs, eqs_noise in zip(all_eqs, all_eqs_noise):
        G = NeuronGroup(2, eqs, method="euler")
        G.x = [5, 17]
        G.y = [25, 5] * Hz
        mon = StateMonitor(G, ["x", "y"], record=True)
        net = Network(G, mon)
        net.run(10 * ms)
        no_noise_x, no_noise_y = mon.x[:], mon.y[:]

        for method_name, method in [("euler", euler), ("heun", heun)]:
            with catch_logs("WARNING"):
                G = NeuronGroup(2, eqs_noise, method=method)
                G.x = [5, 17]
                G.y = [25, 5] * Hz
                mon = StateMonitor(G, ["x", "y"], record=True)
                net = Network(G, mon)
                net.run(10 * ms)
            assert_allclose(mon.x[:], no_noise_x, err_msg="Method %s gave incorrect results" % method_name)
            assert_allclose(mon.y[:], no_noise_y, err_msg="Method %s gave incorrect results" % method_name)
Ejemplo n.º 53
0
def test_multiple_noise_variables_extended():
    # Some actual simulations with multiple noise variables
    eqs = '''dx/dt = y : 1
             dy/dt = - 1*ms**-1*y - 40*ms**-2*x : Hz
            '''
    all_eqs_noise = ['''dx/dt = y : 1
                        dy/dt = noise_factor*ms**-1.5*xi_1 + noise_factor*ms**-1.5*xi_2
                           - 1*ms**-1*y - 40*ms**-2*x : Hz
                     ''',
                     '''dx/dt = y + noise_factor*ms**-0.5*xi_1: 1
                        dy/dt = noise_factor*ms**-1.5*xi_2
                            - 1*ms**-1*y - 40*ms**-2*x : Hz
                     ''']
    G = NeuronGroup(2, eqs, method='euler')
    G.x = [0.5, 1]
    G.y = [0, 0.5] * Hz
    mon = StateMonitor(G, ['x', 'y'], record=True)
    net = Network(G, mon)
    net.run(10*ms)
    no_noise_x, no_noise_y = mon.x[:], mon.y[:]

    for eqs_noise in all_eqs_noise:
        for method_name, method in [('euler', euler), ('heun', heun), ('milstein', milstein)]:
            # Note that for milstein, the check for diagonal noise will fail, but
            # it should still work since the two noise variables really do only
            # present a single variable
            with catch_logs('WARNING'):
                G = NeuronGroup(2, eqs_noise, method=method)
                G.x = [0.5, 1]
                G.y = [0, 0.5] * Hz
                mon = StateMonitor(G, ['x', 'y'], record=True)
                net = Network(G, mon)
                # We run it deterministically, but still we'd detect major errors (e.g.
                # non-stochastic terms that are added twice, see #330
                net.run(10*ms, namespace={'noise_factor': 0})
            assert_allclose(mon.x[:], no_noise_x,
                            err_msg='Method %s gave incorrect results' % method_name)
            assert_allclose(mon.y[:], no_noise_y,
                            err_msg='Method %s gave incorrect results' % method_name)