示例#1
0
def test_GSL_error_incorrect_error_format():
    eqs = """
    dv/dt = (v0 - v)/(10*ms) : volt
    v0 : volt
    """
    options = {'absolute_error_per_variable': object()}
    neuron = NeuronGroup(1,
                         eqs,
                         threshold='v > 10*mV',
                         reset='v = 0*mV',
                         method='gsl',
                         method_options=options)
    net = Network(neuron)
    options2 = {'absolute_error': 'not a float'}
    neuron2 = NeuronGroup(1,
                          eqs,
                          threshold='v > 10*mV',
                          reset='v = 0*mV',
                          method='gsl',
                          method_options=options2)
    net2 = Network(neuron2)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms, namespace={})
    assert exc_isinstance(exc, TypeError, raise_not_implemented=True)
    with pytest.raises(BrianObjectException) as exc:
        net2.run(0 * ms, namespace={})
    assert exc_isinstance(exc, TypeError, raise_not_implemented=True)
示例#2
0
def test_multiple_stateless_function_calls():
    # Check that expressions such as rand() + rand() (which might be incorrectly
    # simplified to 2*rand()) raise an error
    G = NeuronGroup(1, 'dv/dt = (rand() - rand())/second : 1')
    net = Network(G)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0*ms)
    assert exc_isinstance(exc, NotImplementedError)
    G2 = NeuronGroup(1, 'v:1', threshold='v>1', reset='v=rand() - rand()')
    net2 = Network(G2)
    with pytest.raises(BrianObjectException) as exc:
        net2.run(0*ms)
    assert exc_isinstance(exc, NotImplementedError)
    G3 = NeuronGroup(1, 'v:1')
    G3.run_regularly('v = rand() - rand()')
    net3 = Network(G3)
    with pytest.raises(BrianObjectException) as exc:
        net3.run(0*ms)
    assert exc_isinstance(exc, NotImplementedError)
    G4 = NeuronGroup(1, 'x : 1')
    # Verify that synaptic equations are checked as well, see #1146
    S = Synapses(G4, G4, 'dy/dt = (rand() - rand())/second : 1 (clock-driven)')
    S.connect()
    net = Network(G4, S)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0*ms)
    assert exc_isinstance(exc, NotImplementedError)
示例#3
0
def test_multiplicative_noise():
    # Noise is not multiplicative (constant over time step)
    ta = TimedArray([0, 1], dt=defaultclock.dt * 10)
    Eq = Equations('dv/dt = ta(t)*xi*(5*ms)**-0.5 :1')
    group = NeuronGroup(1, Eq, method='euler')
    net = Network(group)
    net.run(0 * ms)  # no error

    # Noise is multiplicative (multiplied with time-varying variable)
    Eq1 = Equations('dv/dt = v*xi*(5*ms)**-0.5 :1')
    group1 = NeuronGroup(1, Eq1, method='euler')
    net1 = Network(group1)
    with pytest.raises(BrianObjectException) as exc:
        net1.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # Noise is multiplicative (multiplied with time)
    Eq2 = Equations('dv/dt = (t/ms)*xi*(5*ms)**-0.5 :1')
    group2 = NeuronGroup(1, Eq2, method='euler')
    net2 = Network(group2)
    with pytest.raises(BrianObjectException) as exc:
        net2.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # Noise is multiplicative (multiplied with time-varying variable)
    Eq3 = Equations("""dv/dt = w*xi*(5*ms)**-0.5 :1
                       dw/dt = -w/(10*ms) : 1""")
    group3 = NeuronGroup(1, Eq3, method='euler')
    net3 = Network(group3)
    with pytest.raises(BrianObjectException) as exc:
        net3.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # One of the equations has multiplicative noise
    Eq4 = Equations("""dv/dt = xi_1*(5*ms)**-0.5 : 1
                       dw/dt = (t/ms)*xi_2*(5*ms)**-0.5 :1""")
    group4 = NeuronGroup(1, Eq4, method='euler')
    net4 = Network(group4)
    with pytest.raises(BrianObjectException) as exc:
        net4.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # One of the equations has multiplicative noise
    Eq5 = Equations("""dv/dt = xi_1*(5*ms)**-0.5 : 1
                       dw/dt = v*xi_2*(5*ms)**-0.5 :1""")
    group5 = NeuronGroup(1, Eq5, method='euler')
    net5 = Network(group4)
    with pytest.raises(BrianObjectException) as exc:
        net5.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)
