def test_queryengine_io(self, fn):
        skip_if_no_external("h5py")
        from mvpa2.base.hdf5 import h5save, h5load

        vol_shape = (10, 10, 10, 1)
        vol_affine = np.identity(4)
        vg = volgeom.VolGeom(vol_shape, vol_affine)

        # generate some surfaces,
        # and add some noise to them
        sphere_density = 10
        outer = surf.generate_sphere(sphere_density) * 5 + 8
        inner = surf.generate_sphere(sphere_density) * 3 + 8
        radius = 5.0

        add_fa = ["center_distances", "grey_matter_position"]
        qe = disc_surface_queryengine(radius, vg, inner, outer, add_fa=add_fa)
        ds = fmri_dataset(vg.get_masked_nifti_image())

        # the following is not really a strong requirement. XXX remove?
        assert_raises(ValueError, lambda: qe[qe.ids[0]])

        # check that after training it behaves well
        qe.train(ds)
        i = qe.ids[0]
        try:
            m = qe[i]
        except ValueError, e:
            raise AssertionError(
                "Failed to query %r from %r after training on %r. " "Exception was: %r" % (i, qe, ds, e)
            )
Example #2
0
def test_permutation_analysis():
    # Examples that should work
    for example in permutation_analysis_good_examples:
        if SANITY_CHECK_PERMUTATION_ANALYSIS_EXAMPLE:
            try:
                numerically_check_permutation_code(example)
            except OrderDependenceError:
                raise AssertionError(('Test unexpectedly raised a numerical '
                                      'OrderDependenceError on these '
                                      'statements:\n') + example)
        try:
            check_permutation_code(example)
        except OrderDependenceError:
            raise AssertionError(('Test unexpectedly raised an '
                                  'OrderDependenceError on these '
                                  'statements:\n') + example)

    for example in permutation_analysis_bad_examples:
        if SANITY_CHECK_PERMUTATION_ANALYSIS_EXAMPLE:
            try:
                assert_raises(OrderDependenceError, numerically_check_permutation_code, example)
            except AssertionError:
                raise AssertionError("Order dependence not raised numerically for example: "+example)
        try:
            assert_raises(OrderDependenceError, check_permutation_code, example)
        except AssertionError:
            raise AssertionError("Order dependence not raised for example: "+example)
Example #3
0
def test_errors():
    # No explicit namespace
    group = SimpleGroup(namespace=None, variables={})
    assert_raises(KeyError, lambda: group._resolve('nonexisting_variable', {}))

    # Empty explicit namespace
    group = SimpleGroup(namespace={}, variables={})
    assert_raises(KeyError, lambda: group._resolve('nonexisting_variable', {}))
Example #4
0
def test_linked_synapses():
    '''
    Test linking to a synaptic variable (should raise an error).
    '''
    G = NeuronGroup(10, '')
    S = Synapses(G, G, 'w:1', connect=True)
    G2 = NeuronGroup(100, 'x : 1 (linked)')
    assert_raises(NotImplementedError, lambda: setattr(G2, 'x', linked_var(S, 'w')))
Example #5
0
def test_invalid_custom_event():
    group1 = NeuronGroup(2, 'v : 1',
                         events={'custom': 't>=(2-i)*ms and t<(2-i)*ms + dt'})
    group2 = NeuronGroup(2, 'v : 1', threshold='v>1')
    assert_raises(ValueError, lambda: Synapses(group1, group1, pre='v+=1',
                                               on_event='spike'))
    assert_raises(ValueError, lambda: Synapses(group2, group2, pre='v+=1',
                                               on_event='custom'))
Example #6
0
def test_errors():
    # No explicit namespace
    namespace = create_namespace()
    assert_raises(KeyError, lambda: namespace['nonexisting_variable'])

    # Empty explicit namespace
    namespace = create_namespace({})
    assert_raises(KeyError, lambda: namespace['nonexisting_variable'])
Example #7
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)
Example #8
0
def test_construction():
    BrianLogger.suppress_name('resolution_conflict')
    morpho = Soma(diameter=30*um)
    morpho.L = Cylinder(length=10*um, diameter=1*um, n=10)
    morpho.LL = Cylinder(length=5*um, diameter=2*um, n=5)
    morpho.LR = Cylinder(length=5*um, diameter=2*um, n=10)
    morpho.right = Cylinder(length=3*um, diameter=1*um, n=7)
    morpho.right.nextone = Cylinder(length=2*um, diameter=1*um, n=3)
    gL=1e-4*siemens/cm**2
    EL=-70*mV
    eqs='''
    Im=gL*(EL-v) : amp/meter**2
    I : meter (point current)
    '''

    # Check units of currents
    assert_raises(DimensionMismatchError, lambda: SpatialNeuron(morphology=morpho,
                                                                model=eqs))

    eqs='''
    Im=gL*(EL-v) : amp/meter**2
    '''
    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=1 * uF / cm ** 2, Ri=100 * ohm * cm)
    # Test initialization of values
    neuron.LL.v = EL
    assert_allclose(neuron.L.main.v, 0)
    assert_allclose(neuron.LL.v, EL)
    neuron.LL[2*um:3.1*um].v = 0*mV
    assert_allclose(neuron.LL.v, Quantity([EL, 0*mV, 0*mV, EL, EL]))
    assert_allclose(neuron.Cm, 1 * uF / cm ** 2)

    # Test morphological variables
    assert_allclose(neuron.main.x_, morpho.x)
    assert_allclose(neuron.L.main.x_, morpho.L.x)
    assert_allclose(neuron.LL.main.x_, morpho.LL.x)
    assert_allclose(neuron.right.main.x_, morpho.right.x)
    assert_allclose(neuron.L.main.distance_, morpho.L.distance)
    assert_allclose(neuron.L.main.diameter_, morpho.L.diameter)
    assert_allclose(neuron.L.main.area_, morpho.L.area)
    assert_allclose(neuron.L.main.length_, morpho.L.length)

    # Check basic consistency of the flattened representation
    assert len(np.unique(neuron.diffusion_state_updater._morph_i[:])) == len(neuron.diffusion_state_updater._morph_i)
    assert all(neuron.diffusion_state_updater._ends[:].flat >=
               neuron.diffusion_state_updater._starts[:].flat)

    # Check that length and distances make sense after compression
    assert_allclose(sum(morpho.L.length)*metre, 10*um)
    assert_allclose(morpho.L.distance*metre, (1 + np.arange(10))*um)
    assert_allclose(sum(morpho.LL.length)*metre, 5*um)
    assert_allclose(morpho.LL.distance*metre, 10*um + (1 + np.arange(5))*um)
    assert_allclose(sum(morpho.LR.length)*metre, 5*um)
    assert_allclose(morpho.LR.distance*metre, 10*um + (1 + np.arange(10))*0.5*um)
    assert_allclose(sum(morpho.right.length)*metre, 3*um)
    assert_allclose(morpho.right.distance*metre, (1 + np.arange(7))*3./7.*um)
    assert_allclose(sum(morpho.right.nextone.length)*metre, 2*um)
    assert_allclose(morpho.right.nextone.distance*metre, 3*um+(1 + np.arange(3))*2./3.*um)
Example #9
0
def test_unit_errors():
    '''
    Test that units are checked for a complete namespace.
    '''
    # Unit error in model equations
    assert_raises(DimensionMismatchError,
                  lambda: NeuronGroup(1, 'dv/dt = -v : 1'))
    assert_raises(DimensionMismatchError,
                  lambda: NeuronGroup(1, 'dv/dt = -v/(10*ms) + 2*mV: 1'))
Example #10
0
def test_allowed_integration():
    morph = Soma(diameter=30 * um)
    EL = -70 * mV
    gL = 1e-4 * siemens / cm ** 2
    ENa = 115 * mV
    gNa = 120 * msiemens / cm ** 2
    VT = -50.4 * mV
    DeltaT = 2 * mV
    ENMDA = 0. * mV

    @check_units(voltage=volt, result=volt)
    def user_fun(voltage):
        return voltage  # could be an arbitrary function and is therefore unsafe
    allowed_eqs = ['Im = gL*(EL-v) : amp/meter**2',
                   '''Im = gl * (El-v) + gNa * m**3 * h * (ENa-v) : amp/meter**2
                      dm/dt = alpham * (1-m) - betam * m : 1
                      dh/dt = alphah * (1-h) - betah * h : 1
                      alpham = (0.1/mV) * (-v+25*mV) / (exp((-v+25*mV) / (10*mV)) - 1)/ms : Hz
                      betam = 4 * exp(-v/(18*mV))/ms : Hz
                      alphah = 0.07 * exp(-v/(20*mV))/ms : Hz
                      betah = 1/(exp((-v+30*mV) / (10*mV)) + 1)/ms : Hz''',
                   '''Im = gl * (El-v) : amp/meter**2
                      I_ext = 1*nA + sin(2*pi*100*Hz*t)*nA : amp (point current)''',
                   '''Im = I_leak + I_spike : amp/meter**2
                      I_leak = gL*(EL - v) : amp/meter**2
                      I_spike = gL*DeltaT*exp((v - VT)/DeltaT): amp/meter**2 (constant over dt)
                   ''',
                   '''
                   Im = gL*(EL-v) : amp/meter**2
                   I_NMDA = gNMDA*(ENMDA-v)*Mgblock : amp (point current)
                   gNMDA : siemens
                   Mgblock = 1./(1. +  exp(-0.062*v/mV)/3.57) : 1 (constant over dt)
                   ''',
                   'Im = gL*(EL - v) + gL*DeltaT*exp((v - VT)/DeltaT) : amp/meter**2',
                   '''Im = I_leak + I_spike : amp/meter**2
                      I_leak = gL*(EL - v) : amp/meter**2
                      I_spike = gL*DeltaT*exp((v - VT)/DeltaT): amp/meter**2
                   ''',
                   '''
                   Im = gL*(EL-v) : amp/meter**2
                   I_NMDA = gNMDA*(ENMDA-v)*Mgblock : amp (point current)
                   gNMDA : siemens
                   Mgblock = 1./(1. +  exp(-0.062*v/mV)/3.57) : 1
                   ''',
                   ]
    forbidden_eqs = [
                    '''Im = gl * (El-v + user_fun(v)) : amp/meter**2''',
                    '''Im = gl * clip(El-v, -100*mV, 100*mV) : amp/meter**2''',
                    ]
    for eqs in allowed_eqs:
        # Should not raise an error
        neuron = SpatialNeuron(morph, eqs)

    for eqs in forbidden_eqs:
        # Should raise an error
        assert_raises(TypeError, SpatialNeuron, morph, eqs)
Example #11
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)
    assert_raises(KeyError, net.run, 0*ms, namespace={})
Example #12
0
def test_GSL_error_dimension_mismatch_dimensionless2():
    eqs = '''
    dv/dt = (v0 - v)/(10*ms) : volt
    v0 : volt
    '''
    options = {'absolute_error_per_variable': {'v': 1e-3}}
    neuron = NeuronGroup(1, eqs, threshold='v > 10*mV', reset='v = 0*mV',
                         method='gsl', method_options=options)
    net = Network(neuron)
    assert_raises(DimensionMismatchError, net.run, 0*ms, namespace={})
Example #13
0
def test_spikegenerator_incorrect_values():
    assert_raises(TypeError, lambda: SpikeGeneratorGroup(0, [], []*second))
    # Floating point value for N
    assert_raises(TypeError, lambda: SpikeGeneratorGroup(1.5, [], []*second))
    # Negative index
    assert_raises(ValueError, lambda: SpikeGeneratorGroup(5, [0, 3, -1], [0, 1, 2]*ms))
    # Too high index
    assert_raises(ValueError, lambda: SpikeGeneratorGroup(5, [0, 5, 1], [0, 1, 2]*ms))
    # Negative time
    assert_raises(ValueError, lambda: SpikeGeneratorGroup(5, [0, 1, 2], [0, -1, 2]*ms))
Example #14
0
def test_priority():
    updater = ExplicitStateUpdater("x_new = x + dt * f(x, t)")
    # Equations that work for the state updater
    eqs = Equations("dv/dt = -v / (10*ms) : 1")
    clock = Clock(dt=0.1 * ms)
    variables = {
        "v": ArrayVariable(
            name="name", unit=Unit(1), size=10, owner=None, device=None, dtype=np.float64, constant=False
        ),
        "t": clock.variables["t"],
        "dt": clock.variables["dt"],
    }
    updater(eqs, variables)  # should not raise an error

    # External parameter in the coefficient, linear integration should work
    param = 1
    eqs = Equations("dv/dt = -param * v / (10*ms) : 1")
    updater(eqs, variables)  # should not raise an error
    can_integrate = {linear: True, euler: True, rk2: True, rk4: True, heun: True, milstein: True}
    for integrator, able in can_integrate.iteritems():
        try:
            integrator(eqs, variables)
            if not able:
                raise AssertionError("Should not be able to integrate these " "equations")
        except UnsupportedEquationsException:
            if able:
                raise AssertionError("Should be able to integrate these " "equations")

    # Equation with additive noise
    eqs = Equations("dv/dt = -v / (10*ms) + xi/(10*ms)**.5 : 1")
    assert_raises(UnsupportedEquationsException, lambda: updater(eqs, variables))

    can_integrate = {linear: False, euler: True, rk2: False, rk4: False, heun: True, milstein: True}
    for integrator, able in can_integrate.iteritems():
        try:
            integrator(eqs, variables)
            if not able:
                raise AssertionError("Should not be able to integrate these " "equations")
        except UnsupportedEquationsException:
            if able:
                raise AssertionError("Should be able to integrate these " "equations")

    # Equation with multiplicative noise
    eqs = Equations("dv/dt = -v / (10*ms) + v*xi/(10*ms)**.5 : 1")
    assert_raises(UnsupportedEquationsException, lambda: updater(eqs, variables))

    can_integrate = {linear: False, euler: False, rk2: False, rk4: False, heun: True, milstein: True}
    for integrator, able in can_integrate.iteritems():
        try:
            integrator(eqs, variables)
            if not able:
                raise AssertionError("Should not be able to integrate these " "equations")
        except UnsupportedEquationsException:
            if able:
                raise AssertionError("Should be able to integrate these " "equations")
Example #15
0
def test_GSL_fixed_timestep_big_dt_small_error():
    # should raise integration error
    neuron = NeuronGroup(1, model=HH_eqs, threshold='v > -40*mV',
                         refractory='v > -40*mV', method='gsl',
                         method_options={'adaptable_timestep': False,
                                         'absolute_error': 1e-12},
                         dt=.001*ms, namespace=HH_namespace)
    neuron.I = 0.7*nA/(20000*umetre**2)
    neuron.v = HH_namespace['El']
    net = Network(neuron)
    assert_raises((RuntimeError, IntegrationError), net.run, 10*ms)
Example #16
0
def test_write_to_subexpression():
    variables = {
        'a': Subexpression(name='a', dtype=np.float32,
                           owner=FakeGroup(variables={}), device=None,
                           expr='2*z'),
        'z': Variable(name='z')
    }

    # Writing to a subexpression is not allowed
    code = 'a = z'
    assert_raises(SyntaxError, make_statements, code, variables, np.float32)
Example #17
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)
    assert_raises(UnsupportedEquationsException,
                  net.run, 0*ms, namespace={'tau': tau,
                                            'sigma': sigma})
Example #18
0
def test_name_clashes():
    # Using identical names for synaptic and pre- or post-synaptic variables
    # is confusing and should be forbidden
    G1 = NeuronGroup(1, 'a : 1')
    G2 = NeuronGroup(1, 'b : 1')
    assert_raises(ValueError, lambda: Synapses(G1, G2, 'a : 1'))
    assert_raises(ValueError, lambda: Synapses(G1, G2, 'b : 1'))

    # this should all be ok
    Synapses(G1, G2, 'c : 1')
    Synapses(G1, G2, 'a_syn : 1')
    Synapses(G1, G2, 'b_syn : 1')
Example #19
0
def test_clear_cache_cython():
    if prefs.codegen.target != 'cython':
        raise SkipTest('Cython-only test')
    assert 'cython' in _cache_dirs_and_extensions
    cache_dir, _ = _cache_dirs_and_extensions['cython']
    # Create a file that should not be there
    fname = os.path.join(cache_dir, 'some_file.py')
    open(fname, 'w').close()
    # clear_cache should refuse to clear the directory
    assert_raises(IOError, clear_cache, 'cython')

    os.remove(fname)
Example #20
0
def test_state_monitor():
    G = NeuronGroup(10, 'v : volt')
    G.v = np.arange(10) * volt
    SG = G[5:]
    mon_all = StateMonitor(SG, 'v', record=True)
    mon_0 = StateMonitor(SG, 'v', record=0)
    run(defaultclock.dt)

    assert_allclose(mon_0[0].v, mon_all[0].v)
    assert_allclose(mon_0[0].v, np.array([5]) * volt)
    assert_allclose(mon_all.v.flatten(), np.arange(5, 10) * volt)

    assert_raises(IndexError, lambda: mon_all[5])
Example #21
0
def test_linked_var_in_reset_incorrect():
    # Raise an error if a scalar variable (linked variable from a group of size
    # 1 is set in a reset statement of a group with size > 1)
    G1 = NeuronGroup(1, 'x:1')
    G2 = NeuronGroup(2, '''x_linked : 1 (linked)
                           y:1''',
                     threshold='y>1', reset='y=0; x_linked += 1')
    G2.x_linked = linked_var(G1, 'x')
    G2.y = 1.1
    net = Network(G1, G2)
    # It is not well-defined what x_linked +=1 means in this context
    # (as for any other shared variable)
    assert_raises(SyntaxError, lambda: net.run(0*ms))
Example #22
0
def test_scalar_subexpression():
    G = NeuronGroup(10, '''v : 1
                           number : 1 (shared)''', threshold='False')
    S = Synapses(G, G, '''s : 1 (shared)
                          sub = number_post + s : 1 (shared)''',
                 pre='v+=s', connect=True)
    S.s = 100
    G.number = 50
    assert S.sub[:] == 150

    assert_raises(SyntaxError, lambda: Synapses(G, G, '''s : 1 (shared)
                                                     sub = v_post + s : 1 (shared)''',
                                                pre='v+=s', connect=True))
    def test_surface_outside_volume_voxel_selection(self, fn):
        skip_if_no_external('h5py')
        from mvpa2.base.hdf5 import h5save, h5load

        vol_shape = (10, 10, 10, 1)
        vol_affine = np.identity(4)
        vg = volgeom.VolGeom(vol_shape, vol_affine)

        # make surfaces that are far away from all voxels
        # in the volume
        sphere_density = 4
        far = 10000.
        outer = surf.generate_sphere(sphere_density) * 10 + far
        inner = surf.generate_sphere(sphere_density) * 5 + far

        vs = volsurf.VolSurfMaximalMapping(vg, inner, outer)
        radii = [10., 10]  # fixed and variable radii

        outside_node_margins = [0, far, True]
        for outside_node_margin in outside_node_margins:
            for radius in radii:
                selector = lambda: surf_voxel_selection.voxel_selection(vs,
                                                                        radius,
                                                                        outside_node_margin=outside_node_margin)

                if type(radius) is int and outside_node_margin is True:
                    assert_raises(ValueError, selector)
                else:
                    sel = selector()
                    if outside_node_margin is True:
                        # it should have all the keys, but they should
                        # all be empty
                        assert_array_equal(sel.keys(), range(inner.nvertices))
                        for k, v in sel.iteritems():
                            assert_equal(v, [])
                    else:
                        assert_array_equal(sel.keys(), [])

                    if outside_node_margin is True and \
                                    externals.versions['hdf5'] < '1.8.7':
                        raise SkipTest("Versions of hdf5 before 1.8.7 have "
                                       "problems with empty arrays")

                    h5save(fn, sel)
                    sel_copy = h5load(fn)

                    assert_array_equal(sel.keys(), sel_copy.keys())
                    for k in sel.keys():
                        assert_equal(sel[k], sel_copy[k])

                    assert_equal(sel, sel_copy)
Example #24
0
def test_state_monitor_record_single_timestep():
    G = NeuronGroup(1, 'dv/dt = -v/(5*ms) : 1')
    G.v = 1
    mon = StateMonitor(G, 'v', record=True)
    # Recording before a run should not work
    assert_raises(TypeError, lambda: mon.record_single_timestep())
    run(0.5*ms)
    mon.record_single_timestep()
    device.build(direct_call=False, **device.build_options)
    assert mon.t[0] == 0*ms
    assert mon[0].v[0] == 1
    assert_allclose(mon.t[-1], 0.5*ms)
    assert len(mon.t) == 6
    assert mon[0].v[-1] == G.v