示例#4
0
def test_rate_unit_check():
    with pytest.raises(DimensionMismatchError):
        PoissonGroup(1, np.array([1, 2]))
    with pytest.raises(DimensionMismatchError):
        PoissonGroup(1, np.array([1, 2]) * ms)
    P = PoissonGroup(1, 'i*mV')
    net = Network(P)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, DimensionMismatchError)

    P = PoissonGroup(1, 'i')
    net = Network(P)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, DimensionMismatchError)
示例#5
0
def test_spikegenerator_incorrect_period():
    """
    Test that you cannot provide incorrect period arguments or combine
    inconsistent period and dt arguments.
    """
    # Period is negative
    with pytest.raises(ValueError):
        SpikeGeneratorGroup(1, [], [] * second, period=-1 * ms)

    # Period is smaller than the highest spike time
    with pytest.raises(ValueError):
        SpikeGeneratorGroup(1, [0], [2] * ms, period=1 * ms)
    # Period is not an integer multiple of dt
    SG = SpikeGeneratorGroup(1, [], [] * second, period=1.25 * ms, dt=0.1 * ms)
    net = Network(SG)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, NotImplementedError)

    SG = SpikeGeneratorGroup(1, [], [] * second,
                             period=0.101 * ms,
                             dt=0.1 * ms)
    net = Network(SG)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, NotImplementedError)

    SG = SpikeGeneratorGroup(1, [], [] * second,
                             period=3.333 * ms,
                             dt=0.1 * ms)
    net = Network(SG)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, NotImplementedError)

    # This should not raise an error (see #1041)
    SG = SpikeGeneratorGroup(1, [], [] * ms, period=150 * ms, dt=0.1 * ms)
    net = Network(SG)
    net.run(0 * ms)

    # Period is smaller than dt
    SG = SpikeGeneratorGroup(1, [], [] * second, period=1 * ms, dt=2 * ms)
    net = Network(SG)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, ValueError)
示例#6
0
def test_refractoriness_types():
    # make sure that using a wrong type of refractoriness does not work
    group = NeuronGroup(1, '', refractory='3*Hz')
    with pytest.raises(BrianObjectException) as exc:
        Network(group).run(0 * ms)
    assert exc_isinstance(exc, TypeError)
    group = NeuronGroup(1, 'ref: Hz', refractory='ref')
    with pytest.raises(BrianObjectException) as exc:
        Network(group).run(0 * ms)
    assert exc_isinstance(exc, TypeError)
    group = NeuronGroup(1, '', refractory='3')
    with pytest.raises(BrianObjectException) as exc:
        Network(group).run(0 * ms)
    assert exc_isinstance(exc, TypeError)
    group = NeuronGroup(1, 'ref: 1', refractory='ref')
    with pytest.raises(BrianObjectException) as exc:
        Network(group).run(0 * ms)
    assert exc_isinstance(exc, TypeError)
示例#7
0
def test_GSL_stochastic():
    tau = 20 * ms
    sigma = .015
    eqs = """
    dx/dt = (1.1 - x) / tau + sigma * (2 / tau)**.5 * xi : 1
    """
    neuron = NeuronGroup(1, eqs, method='gsl')
    net = Network(neuron)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms, namespace={'tau': tau, 'sigma': sigma})
    assert exc_isinstance(exc,
                          UnsupportedEquationsException,
                          raise_not_implemented=True)