Example #25
0
def test_state_monitor_indexing():
    # Check indexing semantics
    G = NeuronGroup(10, 'v:volt')
    G.v = np.arange(10) * volt
    mon = StateMonitor(G, 'v', record=[5, 6, 7])

    run(2 * defaultclock.dt)

    assert_array_equal(mon.v, np.array([[5, 5],
                                  [6, 6],
                                  [7, 7]]) * volt)
    assert_array_equal(mon.v_, np.array([[5, 5],
                                   [6, 6],
                                   [7, 7]]))
    assert_array_equal(mon[5].v, mon.v[0])
    assert_array_equal(mon[7].v, mon.v[2])
    assert_array_equal(mon[[5, 7]].v, mon.v[[0, 2]])
    assert_array_equal(mon[np.array([5, 7])].v, mon.v[[0, 2]])

    assert_allclose(mon.t[1:], Quantity([defaultclock.dt]))

    assert_raises(IndexError, lambda: mon[8])
    assert_raises(TypeError, lambda: mon['string'])
    assert_raises(TypeError, lambda: mon[5.0])
    assert_raises(TypeError, lambda: mon[[5.0, 6.0]])
Example #26
0
def test_delay_specification():
    # By default delays are state variables (i.e. arrays), but if they are
    # specified in the initializer, they are scalars.
    G = NeuronGroup(10, 'v:1', threshold='False')

    # Array delay
    S = Synapses(G, G, 'w:1', pre='v+=w')
    S.connect('i==j')
    assert len(S.delay[:]) == len(G)
    S.delay = 'i*ms'
    assert_equal(S.delay[:], np.arange(len(G))*ms)
    S.delay = 5*ms
    assert_equal(S.delay[:], np.ones(len(G))*5*ms)

    # Scalar delay
    S = Synapses(G, G, 'w:1', pre='v+=w', delay=5*ms)
    assert_equal(S.delay[:], 5*ms)
    S.connect('i==j')
    S.delay = 10*ms
    assert_equal(S.delay[:], 10*ms)
    # S.delay = '3*ms'
    # assert_equal(S.delay[:], 3*ms)

    # Invalid arguments
    assert_raises(DimensionMismatchError, lambda: Synapses(G, G, 'w:1',
                                                           pre='v+=w',
                                                           delay=5*mV))
    assert_raises(TypeError, lambda: Synapses(G, G, 'w:1', pre='v+=w',
                                              delay=object()))
    assert_raises(ValueError, lambda: Synapses(G, G, 'w:1', delay=5*ms))
    assert_raises(ValueError, lambda: Synapses(G, G, 'w:1', pre='v+=w',
                                               delay={'post': 5*ms}))
Example #27
0
def test_state_variables():
    '''
    Test the setting and accessing of state variables in subgroups.
    '''
    for codeobj_class in codeobj_classes:
        G = NeuronGroup(10, 'v : volt', codeobj_class=codeobj_class)
        SG = G[4:9]
        assert_raises(DimensionMismatchError, lambda: SG.__setattr__('v', -70))
        SG.v_ = float(-80*mV)
        assert_allclose(G.v,
                        np.array([0, 0, 0, 0, -80, -80, -80, -80, -80, 0])*mV)
        assert_allclose(SG.v,
                        np.array([-80, -80, -80, -80, -80])*mV)
        assert_allclose(G.v_,
                        np.array([0, 0, 0, 0, -80, -80, -80, -80, -80, 0])*mV)
        assert_allclose(SG.v_,
                        np.array([-80, -80, -80, -80, -80])*mV)
        # You should also be able to set variables with a string
        SG.v = 'v + i*mV'
        assert_allclose(SG.v[0], -80*mV)
        assert_allclose(SG.v[4], -76*mV)
        assert_allclose(G.v[4:9], -80*mV + np.arange(5)*mV)

        # Calculating with state variables should work too
        assert all(G.v[4:9] - SG.v == 0)

        # And in-place modification should work as well
        SG.v += 10*mV
        assert_allclose(G.v[4:9], -70*mV + np.arange(5)*mV)
        SG.v *= 2
        assert_allclose(G.v[4:9], 2*(-70*mV + np.arange(5)*mV))
        # with unit checking
        assert_raises(DimensionMismatchError, lambda: SG.v.__iadd__(3*second))
        assert_raises(DimensionMismatchError, lambda: SG.v.__iadd__(3))
        assert_raises(DimensionMismatchError, lambda: SG.v.__imul__(3*second))
Example #28
0
def test_delay_specification():
    # By default delays are state variables (i.e. arrays), but if they are
    # specified in the initializer, they are scalars.
    G = NeuronGroup(10, 'v:1')

    # Array delay
    S = Synapses(G, G, 'w:1', pre='v+=w')
    S.connect('i==j')
    assert len(S.delay[:]) == len(G)
    S.delay = 'i*ms'
    assert_equal(S.delay[:], np.arange(len(G))*ms)
    S.delay = 5*ms
    assert_equal(S.delay[:], np.ones(len(G))*5*ms)

    # Scalar delay
    S = Synapses(G, G, 'w:1', pre='v+=w', delay=5*ms)
    S.connect('i==j')
    S.delay = 10*ms
    assert_equal(S.delay[:], 10*ms)
    S.delay = '3*ms'
    assert_equal(S.delay[:], 3*ms)
    # TODO: Assignment with strings or arrays is currently possible, it only
    # takes into account the first value

    # Invalid arguments
    assert_raises(DimensionMismatchError, lambda: Synapses(G, G, 'w:1',
                                                           pre='v+=w',
                                                           delay=5*mV))
    assert_raises(TypeError, lambda: Synapses(G, G, 'w:1', pre='v+=w',
                                              delay=object()))
    assert_raises(ValueError, lambda: Synapses(G, G, 'w:1', delay=5*ms))
    assert_raises(ValueError, lambda: Synapses(G, G, 'w:1', pre='v+=w',
                                               delay={'post': 5*ms}))
Example #29
0
def test_state_variable_access():
    for codeobj_class in codeobj_classes:
        G = NeuronGroup(10, 'v:volt', codeobj_class=codeobj_class)
        G.v = np.arange(10) * volt

        assert_equal(np.asarray(G.v[:]), np.arange(10))
        assert have_same_dimensions(G.v[:], volt)
        assert_equal(np.asarray(G.v[:]), G.v_[:])
        # Accessing single elements, slices and arrays
        assert G.v[5] == 5 * volt
        assert G.v_[5] == 5
        assert_equal(G.v[:5], np.arange(5) * volt)
        assert_equal(G.v_[:5], np.arange(5))
        assert_equal(G.v[[0, 5]], [0, 5] * volt)
        assert_equal(G.v_[[0, 5]], np.array([0, 5]))

        # Illegal indexing
        assert_raises(IndexError, lambda: G.v[0, 0])
        assert_raises(IndexError, lambda: G.v_[0, 0])
        assert_raises(TypeError, lambda: G.v[object()])
        assert_raises(TypeError, lambda: G.v_[object()])

        # A string representation should not raise any error
        assert len(str(G.v))
        assert len(repr(G.v))
        assert len(str(G.v_))
        assert len(repr(G.v_))
Example #30
0
def test_state_variable_indexing():
    G1 = NeuronGroup(5, 'v:volt')
    G1.v = 'i*mV'
    G2 = NeuronGroup(7, 'v:volt')
    G2.v= '10*mV + i*mV'
    S = Synapses(G1, G2, 'w:1')
    S.connect(True, n=2)
    S.w[:, :, 0] = '5*i + j'
    S.w[:, :, 1] = '35 + 5*i + j'

    #Slicing
    assert len(S.w[:]) == len(S.w[:, :]) == len(S.w[:, :, :]) == len(G1)*len(G2)*2
    assert len(S.w[0:, 0:]) == len(S.w[0:, 0:, 0:]) == len(G1)*len(G2)*2
    assert len(S.w[0::2, 0:]) == 3*len(G2)*2
    assert len(S.w[0, :]) == len(S.w[0, :, :]) == len(G2)*2
    assert len(S.w[0:2, :]) == len(S.w[0:2, :, :]) == 2*len(G2)*2
    assert len(S.w[:2, :]) == len(S.w[:2, :, :]) == 2*len(G2)*2
    assert len(S.w[0:4:2, :]) == len(S.w[0:4:2, :, :]) == 2*len(G2)*2
    assert len(S.w[:4:2, :]) == len(S.w[:4:2, :, :]) == 2*len(G2)*2
    assert len(S.w[:, 0]) == len(S.w[:, 0, :]) == len(G1)*2
    assert len(S.w[:, 0:2]) == len(S.w[:, 0:2, :]) == 2*len(G1)*2
    assert len(S.w[:, :2]) == len(S.w[:, :2, :]) == 2*len(G1)*2
    assert len(S.w[:, 0:4:2]) == len(S.w[:, 0:4:2, :]) == 2*len(G1)*2
    assert len(S.w[:, :4:2]) == len(S.w[:, :4:2, :]) == 2*len(G1)*2
    assert len(S.w[:, :, 0]) == len(G1)*len(G2)
    assert len(S.w[:, :, 0:2]) == len(G1)*len(G2)*2
    assert len(S.w[:, :, :2]) == len(G1)*len(G2)*2
    assert len(S.w[:, :, 0:2:2]) == len(G1)*len(G2)
    assert len(S.w[:, :, :2:2]) == len(G1)*len(G2)

    # 1d indexing is directly indexing synapses!
    assert len(S.w[:]) == len(S.w[0:])
    assert len(S.w[[0, 1]]) == len(S.w[3:5]) == 2
    assert len(S.w[:]) == len(S.w[np.arange(len(G1)*len(G2)*2)])

    #Array-indexing (not yet supported for synapse index)
    assert_equal(S.w[:, 0:3], S.w[:, [0, 1, 2]])
    assert_equal(S.w[:, 0:3], S.w[np.arange(len(G1)), [0, 1, 2]])

    #string-based indexing
    assert_equal(S.w[0:3, :], S.w['i<3'])
    assert_equal(S.w[:, 0:3], S.w['j<3'])
    # TODO: k is not working yet
    # assert_equal(S.w[:, :, 0], S.w['k==0'])
    assert_equal(S.w[0:3, :], S.w['v_pre < 3*mV'])
    assert_equal(S.w[:, 0:3], S.w['v_post < 13*mV'])

    #invalid indices
    assert_raises(IndexError, lambda: S.w.__getitem__((1, 2, 3, 4)))
    assert_raises(IndexError, lambda: S.w.__getitem__(object()))
Example #31
0
def test_spikegenerator_incorrect_period():
    '''
    Test that you cannot provide incorrect period arguments or combine
    inconsistent period and dt arguments.
    '''
    # Period is negative
    assert_raises(ValueError, lambda: SpikeGeneratorGroup(1, [], []*second,
                                                          period=-1*ms))

    # Period is smaller than the highest spike time
    assert_raises(ValueError, lambda: 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)
    assert_raises(NotImplementedError, lambda: net.run(0*ms))

    # Period is smaller than dt
    SG = SpikeGeneratorGroup(1, [], []*second, period=1*ms, dt=2*ms)
    net = Network(SG)
    assert_raises(ValueError, lambda: net.run(0*ms))
Example #32
0
def test_poissoninput_errors():
    # Targeting non-existing variable
    G = NeuronGroup(10, '''x : volt
                           y : 1''')
    assert_raises(KeyError,
                  lambda: PoissonInput(G, 'z', 100, 100 * Hz, weight=1.0))

    # Incorrect units
    assert_raises(DimensionMismatchError,
                  lambda: PoissonInput(G, 'x', 100, 100 * Hz, weight=1.0))
    assert_raises(
        DimensionMismatchError,
        lambda: 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())
    assert_raises(NotImplementedError, lambda: net.run(0 * ms))
    defaultclock.dt = old_dt
Example #33
0
def test_state_monitor_indexing():
    # Check indexing semantics
    G = NeuronGroup(10, 'v:volt')
    G.v = np.arange(10) * volt
    mon = StateMonitor(G, 'v', record=[5, 6, 7])

    run(2 * defaultclock.dt)

    assert_array_equal(mon.v, np.array([[5, 5], [6, 6], [7, 7]]) * volt)
    assert_array_equal(mon.v_, np.array([[5, 5], [6, 6], [7, 7]]))
    assert_array_equal(mon[5].v, mon.v[0])
    assert_array_equal(mon[7].v, mon.v[2])
    assert_array_equal(mon[[5, 7]].v, mon.v[[0, 2]])
    assert_array_equal(mon[np.array([5, 7])].v, mon.v[[0, 2]])

    assert_allclose(mon.t[1:], Quantity([defaultclock.dt]))

    assert_raises(IndexError, lambda: mon[8])
    assert_raises(TypeError, lambda: mon['string'])
    assert_raises(TypeError, lambda: mon[5.0])
    assert_raises(TypeError, lambda: mon[[5.0, 6.0]])
Example #34
0
def test_get_dtype():
    '''
    Check the utility function get_dtype
    '''
    eqs = Equations('''dv/dt = -v / (10*ms) : volt
                       x : 1
                       b : boolean
                       n : integer''')

    # Test standard dtypes
    assert get_dtype(eqs['v']) == prefs['core.default_float_dtype']
    assert get_dtype(eqs['x']) == prefs['core.default_float_dtype']
    assert get_dtype(eqs['n']) == prefs['core.default_integer_dtype']
    assert get_dtype(eqs['b']) == np.bool

    # Test a changed default (float) dtype
    assert get_dtype(eqs['v'], np.float32) == np.float32, get_dtype(
        eqs['v'], np.float32)
    assert get_dtype(eqs['x'], np.float32) == np.float32
    # integer and boolean variables should be unaffected
    assert get_dtype(eqs['n']) == prefs['core.default_integer_dtype']
    assert get_dtype(eqs['b']) == np.bool

    # Explicitly provide a dtype for some variables
    dtypes = {'v': np.float32, 'x': np.float64, 'n': np.int64}
    for varname in dtypes:
        assert get_dtype(eqs[varname], dtypes) == dtypes[varname]

    # Not setting some dtypes should use the standard dtypes
    dtypes = {'n': np.int64}
    assert get_dtype(eqs['n'], dtypes) == np.int64
    assert get_dtype(eqs['v'], dtypes) == prefs['core.default_float_dtype']

    # Test that incorrect types raise an error
    # incorrect general dtype
    assert_raises(TypeError, lambda: get_dtype(eqs['v'], np.int32))
    # incorrect specific types
    assert_raises(TypeError, lambda: get_dtype(eqs['v'], {'v': np.int32}))
    assert_raises(TypeError, lambda: get_dtype(eqs['n'], {'n': np.float32}))
    assert_raises(TypeError, lambda: get_dtype(eqs['b'], {'b': np.int32}))
Example #35
0
def test_unit_errors_threshold_reset():
    '''
    Test that unit errors in thresholds and resets are detected.
    '''
    # Unit error in threshold
    assert_raises(DimensionMismatchError,
                  lambda: NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                                      threshold='v > -20*mV'))

    # Unit error in reset
    assert_raises(DimensionMismatchError,
                  lambda: NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                                      reset='v = -65*mV'))

    # More complicated unit reset with an intermediate variable
    # This should pass
    NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                reset='''temp_var = -65
                         v = temp_var''')
    # throw in an empty line (should still pass)
    NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                reset='''temp_var = -65

                         v = temp_var''')

    # This should fail
    assert_raises(DimensionMismatchError,
                  lambda: NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                                      reset='''temp_var = -65*mV
                                               v = temp_var'''))

    # Resets with an in-place modification
    # This should work
    NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                reset='''v /= 2''')

    # This should fail
    assert_raises(DimensionMismatchError,
                  lambda: NeuronGroup(1, 'dv/dt = -v/(10*ms) : 1',
                                      reset='''v -= 60*mV'''))
Example #36
0
def test_illegal_calls():
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    clock = Clock(dt=0.1*ms)
    variables = {'v': ArrayVariable(name='name', unit=Unit(1), size=10,
                                    owner=None, device=None, dtype=np.float64,
                                    constant=False),
                 't': clock.variables['t'],
                 'dt': clock.variables['dt']}
    assert_raises(TypeError, lambda: StateUpdateMethod.apply_stateupdater(eqs,
                                                                          variables,
                                                                          object()))
    assert_raises(TypeError, lambda: StateUpdateMethod.apply_stateupdater(eqs,
                                                                          variables,
                                                                          group_name='my_name',
                                                                          method=object()))
    assert_raises(TypeError, lambda: StateUpdateMethod.apply_stateupdater(eqs,
                                                                          variables,
                                                                          [object(), 'euler']))
    assert_raises(TypeError, lambda: StateUpdateMethod.apply_stateupdater(eqs,
                                                                          variables,
                                                                          group_name='my_name',
                                                                          method=[object(), 'euler']))
Example #37
0
def test_creation():
    '''
    A basic test that creating a NeuronGroup works.
    '''
    G = NeuronGroup(42, model='dv/dt = -v/(10*ms) : 1', reset='v=0',
                    threshold='v>1')
    assert len(G) == 42
        
    # Test some error conditions
    # --------------------------
    
    # Model equations as first argument (no number of neurons)
    assert_raises(TypeError, lambda: NeuronGroup('dv/dt = 5*Hz : 1', 1))
    
    # Not a number as first argument
    assert_raises(TypeError, lambda: NeuronGroup(object(), 'dv/dt = 5*Hz : 1'))
    
    # Illegal number
    assert_raises(ValueError, lambda: NeuronGroup(0, 'dv/dt = 5*Hz : 1'))
    
    # neither string nor Equations object as model description
    assert_raises(TypeError, lambda: NeuronGroup(1, object()))
Example #38
0
def test_namespace_errors():

    # model equations use unknown identifier
    G = NeuronGroup(1, 'dv/dt = -v/tau : 1')
    net = Network(G)
    assert_raises(KeyError, lambda: net.run(1*ms))

    # reset uses unknown identifier
    G = NeuronGroup(1, 'dv/dt = -v/tau : 1', threshold='False', reset='v = v_r')
    net = Network(G)
    assert_raises(KeyError, lambda: net.run(1*ms))

    # threshold uses unknown identifier
    G = NeuronGroup(1, 'dv/dt = -v/tau : 1', threshold='v > v_th')
    net = Network(G)
    assert_raises(KeyError, lambda: net.run(1*ms))
Example #39
0
def test_spike_monitor():
    G = NeuronGroup(3, '''dv/dt = rate : 1
                          rate: Hz''', threshold='v>1', reset='v=0')
    # We don't use 100 and 1000Hz, because then the membrane potential would
    # be exactly at 1 after 10 resp. 100 timesteps. Due to floating point
    # issues this will not be exact,
    G.rate = [101, 0, 1001] * Hz

    mon = SpikeMonitor(G)

    assert_raises(ValueError, lambda: SpikeMonitor(G, order=1))  # need to specify 'when' as well

    run(10*ms)

    spike_trains = mon.spike_trains()

    assert_allclose(mon.t[mon.i == 0], [9.9]*ms)
    assert len(mon.t[mon.i == 1]) == 0
    assert_allclose(mon.t[mon.i == 2], np.arange(10)*ms + 0.9*ms)
    assert_allclose(mon.t_[mon.i == 0], np.array([9.9*float(ms)]))
    assert len(mon.t_[mon.i == 1]) == 0
    assert_allclose(mon.t_[mon.i == 2], (np.arange(10) + 0.9)*float(ms))
    assert_allclose(spike_trains[0], [9.9]*ms)
    assert len(spike_trains[1]) == 0
    assert_allclose(spike_trains[2], np.arange(10)*ms + 0.9*ms)
    assert_array_equal(mon.count, np.array([1, 0, 10]))

    i, t = mon.it
    i_, t_ = mon.it_
    assert_array_equal(i, mon.i)
    assert_array_equal(i, i_)
    assert_array_equal(t, mon.t)
    assert_array_equal(t_, mon.t_)

    assert_raises(KeyError, lambda: spike_trains[3])
    assert_raises(KeyError, lambda: spike_trains[-1])
    assert_raises(KeyError, lambda: spike_trains['string'])