示例#8
0
def test_spikegenerator_multiple_spikes_per_bin():
    # Multiple spikes per bin are of course fine if they don't belong to the
    # same neuron
    SG = SpikeGeneratorGroup(2, [0, 1], [0, 0.05] * ms, dt=0.1 * ms)
    net = Network(SG)
    net.run(0 * ms)

    # This should raise an error
    SG = SpikeGeneratorGroup(2, [0, 0], [0, 0.05] * ms, dt=0.1 * ms)
    net = Network(SG)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    print(exc.value.__cause__)
    assert exc_isinstance(exc, ValueError)

    # More complicated scenario where dt changes between runs
    defaultclock.dt = 0.1 * ms
    SG = SpikeGeneratorGroup(2, [0, 0], [0.05, 0.15] * ms)
    net = Network(SG)
    net.run(0 * ms)  # all is fine
    defaultclock.dt = 0.2 * ms  # Now the two spikes fall into the same bin
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, ValueError)
示例#9
0
def test_GSL_error_nonODE_variable():
    eqs = """
    dv/dt = (v0 - v)/(10*ms) : volt
    v0 : volt
    """
    options = {'absolute_error_per_variable': {'v0': 1e-3 * mV}}
    neuron = NeuronGroup(1,
                         eqs,
                         threshold='v > 10*mV',
                         reset='v = 0*mV',
                         method='gsl',
                         method_options=options)
    net = Network(neuron)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms, namespace={})
    assert exc_isinstance(exc, KeyError, raise_not_implemented=True)
示例#10
0
def test_GSL_error_dimension_mismatch_dimensionless1():
    eqs = """
    dv/dt = (v0 - v)/(10*ms) : 1
    v0 : 1
    """
    options = {'absolute_error_per_variable': {'v': 1 * mV}}
    neuron = NeuronGroup(1,
                         eqs,
                         threshold='v > 10',
                         reset='v = 0',
                         method='gsl',
                         method_options=options)
    net = Network(neuron)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms, namespace={})
    assert exc_isinstance(exc,
                          DimensionMismatchError,
                          raise_not_implemented=True)
示例#11
0
def test_spikegenerator_period_rounding():
    # See discussion in PR #1042
    # The last spike will be considered to be in the time step *after* 1s, due
    # to the way our rounding works. Although probably not what the user
    # expects, this should therefore raise an error. In previous versions of
    # Brian, this did not raise any error but silently discarded the spike.
    with pytest.raises(ValueError):
        SpikeGeneratorGroup(1, [0, 0, 0], [0 * ms, .9 * ms, .99999 * ms],
                            period=1 * ms,
                            dt=0.1 * ms)
    # This should also raise a ValueError, since the last two spikes fall into
    # the same bin
    s = SpikeGeneratorGroup(1, [0, 0, 0], [0 * ms, .9 * ms, .96 * ms],
                            period=1 * ms,
                            dt=0.1 * ms)
    net = Network(s)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, ValueError)
示例#12
0
def test_manual_user_defined_function_cython_wrong_compiler_args2():
    if prefs.codegen.target != 'cython':
        pytest.skip('Cython-only test')

    @implementation('cython', """
    cdef double foo(double x, const double y):
        return x + y + 3
    """,   libraries='cstdio')  # existing argument, wrong value type
    @check_units(x=volt, y=volt, result=volt)
    def foo(x, y):
        return x + y + 3*volt

    G = NeuronGroup(1, """
                       func = foo(x, y) : volt
                       x : volt
                       y : volt""")
    mon = StateMonitor(G, 'func', record=True)
    net = Network(G, mon)
    with pytest.raises(BrianObjectException) as exc:
        net.run(defaultclock.dt, namespace={'foo': foo})
    assert exc_isinstance(exc, TypeError)