Example #40
0
def test_state_variables():
    '''
    Test the setting and accessing of state variables in subgroups.
    '''
    G = NeuronGroup(10, 'v : volt')
    SG = G[4:9]
    assert_raises(DimensionMismatchError, lambda: SG.__setattr__('v', -70))
    SG.v_ = float(-80*mV)
    assert_allclose(G.v,
                    np.array([0, 0, 0, 0, -80, -80, -80, -80, -80, 0])*mV)
    assert_allclose(SG.v,
                    np.array([-80, -80, -80, -80, -80])*mV)
    assert_allclose(G.v_,
                    np.array([0, 0, 0, 0, -80, -80, -80, -80, -80, 0])*float(mV))
    assert_allclose(SG.v_,
                    np.array([-80, -80, -80, -80, -80])*float(mV))
    # You should also be able to set variables with a string
    SG.v = 'v + i*mV'
    assert_allclose(SG.v[0], -80*mV)
    assert_allclose(SG.v[4], -76*mV)
    assert_allclose(G.v[4:9], -80*mV + np.arange(5)*mV)

    # Calculating with state variables should work too
    assert all(G.v[4:9] - SG.v == 0)

    # And in-place modification should work as well
    SG.v += 10*mV
    assert_allclose(G.v[4:9], -70*mV + np.arange(5)*mV)
    SG.v *= 2
    assert_allclose(G.v[4:9], 2*(-70*mV + np.arange(5)*mV))
    # with unit checking
    assert_raises(DimensionMismatchError, lambda: SG.v.__iadd__(3*second))
    assert_raises(DimensionMismatchError, lambda: SG.v.__iadd__(3))
    assert_raises(DimensionMismatchError, lambda: SG.v.__imul__(3*second))

    # Indexing with subgroups
    assert_equal(G.v[SG], SG.v[:])
Example #41
0
def test_initialize_nevergrad():
    n_opt = NevergradOptimizer()
    n_opt.initialize({'g'}, g=[1, 30], popsize=30)
    assert isinstance(n_opt.optim, NOptimzer)
    assert_equal(n_opt.optim.dimension, 1)

    n_opt.initialize(['g', 'E'], g=[1, 30], E=[2, 20], popsize=30)
    assert isinstance(n_opt.optim, NOptimzer)
    assert_equal(n_opt.optim.dimension, 2)

    assert_raises(AssertionError, n_opt.initialize, ['g'], g=[1], popsize=30)
    assert_raises(AssertionError,
                  n_opt.initialize, ['g'],
                  g=[[1, 2]],
                  popsize=30)
    assert_raises(Exception,
                  n_opt.initialize, ['g'],
                  g=[1, 2],
                  E=[1, 2],
                  popsize=30)
    assert_raises(Exception,
                  n_opt.initialize, ['g', 'E'],
                  g=[1, 2],
                  popsize=30)
Example #42
0
def test_initialize_skopt():
    s_opt = SkoptOptimizer()
    s_opt.initialize({'g'}, g=[1, 30], popsize=30)
    assert isinstance(s_opt.optim, SOptimizer)
    assert_equal(len(s_opt.optim.space.dimensions), 1)

    s_opt.initialize({'g', 'E'}, g=[1, 30], E=[2, 20], popsize=30)
    assert isinstance(s_opt.optim, SOptimizer)
    assert_equal(len(s_opt.optim.space.dimensions), 2)

    assert_raises(TypeError, s_opt.initialize, ['g'], g=[1], popsize=30)
    assert_raises(Exception,
                  s_opt.initialize, ['g'],
                  g=[1, 2],
                  E=[1, 2],
                  popsize=30)
    assert_raises(Exception,
                  s_opt.initialize, ['g', 'E'],
                  g=[1, 2],
                  popsize=30)
Example #43
0
def test_event_monitor():
    G = NeuronGroup(3,
                    '''dv/dt = rate : 1
                          rate: Hz''',
                    events={'my_event': 'v>1'})
    G.run_on_event('my_event', 'v=0')
    # We don't use 100 and 1000Hz, because then the membrane potential would
    # be exactly at 1 after 10 resp. 100 timesteps. Due to floating point
    # issues this will not be exact,
    G.rate = [101, 0, 1001] * Hz

    mon = EventMonitor(G, 'my_event')
    net = Network(G, mon)
    net.run(10 * ms)

    event_trains = mon.event_trains()

    assert_allclose(mon.t[mon.i == 0], [9.9] * ms)
    assert len(mon.t[mon.i == 1]) == 0
    assert_allclose(mon.t[mon.i == 2], np.arange(10) * ms + 0.9 * ms)
    assert_allclose(mon.t_[mon.i == 0], np.array([9.9 * float(ms)]))
    assert len(mon.t_[mon.i == 1]) == 0
    assert_allclose(mon.t_[mon.i == 2], (np.arange(10) + 0.9) * float(ms))
    assert_allclose(event_trains[0], [9.9] * ms)
    assert len(event_trains[1]) == 0
    assert_allclose(event_trains[2], np.arange(10) * ms + 0.9 * ms)
    assert_array_equal(mon.count, np.array([1, 0, 10]))

    i, t = mon.it
    i_, t_ = mon.it_
    assert_array_equal(i, mon.i)
    assert_array_equal(i, i_)
    assert_array_equal(t, mon.t)
    assert_array_equal(t_, mon.t_)

    assert_raises(KeyError, lambda: event_trains[3])
    assert_raises(KeyError, lambda: event_trains[-1])
    assert_raises(KeyError, lambda: event_trains['string'])
Example #44
0
def test_explicit_stateupdater_parsing():
    '''
    Test the parsing of explicit state updater descriptions.
    '''
    # These are valid descriptions and should not raise errors
    updater = ExplicitStateUpdater('x_new = x + dt * f(x, t)')
    updater(Equations('dv/dt = -v / tau : 1'))
    updater = ExplicitStateUpdater('''x2 = x + dt * f(x, t)
                                      x_new = x2''')
    updater(Equations('dv/dt = -v / tau : 1'))
    updater = ExplicitStateUpdater('''x1 = g(x, t) * dW
                                      x2 = x + dt * f(x, t)
                                      x_new = x1 + x2''',
                                   stochastic='multiplicative')
    updater(Equations('dv/dt = -v / tau + v * xi * tau**-.5: 1'))

    updater = ExplicitStateUpdater(
        '''x_support = x + dt*f(x, t) + dt**.5 * g(x, t)
                                      g_support = g(x_support, t)
                                      k = 1/(2*dt**.5)*(g_support - g(x, t))*(dW**2)
                                      x_new = x + dt*f(x,t) + g(x, t) * dW + k''',
        stochastic='multiplicative')
    updater(Equations('dv/dt = -v / tau + v * xi * tau**-.5: 1'))

    # Examples of failed parsing
    # No x_new = ... statement
    assert_raises(SyntaxError,
                  lambda: ExplicitStateUpdater('x = x + dt * f(x, t)'))
    # Not an assigment
    assert_raises(
        SyntaxError, lambda: ExplicitStateUpdater('''2 * x
                                                               x_new = x + dt * f(x, t)'''
                                                  ))

    # doesn't separate into stochastic and non-stochastic part
    updater = ExplicitStateUpdater(
        '''x_new = x + dt * f(x, t) * g(x, t) * dW''')
    assert_raises(ValueError, lambda: updater(Equations('')))
Example #45
0
def test_calc_gf():
    assert_raises(TypeError, GammaFactor)
    assert_raises(DimensionMismatchError, GammaFactor, delta=10 * mV)
    assert_raises(DimensionMismatchError, GammaFactor, time=10)

    model_spikes = [
        [np.array([1, 5, 8]), np.array([2, 3, 8, 9])],  # Correct rate
        [np.array([1, 5]), np.array([0, 2, 3, 8, 9])]
    ]  # Wrong rate
    data_spikes = [np.array([0, 5, 9]), np.array([1, 3, 5, 6])]

    gf = GammaFactor(delta=0.5 * ms, time=10 * ms)
    errors = gf.calc([data_spikes] * 5, data_spikes, 0.1 * ms)
    assert_almost_equal(errors, np.ones(5) * -1)
    errors = gf.calc(model_spikes, data_spikes, 0.1 * ms)
    assert errors[0] > -1  # correct rate
    assert errors[1] > errors[0]

    gf = GammaFactor(delta=0.5 * ms, time=10 * ms, rate_correction=False)
    errors = gf.calc([data_spikes] * 5, data_spikes, 0.1 * ms)
    assert_almost_equal(errors, np.zeros(5))
    errors = gf.calc(model_spikes, data_spikes, 0.1 * ms)
    assert all(errors > 0)
Example #46
0
def test_determination():
    '''
    Test the determination of suitable state updaters.
    '''
    # To save some typing
    apply_stateupdater = StateUpdateMethod.apply_stateupdater

    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    # Just make sure that state updaters know about the two state variables
    variables = {'v': Variable(name='v'), 'w': Variable(name='w')}

    # all methods should work for these equations.
    # First, specify them explicitly (using the object)
    for integrator in (
            linear,
            euler,
            exponential_euler,  #TODO: Removed "independent" here due to the issue in sympy 0.7.4
            rk2,
            rk4,
            heun,
            milstein):
        with catch_logs() as logs:
            returned = apply_stateupdater(eqs, variables, method=integrator)
            assert len(logs) == 0, 'Got %d unexpected warnings: %s' % (
                len(logs), str([l[2] for l in logs]))

    # Equation with multiplicative noise, only milstein and heun should work
    eqs = Equations('dv/dt = -v / (10*ms) + v*xi*second**-.5: 1')
    for integrator in (linear, independent, euler, exponential_euler, rk2,
                       rk4):
        assert_raises(UnsupportedEquationsException,
                      lambda: apply_stateupdater(eqs, variables, integrator))

    for integrator in (heun, milstein):
        with catch_logs() as logs:
            returned = apply_stateupdater(eqs, variables, method=integrator)
            assert len(logs) == 0, 'Got %d unexpected warnings: %s' % (
                len(logs), str([l[2] for l in logs]))

    # Arbitrary functions (converting equations into abstract code) should
    # always work
    my_stateupdater = lambda eqs, vars, options: 'x_new = x'
    with catch_logs() as logs:
        returned = apply_stateupdater(eqs, variables, method=my_stateupdater)
        # No warning here
        assert len(logs) == 0

    # Specification with names
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    for name, integrator in [
        ('exact', exact),
        ('linear', linear),
        ('euler', euler),
            #('independent', independent), #TODO: Removed "independent" here due to the issue in sympy 0.7.4
        ('exponential_euler', exponential_euler),
        ('rk2', rk2),
        ('rk4', rk4),
        ('heun', heun),
        ('milstein', milstein)
    ]:
        with catch_logs() as logs:
            returned = apply_stateupdater(eqs, variables, method=name)
            # No warning here
            assert len(logs) == 0

    # Now all except heun and milstein should refuse to work
    eqs = Equations('dv/dt = -v / (10*ms) + v*xi*second**-.5: 1')
    for name in [
            'linear', 'exact', 'independent', 'euler', 'exponential_euler',
            'rk2', 'rk4'
    ]:
        assert_raises(UnsupportedEquationsException,
                      lambda: apply_stateupdater(eqs, variables, method=name))

    # milstein should work
    with catch_logs() as logs:
        apply_stateupdater(eqs, variables, method='milstein')
        assert len(logs) == 0

    # heun should work
    with catch_logs() as logs:
        apply_stateupdater(eqs, variables, method='heun')
        assert len(logs) == 0

    # non-existing name
    assert_raises(
        ValueError,
        lambda: apply_stateupdater(eqs, variables, method='does_not_exist'))

    # Automatic state updater choice should return linear for linear equations,
    # euler for non-linear, non-stochastic equations and equations with
    # additive noise, heun for equations with multiplicative noise
    # Because it is somewhat fragile, the "independent" state updater is not
    # included in this list
    all_methods = [
        'linear', 'exact', 'exponential_euler', 'euler', 'heun', 'milstein'
    ]
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    with catch_logs(log_level=logging.INFO) as logs:
        apply_stateupdater(eqs, variables, all_methods)
        assert len(logs) == 1
        assert ('linear' in logs[0][2]) or ('exact' in logs[0][2])

    # This is conditionally linear
    eqs = Equations('''dv/dt = -(v + w**2)/ (10*ms) : 1
                       dw/dt = -w/ (10*ms) : 1''')
    with catch_logs(log_level=logging.INFO) as logs:
        apply_stateupdater(eqs, variables, all_methods)
        assert len(logs) == 1
        assert 'exponential_euler' in logs[0][2]

    # # Do not test for now
    # eqs = Equations('dv/dt = sin(t) / (10*ms) : 1')
    # assert apply_stateupdater(eqs, variables) is independent

    eqs = Equations('dv/dt = -sqrt(v) / (10*ms) : 1')
    with catch_logs(log_level=logging.INFO) as logs:
        apply_stateupdater(eqs, variables, all_methods)
        assert len(logs) == 1
        assert "'euler'" in logs[0][2]

    eqs = Equations('dv/dt = -v / (10*ms) + 0.1*second**-.5*xi: 1')
    with catch_logs(log_level=logging.INFO) as logs:
        apply_stateupdater(eqs, variables, all_methods)
        assert len(logs) == 1
        assert "'euler'" in logs[0][2]

    eqs = Equations('dv/dt = -v / (10*ms) + v*0.1*second**-.5*xi: 1')
    with catch_logs(log_level=logging.INFO) as logs:
        apply_stateupdater(eqs, variables, all_methods)
        assert len(logs) == 1
        assert "'heun'" in logs[0][2]
Example #47
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():
                assert_raises(UnsupportedEquationsException,
                              lambda: net.run(0 * ms))

        # 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():
                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='exact',
                    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='exact')
    net = Network(G)
    assert_raises(UnsupportedEquationsException, lambda: net.run(0 * ms))

    # Stateful functions aren't either
    G = NeuronGroup(1, 'dv/dt = -v/(10*ms) + rand()*Hz : 1', method='exact')
    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='exact')
    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='exact')
    net = Network(G)
    net.run(0 * ms)
Example #48
0
def test_profile_build_raises():
    # Test that profiling info is not 0
    set_device('cuda_standalone', directory=None, build_on_run=False)
    assert_raises(TypeError, lambda: device.build(profile=True))
    assert_raises(TypeError, lambda: device.build(profile=False))
    assert_raises(TypeError, lambda: device.build(profile='string'))
Example #49
0
def test_priority():
    updater = ExplicitStateUpdater('x_new = x + dt * f(x, t)')
    # Equations that work for the state updater
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    clock = Clock(dt=0.1 * ms)
    variables = {
        'v':
        ArrayVariable(name='name',
                      size=10,
                      owner=None,
                      device=None,
                      dtype=np.float64,
                      constant=False),
        'w':
        ArrayVariable(name='name',
                      size=10,
                      owner=None,
                      device=None,
                      dtype=np.float64,
                      constant=False),
        't':
        clock.variables['t'],
        'dt':
        clock.variables['dt']
    }
    updater(eqs, variables)  # should not raise an error

    # External parameter in the coefficient, linear integration should work
    param = 1
    eqs = Equations('dv/dt = -param * v / (10*ms) : 1')
    updater(eqs, variables)  # should not raise an error
    can_integrate = {
        linear: True,
        euler: True,
        exponential_euler: True,
        rk2: True,
        rk4: True,
        heun: True,
        milstein: True
    }

    check_integration(eqs, variables, can_integrate)

    # Constant equation, should work for all except linear (see #1010)
    param = 1
    eqs = Equations('''dv/dt = 10*Hz : 1
                       dw/dt = -v/(10*ms) : 1''')
    updater(eqs, variables)  # should not raise an error
    can_integrate = {
        linear: None,
        euler: True,
        exponential_euler: True,
        rk2: True,
        rk4: True,
        heun: True,
        milstein: True
    }

    check_integration(eqs, variables, can_integrate)

    # Equations resulting in complex linear solution for older versions of sympy
    eqs = Equations('''dv/dt      = (ge+gi-(v+49*mV))/(20*ms) : volt
            dge/dt     = -ge/(5*ms) : volt
            dgi/dt     = Dgi/(5*ms) : volt
            dDgi/dt    = ((-2./5) * Dgi - (1./5**2)*gi)/(10*ms) : volt''')
    can_integrate = {
        linear: None,
        euler: True,
        exponential_euler: True,
        rk2: True,
        rk4: True,
        heun: True,
        milstein: True
    }
    check_integration(eqs, variables, can_integrate)

    # Equation with additive noise
    eqs = Equations('dv/dt = -v / (10*ms) + xi/(10*ms)**.5 : 1')
    assert_raises(UnsupportedEquationsException,
                  lambda: updater(eqs, variables))

    can_integrate = {
        linear: False,
        euler: True,
        exponential_euler: False,
        rk2: False,
        rk4: False,
        heun: True,
        milstein: True
    }

    check_integration(eqs, variables, can_integrate)

    # Equation with multiplicative noise
    eqs = Equations('dv/dt = -v / (10*ms) + v*xi/(10*ms)**.5 : 1')
    assert_raises(UnsupportedEquationsException,
                  lambda: updater(eqs, variables))

    can_integrate = {
        linear: False,
        euler: False,
        exponential_euler: False,
        rk2: False,
        rk4: False,
        heun: True,
        milstein: True
    }

    check_integration(eqs, variables, can_integrate)
Example #50
0
def test_subgroup():
    morpho = Soma(diameter=30 * um)
    morpho.L = Cylinder(length=10 * um, diameter=1 * um, n=10)
    morpho.LL = Cylinder(length=5 * um, diameter=2 * um, n=5)
    morpho.right = Cylinder(length=3 * um, diameter=1 * um, n=7)
    # Getting a single compartment by index
    assert_allclose(morpho.L[2].distance, 3 * um)
    # Getting a single compartment by position
    assert_allclose(morpho.LL[0 * um].distance, 11 * um)
    assert_allclose(morpho.LL[1 * um].distance, 11 * um)
    assert_allclose(morpho.LL[1.5 * um].distance, 12 * um)
    assert_allclose(morpho.LL[5 * um].distance, 15 * um)
    # Getting a segment
    assert_allclose(morpho.L[3 * um:5.1 * um].distance,
                    [3 * um, 4 * um, 5 * um])
    # Indices cannot be obtained at this stage
    assert_raises(AttributeError, lambda: morpho.L.indices[:])
    # Compress the morphology and get absolute compartment indices
    N = len(morpho)
    morpho.compress(MorphologyData(N))
    assert_equal(morpho.LL.indices[:], [11, 12, 13, 14, 15])
    assert_equal(morpho.L.indices[3 * um:5.1 * um], [3, 4, 5])
    assert_equal(morpho.L.indices[3 * um:5.1 * um],
                 morpho.L[3 * um:5.1 * um].indices[:])
    assert_equal(morpho.L.indices[:5.1 * um], [1, 2, 3, 4, 5])
    assert_equal(morpho.L.indices[3 * um:], [3, 4, 5, 6, 7, 8, 9, 10])
    assert_equal(morpho.L.indices[3.5 * um], 4)
    assert_equal(morpho.L.indices[3], 4)
    assert_equal(morpho.L.indices[-1], 10)
    assert_equal(morpho.L.indices[3:5], [4, 5])
    assert_equal(morpho.L.indices[3:], [4, 5, 6, 7, 8, 9, 10])
    assert_equal(morpho.L.indices[:5], [1, 2, 3, 4, 5])

    # Main branch
    assert_equal(len(morpho.L.main), 10)

    # Non-existing branch
    assert_raises(AttributeError, lambda: morpho.axon)

    # Incorrect indexing
    #  wrong units or mixing units
    assert_raises(TypeError, lambda: morpho.indices[3 * second:5 * second])
    assert_raises(TypeError, lambda: morpho.indices[3.4:5.3])
    assert_raises(TypeError, lambda: morpho.indices[3:5 * um])
    assert_raises(TypeError, lambda: morpho.indices[3 * um:5])
    #   providing a step
    assert_raises(TypeError, lambda: morpho.indices[3 * um:5 * um:2 * um])
    assert_raises(TypeError, lambda: morpho.indices[3:5:2])
    #   incorrect type
    assert_raises(TypeError, lambda: morpho.indices[object()])