示例#13
0
def test_manual_user_defined_function_cpp_standalone_wrong_compiler_args2():
    set_device('cpp_standalone', directory=None)

    @implementation('cpp', """
    static inline double foo(const double x, const double y)
    {
        return x + y + _THREE;
    }""",  headers='<stdio.h>')  # existing argument, wrong value type
    @check_units(x=volt, y=volt, result=volt)
    def foo(x, y):
        return x + y + 3*volt

    G = NeuronGroup(1, """
                       func = foo(x, y) : volt
                       x : volt
                       y : volt""")
    mon = StateMonitor(G, 'func', record=True)
    net = Network(G, mon)
    with pytest.raises(BrianObjectException) as exc:
        net.run(defaultclock.dt, namespace={'foo': foo})
    assert exc_isinstance(exc, TypeError)
示例#14
0
def test_poissoninput_errors():
    # Targeting non-existing variable
    G = NeuronGroup(10, """x : volt
                           y : 1""")
    with pytest.raises(KeyError):
        PoissonInput(G, 'z', 100, 100 * Hz, weight=1.0)

    # Incorrect units
    with pytest.raises(DimensionMismatchError):
        PoissonInput(G, 'x', 100, 100 * Hz, weight=1.0)
    with pytest.raises(DimensionMismatchError):
        PoissonInput(G, 'y', 100, 100 * Hz, weight=1.0 * volt)

    # dt change
    old_dt = defaultclock.dt
    inp = PoissonInput(G, 'x', 100, 100 * Hz, weight=1 * volt)
    defaultclock.dt = 2 * old_dt
    net = Network(collect())
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, NotImplementedError)
    defaultclock.dt = old_dt
示例#15
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='exact',
                        namespace={'ta': ta_func})
        net = Network(G)
        if ok:
            # This should work
            net.run(0 * ms)
        else:
            # This should not
            with catch_logs():
                with pytest.raises(BrianObjectException) as exc:
                    net.run(0 * ms)
                    assert exc.errisinstance(UnsupportedEquationsException)

        # multiplicative
        G = NeuronGroup(1,
                        'dv/dt = -v*ta(t)/(10*ms) : 1',
                        method='exact',
                        namespace={'ta': ta_func})
        net = Network(G)
        if ok:
            # This should work
            net.run(0 * ms)
        else:
            # This should not
            with catch_logs():
                with pytest.raises(BrianObjectException) as exc:
                    net.run(0 * ms)
                    assert exc.errisinstance(UnsupportedEquationsException)

    # 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='exact',
                    namespace={'ta': ta0})
    net = Network(G)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # 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='exact')
    net = Network(G)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # Stateful functions aren't either
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + rand()*Hz : 1', method='exact')
    net = Network(G)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # Neither is "t" itself
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + t/second**2 : 1', method='exact')
    net = Network(G)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0 * ms)
    assert exc_isinstance(exc, UnsupportedEquationsException)

    # 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='exact')
    net = Network(G)
    net.run(0 * ms)
示例#16
0
def test_declare_types():
    if prefs.codegen.target != 'numpy':
        pytest.skip('numpy-only test')

    @declare_types(a='integer', b='float', result='highest')
    def f(a, b):
        return a*b
    assert f._arg_types==['integer', 'float']
    assert f._return_type == 'highest'

    @declare_types(b='float')
    def f(a, b, c):
        return a*b*c
    assert f._arg_types==['any', 'float', 'any']
    assert f._return_type == 'float'

    def bad_argtype():
        @declare_types(b='floating')
        def f(a, b, c):
            return a*b*c
    with pytest.raises(ValueError):
        bad_argtype()

    def bad_argname():
        @declare_types(d='floating')
        def f(a, b, c):
            return a*b*c
    with pytest.raises(ValueError):
        bad_argname()

    @check_units(a=volt, b=1)
    @declare_types(a='float', b='integer')
    def f(a, b):
        return a*b

    @declare_types(a='float', b='integer')
    @check_units(a=volt, b=1)
    def f(a, b):
        return a*b

    def bad_units():
        @declare_types(a='integer', b='float')
        @check_units(a=volt, b=1, result=volt)
        def f(a, b):
            return a*b
        eqs = """
        dv/dt = f(v, 1)/second : 1
        """
        G = NeuronGroup(1, eqs)
        Network(G).run(1*ms)
    with pytest.raises(BrianObjectException) as exc:
        bad_units()
    assert exc_isinstance(exc, TypeError)

    def bad_type():
        @implementation('numpy', discard_units=True)
        @declare_types(a='float', result='float')
        @check_units(a=1, result=1)
        def f(a):
            return a
        eqs = """
        a : integer
        dv/dt = f(a)*v/second : 1
        """
        G = NeuronGroup(1, eqs)
        Network(G).run(1*ms)
    with pytest.raises(BrianObjectException) as exc:
        bad_type()
    assert exc_isinstance(exc, TypeError)