Example #51
0
def test_construction_coordinates():
    # Same as test_construction, but uses coordinates instead of lengths to
    # set up everything
    # Note that all coordinates here are relative to the origin of the
    # respective cylinder
    BrianLogger.suppress_name('resolution_conflict')
    morpho = Soma(diameter=30*um)
    morpho.L = Cylinder(x=[0, 10]*um, diameter=1*um, n=10)
    morpho.LL = Cylinder(y=[0, 5]*um, diameter=2*um, n=5)
    morpho.LR = Cylinder(z=[0, 5]*um, diameter=2*um, n=10)
    morpho.right = Cylinder(x=[0, sqrt(2)*1.5]*um, y=[0, sqrt(2)*1.5]*um,
                            diameter=1*um, n=7)
    morpho.right.nextone = Cylinder(y=[0, sqrt(2)]*um, z=[0, sqrt(2)]*um,
                                    diameter=1*um, n=3)
    gL=1e-4*siemens/cm**2
    EL=-70*mV
    eqs='''
    Im=gL*(EL-v) : amp/meter**2
    I : meter (point current)
    '''

    # Check units of currents
    assert_raises(DimensionMismatchError, lambda: SpatialNeuron(morphology=morpho,
                                                                model=eqs))

    eqs='''
    Im=gL*(EL-v) : amp/meter**2
    '''
    neuron = SpatialNeuron(morphology=morpho, model=eqs, Cm=1 * uF / cm ** 2, Ri=100 * ohm * cm)

    # Test initialization of values
    neuron.LL.v = EL
    assert_allclose(neuron.L.main.v, 0)
    assert_allclose(neuron.LL.v, EL)
    neuron.LL[1*um:3*um].v = 0*mV
    assert_allclose(neuron.LL.v, Quantity([EL, 0*mV, 0*mV, EL, EL]))
    assert_allclose(neuron.Cm, 1 * uF / cm ** 2)

    # Test morphological variables
    assert_allclose(neuron.L.main.x, morpho.L.x)
    assert_allclose(neuron.LL.main.x, morpho.LL.x)
    assert_allclose(neuron.right.main.x, morpho.right.x)
    assert_allclose(neuron.L.main.distance, morpho.L.distance)
    # assert_allclose(neuron.L.main.diameter, morpho.L.diameter)
    assert_allclose(neuron.L.main.area, morpho.L.area)
    assert_allclose(neuron.L.main.length, morpho.L.length)

    # Check basic consistency of the flattened representation
    assert all(neuron.diffusion_state_updater._ends[:].flat >=
               neuron.diffusion_state_updater._starts[:].flat)

    # Check that length and distances make sense
    assert_allclose(sum(morpho.L.length), 10*um)
    assert_allclose(morpho.L.distance, (0.5 + np.arange(10))*um)
    assert_allclose(sum(morpho.LL.length), 5*um)
    assert_allclose(morpho.LL.distance, (10 + .5 + np.arange(5))*um)
    assert_allclose(sum(morpho.LR.length), 5*um)
    assert_allclose(morpho.LR.distance, (10 + 0.25 + np.arange(10)*0.5)*um)
    assert_allclose(sum(morpho.right.length), 3*um)
    assert_allclose(morpho.right.distance, (0.5 + np.arange(7))*3./7.*um)
    assert_allclose(sum(morpho.right.nextone.length), 2*um)
    assert_allclose(morpho.right.nextone.distance, 3*um + (0.5 + np.arange(3))*2./3.*um)
Example #52
0
def test_determination():
    '''
    Test the determination of suitable state updaters.
    '''
    
    # To save some typing
    determine_stateupdater = StateUpdateMethod.determine_stateupdater
    
    # Save state before tests
    before = list(StateUpdateMethod.stateupdaters)
    
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    # Just make sure that state updaters know about the two state variables
    variables = {'v': Variable(name='v', unit=None),
                 'w': Variable(name='w', unit=None)}
    
    # all methods should work for these equations.
    # First, specify them explicitly (using the object)
    for integrator in (linear, euler, exponential_euler, #TODO: Removed "independent" here due to the issue in sympy 0.7.4
                       rk2, rk4, milstein):
        with catch_logs() as logs:
            returned = determine_stateupdater(eqs, variables,
                                              method=integrator)
            assert returned is integrator, 'Expected state updater %s, got %s' % (integrator, returned)
            assert len(logs) == 0, 'Got %d unexpected warnings: %s' % (len(logs), str([l[2] for l in logs]))
    
    # Equation with multiplicative noise, only milstein should work without
    # a warning
    eqs = Equations('dv/dt = -v / (10*ms) + v*xi*second**-.5: 1')
    for integrator in (linear, independent, euler, exponential_euler, rk2, rk4):
        with catch_logs() as logs:
            returned = determine_stateupdater(eqs, variables,
                                              method=integrator)
            assert returned is integrator, 'Expected state updater %s, got %s' % (integrator, returned)
            # We should get a warning here
            assert len(logs) == 1, 'Got %d warnings but expected 1: %s' % (len(logs), str([l[2] for l in logs]))
            
    with catch_logs() as logs:
        returned = determine_stateupdater(eqs, variables,
                                          method=milstein)
        assert returned is milstein, 'Expected state updater milstein, got %s' % (integrator, returned)
        # No warning here
        assert len(logs) == 0, 'Got %d unexpected warnings: %s' % (len(logs), str([l[2] for l in logs]))
    
    
    # Arbitrary functions (converting equations into abstract code) should
    # always work
    my_stateupdater = lambda eqs: 'x_new = x'
    with catch_logs() as logs:
        returned = determine_stateupdater(eqs, variables,
                                          method=my_stateupdater)
        assert returned is my_stateupdater
        # No warning here
        assert len(logs) == 0
    
    
    # Specification with names
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    for name, integrator in [('linear', linear), ('euler', euler),
                             #('independent', independent), #TODO: Removed "independent" here due to the issue in sympy 0.7.4
                             ('exponential_euler', exponential_euler),
                             ('rk2', rk2), ('rk4', rk4),
                             ('milstein', milstein)]:
        with catch_logs() as logs:
            returned = determine_stateupdater(eqs, variables,
                                              method=name)
        assert returned is integrator
        # No warning here
        assert len(logs) == 0    

    # Now all except milstein should refuse to work
    eqs = Equations('dv/dt = -v / (10*ms) + v*xi*second**-.5: 1')
    for name in ['linear', 'independent', 'euler', 'exponential_euler',
                 'rk2', 'rk4']:
        assert_raises(ValueError, lambda: determine_stateupdater(eqs,
                                                                 variables,
                                                                 method=name))
    # milstein should work
    with catch_logs() as logs:
        determine_stateupdater(eqs, variables, method='milstein')
        assert len(logs) == 0
    
    # non-existing name
    assert_raises(ValueError, lambda: determine_stateupdater(eqs,
                                                             variables,
                                                             method='does_not_exist'))
    
    # Automatic state updater choice should return linear for linear equations,
    # euler for non-linear, non-stochastic equations and equations with
    # additive noise, milstein for equations with multiplicative noise
    eqs = Equations('dv/dt = -v / (10*ms) : 1')
    assert determine_stateupdater(eqs, variables) is linear
    
    # This is conditionally linear
    eqs = Equations('''dv/dt = -(v + w**2)/ (10*ms) : 1
                       dw/dt = -w/ (10*ms) : 1''')
    assert determine_stateupdater(eqs, variables) is exponential_euler

    eqs = Equations('dv/dt = sin(t) / (10*ms) : 1')
    assert determine_stateupdater(eqs, variables) is independent

    eqs = Equations('dv/dt = -sqrt(v) / (10*ms) : 1')
    assert determine_stateupdater(eqs, variables) is euler

    eqs = Equations('dv/dt = -v / (10*ms) + 0.1*second**-.5*xi: 1')
    assert determine_stateupdater(eqs, variables) is euler

    eqs = Equations('dv/dt = -v / (10*ms) + v*0.1*second**-.5*xi: 1')
    assert determine_stateupdater(eqs, variables) is milstein

    # remove all registered state updaters --> automatic choice no longer works
    StateUpdateMethod.stateupdaters = {}
    assert_raises(ValueError, lambda: determine_stateupdater(eqs, variables))

    # reset to state before the test
    StateUpdateMethod.stateupdaters = before
Example #53
0
def test_wrong_indexing():
    G = NeuronGroup(10, 'v:1')
    assert_raises(TypeError, lambda: G['string'])

    assert_raises(IndexError, lambda: G[10])
    assert_raises(IndexError, lambda: G[10:])
    assert_raises(IndexError, lambda: G[::2])
    assert_raises(IndexError, lambda: G[3:2])
    assert_raises(IndexError, lambda: G[[5, 4, 3]])
    assert_raises(IndexError, lambda: G[[2, 4, 6]])
    assert_raises(IndexError, lambda: G[[-1, 0, 1]])
    assert_raises(IndexError, lambda: G[[9, 10, 11]])
    assert_raises(IndexError, lambda: G[[9, 10]])
    assert_raises(IndexError, lambda: G[[10, 11]])
    assert_raises(TypeError, lambda: G[[2.5, 3.5, 4.5]])
Example #54
0
def test_wrong_indexing():
    G = NeuronGroup(10, 'v:1')
    assert_raises(TypeError, lambda: G[0])
    assert_raises(TypeError, lambda: G[[0, 1]])
    assert_raises(TypeError, lambda: G['string'])

    assert_raises(IndexError, lambda: G[10:])
    assert_raises(IndexError, lambda: G[::2])
    assert_raises(IndexError, lambda: G[3:2])
Example #55
0
def test_rate_monitor_smoothed_rate_incorrect():
    # Test the filter response by having a single spiking neuron
    G = SpikeGeneratorGroup(1, [0], [1]*ms)
    r_mon = PopulationRateMonitor(G)
    run(2*ms)

    assert_raises(TypeError, lambda: r_mon.smooth_rate(window='flat'))  # no width
    assert_raises(TypeError, lambda: r_mon.smooth_rate(window=np.ones(5), width=1*ms))
    assert_raises(NotImplementedError, lambda: r_mon.smooth_rate(window='unknown', width=1*ms))
    assert_raises(TypeError, lambda: r_mon.smooth_rate(window=object()))
    assert_raises(TypeError, lambda: r_mon.smooth_rate(window=np.ones(5, 2)))
    assert_raises(TypeError, lambda: r_mon.smooth_rate(window=np.ones(4)))  # even number
Example #56
0
def test_scalar_parameter_access():
    for codeobj_class in codeobj_classes:
        G = NeuronGroup(10, '''dv/dt = freq : 1
                               freq : Hz (shared)
                               number : 1 (shared)
                               array : 1''',
                        codeobj_class=codeobj_class)

        # Try setting a scalar variable
        G.freq = 100*Hz
        assert_equal(G.freq[:], 100*Hz)
        G.freq[:] = 200*Hz
        assert_equal(G.freq[:], 200*Hz)
        G.freq = 'freq - 50*Hz + number*Hz'
        assert_equal(G.freq[:], 150*Hz)
        G.freq[:] = '50*Hz'
        assert_equal(G.freq[:], 50*Hz)

        # Check the second method of accessing that works
        assert_equal(np.asanyarray(G.freq), 50*Hz)

        # Check error messages
        assert_raises(IndexError, lambda: G.freq[0])
        assert_raises(IndexError, lambda: G.freq[1])
        assert_raises(IndexError, lambda: G.freq[0:1])
        assert_raises(IndexError, lambda: G.freq['i>5'])

        assert_raises(ValueError, lambda: G.freq.set_item(slice(None), [0, 1]*Hz))
        assert_raises(IndexError, lambda: G.freq.set_item(0, 100*Hz))
        assert_raises(IndexError, lambda: G.freq.set_item(1, 100*Hz))
        assert_raises(IndexError, lambda: G.freq.set_item('i>5', 100*Hz))
Example #57
0
def test_state_variable_access_strings():
    for codeobj_class in codeobj_classes:
        G = NeuronGroup(10, 'v:volt', codeobj_class=codeobj_class)
        G.v = np.arange(10) * volt
        # Indexing with strings
        assert G.v['i==2'] == G.v[2]
        assert G.v_['i==2'] == G.v_[2]
        assert_equal(G.v['v >= 3*volt'], G.v[3:])
        assert_equal(G.v_['v >= 3*volt'], G.v_[3:])
        # Should also check for units
        assert_raises(DimensionMismatchError, lambda: G.v['v >= 3'])
        assert_raises(DimensionMismatchError, lambda: G.v['v >= 3*second'])

        # Setting with strings
        # --------------------
        # String value referring to i
        G.v = '2*i*volt'
        assert_equal(G.v[:], 2*np.arange(10)*volt)
        # String value referring to i
        G.v[:5] = '3*i*volt'
        assert_equal(G.v[:],
                     np.array([0, 3, 6, 9, 12, 10, 12, 14, 16, 18])*volt)

        G.v = np.arange(10) * volt
        # String value referring to a state variable
        G.v = '2*v'
        assert_equal(G.v[:], 2*np.arange(10)*volt)
        G.v[:5] = '2*v'
        assert_equal(G.v[:],
                     np.array([0, 4, 8, 12, 16, 10, 12, 14, 16, 18])*volt)

        G.v = np.arange(10) * volt
        # String value referring to state variables, i, and an external variable
        ext = 5*volt
        G.v = 'v + ext + (N + i)*volt'
        assert_equal(G.v[:], 2*np.arange(10)*volt + 15*volt)

        G.v = np.arange(10) * volt
        G.v[:5] = 'v + ext + (N + i)*volt'
        assert_equal(G.v[:],
                     np.array([15, 17, 19, 21, 23, 5, 6, 7, 8, 9])*volt)

        G.v = 'v + randn()*volt'  # only check that it doesn't raise an error
        G.v[:5] = 'v + randn()*volt'  # only check that it doesn't raise an error

        G.v = np.arange(10) * volt
        # String index using a random number
        G.v['rand() <= 1'] = 0*mV
        assert_equal(G.v[:], np.zeros(10)*volt)

        G.v = np.arange(10) * volt
        # String index referring to i and setting to a scalar value
        G.v['i>=5'] = 0*mV
        assert_equal(G.v[:], np.array([0, 1, 2, 3, 4, 0, 0, 0, 0, 0])*volt)
        # String index referring to a state variable
        G.v['v<3*volt'] = 0*mV
        assert_equal(G.v[:], np.array([0, 0, 0, 3, 4, 0, 0, 0, 0, 0])*volt)
        # String index referring to state variables, i, and an external variable
        ext = 2*volt
        G.v['v>=ext and i==(N-6)'] = 0*mV
        assert_equal(G.v[:], np.array([0, 0, 0, 3, 0, 0, 0, 0, 0, 0])*volt)

        G.v = np.arange(10) * volt
        # Strings for both condition and values
        G.v['i>=5'] = 'v*2'
        assert_equal(G.v[:], np.array([0, 1, 2, 3, 4, 10, 12, 14, 16, 18])*volt)
        G.v['v>=5*volt'] = 'i*volt'
        assert_equal(G.v[:], np.arange(10)*volt)
Example #58
0
def test_array_cache():
    # Check that variables are only accessible from Python when they should be
    set_device('cpp_standalone', build_on_run=False)
    G = NeuronGroup(10, '''dv/dt = -v / (10*ms) : 1
                           w : 1
                           x : 1
                           y : 1
                           z : 1 (shared)''',
                    threshold='v>1')
    S = Synapses(G, G, 'weight: 1', on_pre='w += weight')
    S.connect(p=0.2)
    S.weight = 7
    # All neurongroup values should be known
    assert_allclose(G.v, 0)
    assert_allclose(G.w, 0)
    assert_allclose(G.x, 0)
    assert_allclose(G.y, 0)
    assert_allclose(G.z, 0)
    assert_allclose(G.i, np.arange(10))

    # But the synaptic variable is not -- we don't know the number of synapses
    assert_raises(NotImplementedError, lambda: S.weight[:])

    # Setting variables with explicit values should not change anything
    G.v = np.arange(10)+1
    G.w = 2
    G.y = 5
    G.z = 7
    assert_allclose(G.v, np.arange(10)+1)
    assert_allclose(G.w, 2)
    assert_allclose(G.y, 5)
    assert_allclose(G.z, 7)

    # But setting with code should invalidate them
    G.x = 'i*2'
    assert_raises(NotImplementedError, lambda: G.x[:])

    # Make sure that the array cache does not allow to use incorrectly sized
    # values to pass
    assert_raises(ValueError, lambda: setattr(G, 'w', [0, 2]))
    assert_raises(ValueError, lambda: G.w.__setitem__(slice(0, 4), [0, 2]))

    run(10*ms)
    # v is now no longer known without running the network
    assert_raises(NotImplementedError, lambda: G.v[:])
    # Neither is w, it is updated in the synapse
    assert_raises(NotImplementedError, lambda: G.w[:])
    # However, no code touches y or z
    assert_allclose(G.y, 5)
    assert_allclose(G.z, 7)
    # i is read-only anyway
    assert_allclose(G.i, np.arange(10))

    # After actually running the network, everything should be accessible
    device.build(directory=None, with_output=False)
    assert all(G.v > 0)
    assert all(G.w > 0)
    assert_allclose(G.x, np.arange(10)*2)
    assert_allclose(G.y, 5)
    assert_allclose(G.z, 7)
    assert_allclose(G.i, np.arange(10))
    assert_allclose(S.weight, 7)
Example #59
0
def test_state_variables():
    '''
    Test the setting and accessing of state variables.
    '''
    for codeobj_class in codeobj_classes:
        G = NeuronGroup(10, 'v : volt', codeobj_class=codeobj_class)

        # The variable N should be always present
        assert G.N == 10
        # But it should be read-only
        assert_raises(TypeError, lambda: G.__setattr__('N', 20))
        assert_raises(TypeError, lambda: G.__setattr__('N_', 20))

        G.v = -70*mV
        assert_raises(DimensionMismatchError, lambda: G.__setattr__('v', -70))
        G.v_ = float(-70*mV)
        assert_allclose(G.v[:], -70*mV)
        G.v = -70*mV + np.arange(10)*mV
        assert_allclose(G.v[:], -70*mV + np.arange(10)*mV)
        G.v = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] * volt
        assert_allclose(G.v[:], np.arange(10) * volt)
        # incorrect size
        assert_raises(ValueError, lambda: G.__setattr__('v', [0, 1]*volt))
        assert_raises(ValueError, lambda: G.__setattr__('v', np.arange(11)*volt))

        G.v = -70*mV
        # Numpy methods should be able to deal with state variables
        # (discarding units)
        assert_allclose(np.mean(G.v), float(-70*mV))
        # Getting the content should return a Quantity object which then natively
        # supports numpy functions that access a method
        assert_allclose(np.mean(G.v[:]), -70*mV)

        # You should also be able to set variables with a string
        G.v = '-70*mV + i*mV'
        assert_allclose(G.v[0], -70*mV)
        assert_allclose(G.v[9], -61*mV)
        assert_allclose(G.v[:], -70*mV + np.arange(10)*mV)

        # And it should raise an unit error if the units are incorrect
        assert_raises(DimensionMismatchError,
                      lambda: G.__setattr__('v', '70 + i'))
        assert_raises(DimensionMismatchError,
                      lambda: G.__setattr__('v', '70 + i*mV'))

        # Calculating with state variables should work too
        # With units
        assert all(G.v - G.v == 0)
        assert all(G.v - G.v[:] == 0*mV)
        assert all(G.v[:] - G.v == 0*mV)
        assert all(G.v + 70*mV == G.v[:] + 70*mV)
        assert all(70*mV + G.v == G.v[:] + 70*mV)
        assert all(G.v + G.v == 2*G.v)
        assert all(G.v / 2.0 == 0.5*G.v)
        assert all(1.0 / G.v == 1.0 / G.v[:])
        assert_equal((-G.v)[:], -G.v[:])
        assert_equal((+G.v)[:], G.v[:])
        #Without units
        assert all(G.v_ - G.v_ == 0)
        assert all(G.v_ - G.v_[:] == 0)
        assert all(G.v_[:] - G.v_ == 0)
        assert all(G.v_ + float(70*mV) == G.v_[:] + float(70*mV))
        assert all(float(70*mV) + G.v_ == G.v_[:] + float(70*mV))
        assert all(G.v_ + G.v_ == 2*G.v_)
        assert all(G.v_ / 2.0 == 0.5*G.v_)
        assert all(1.0 / G.v_ == 1.0 / G.v_[:])
        assert_equal((-G.v)[:], -G.v[:])
        assert_equal((+G.v)[:], G.v[:])

        # And in-place modification should work as well
        G.v += 10*mV
        G.v -= 10*mV
        G.v *= 2
        G.v /= 2.0

        # with unit checking
        assert_raises(DimensionMismatchError, lambda: G.v.__iadd__(3*second))
        assert_raises(DimensionMismatchError, lambda: G.v.__iadd__(3))
        assert_raises(DimensionMismatchError, lambda: G.v.__imul__(3*second))

        # in-place modification with strings should not work
        assert_raises(TypeError, lambda: G.v.__iadd__('string'))
        assert_raises(TypeError, lambda: G.v.__imul__('string'))
        assert_raises(TypeError, lambda: G.v.__idiv__('string'))
        assert_raises(TypeError, lambda: G.v.__isub__('string'))
Example #60
0
def test_clear_cache_numpy():
    if prefs.codegen.target != 'numpy':
        raise SkipTest('numpy-only test')
    assert 'numpy' not in _cache_dirs_and_extensions
    assert_raises(ValueError, clear_cache, 'numpy')