示例#17
0
def test_manual_user_defined_function():
    if prefs.codegen.target != 'numpy':
        pytest.skip('numpy-only test')

    default_dt = defaultclock.dt

    # User defined function without any decorators
    def foo(x, y):
        return x + y + 3*volt
    orig_foo = foo
    # Since the function is not annotated with check units, we need to specify
    # both the units of the arguments and the return unit
    with pytest.raises(ValueError):
        Function(foo, return_unit=volt)
    with pytest.raises(ValueError):
        Function(foo, arg_units=[volt, volt])
    # If the function uses the string syntax for "same units", it needs to
    # specify the names of the arguments
    with pytest.raises(TypeError):
        Function(foo, arg_units=[volt, 'x'])
    with pytest.raises(TypeError):
        Function(foo, arg_units=[volt, 'x'],
                 arg_names=['x'])  # Needs two entries

    foo = Function(foo, arg_units=[volt, volt], return_unit=volt)

    assert foo(1*volt, 2*volt) == 6*volt

    # a can be any unit, b and c need to be the same unit
    def bar(a, b, c):
        return a*(b + c)
    bar = Function(bar, arg_units=[None, None, 'b'],
                   arg_names=['a', 'b', 'c'],
                   return_unit=lambda a, b, c: a*b)
    assert bar(2, 3*volt, 5*volt) == 16*volt
    assert bar(2*amp, 3*volt, 5*volt) == 16*watt
    assert bar(2*volt, 3*amp, 5*amp) == 16*watt

    with pytest.raises(DimensionMismatchError):
        bar(2, 3 * volt, 5 * amp)

    # Incorrect argument units
    group = NeuronGroup(1, """
                       dv/dt = foo(x, y)/ms : volt
                       x : 1
                       y : 1""")
    net = Network(group)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0*ms, namespace={'foo': foo})
    assert exc_isinstance(exc, DimensionMismatchError)

    # Incorrect output unit
    group = NeuronGroup(1, """
                       dv/dt = foo(x, y)/ms : 1
                       x : volt
                       y : volt""")
    net = Network(group)
    with pytest.raises(BrianObjectException) as exc:
        net.run(0*ms, namespace={'foo': foo})
    assert exc_isinstance(exc, DimensionMismatchError)

    G = NeuronGroup(1, """
                       func = foo(x, y) : volt
                       x : volt
                       y : volt""")
    G.x = 1*volt
    G.y = 2*volt
    mon = StateMonitor(G, 'func', record=True)
    net = Network(G, mon)
    net.run(default_dt)

    assert mon[0].func == [6] * volt

    # discard units
    foo.implementations.add_numpy_implementation(orig_foo,
                                                 discard_units=True)
    G = NeuronGroup(1, """
                       func = foo(x, y) : volt
                       x : volt
                       y : volt""")
    G.x = 1*volt
    G.y = 2*volt
    mon = StateMonitor(G, 'func', record=True)
    net = Network(G, mon)
    net.run(default_dt)

    assert mon[0].func == [6] * volt