예제 #1
0
def _old_graph_tool(version_min):
    '''
    Check for old versions of graph-tool for which some functions are not
    working.
    '''
    return (nngt.get_config('backend') == 'graph-tool'
            and nngt.get_config('library').__version__[:4] < version_min)
예제 #2
0
def setup_module():
    ''' setup any state specific to the execution of the current module.'''
    with_plot = nngt.get_config("with_plot")
    with_nest = nngt.get_config("with_nest")

    nngt.set_config("with_plot", False)
    nngt.set_config("with_nest", False)
예제 #3
0
파일: test_basics.py 프로젝트: tfardet/NNGT
def test_config():
    '''
    Check get/set_config functions.
    '''
    old_cfg = nngt.get_config(detailed=True)

    # get config
    cfg = nngt.get_config()

    for k, v in cfg.items():
        assert v == nngt.get_config(k)

    cfg_detailed = nngt.get_config(detailed=True)

    for k, v in cfg_detailed.items():
        assert v == nngt.get_config(k)

    # set config (omp)
    num_omp = 2
    nngt.set_config("omp", num_omp)

    assert nngt.get_config("multithreading")
    assert nngt.get_config("omp") == num_omp

    # set config (mpi)
    has_mpi = False

    try:
        import mpi4py
        has_mpi = True
    except:
        pass

    if has_mpi:
        nngt.set_config("mpi", True)

        assert nngt.get_config("mpi")
        assert not nngt.get_config("multithreading")
        assert nngt.get_config("omp") == 1

    # key error
    key_error = False

    try:
        nngt.set_config("random_entry", "plop")
    except KeyError:
        key_error = True

    assert key_error

    # except for palettes
    nngt.set_config("palette_continuous", "viridis")
    nngt.set_config("palette_discrete", "Set2")

    # restore old config
    nngt.set_config(old_cfg)
예제 #4
0
파일: test_mpi.py 프로젝트: SBottani/NNGT
 def test_model_properties(self, graph, instructions, **kwargs):
     '''
     When generating graphs from on of the preconfigured models, check that
     the expected properties are indeed obtained.
     '''
     if nngt.get_config("backend") != "nngt" and nngt.on_master_process():
         graph_type = instructions["graph_type"]
         ref_result = self.theo_prop[graph_type](instructions)
         computed_result = self.exp_prop[graph_type](graph, instructions)
         if graph_type == 'distance_rule':
             # average degree
             self.assertTrue(
                 ref_result[0] == computed_result[0],
                 "Avg. deg. for graph {} failed:\nref = {} vs exp {}\
                 ".format(graph.name, ref_result[0], computed_result[0]))
             # average error on distance distribution
             sqd = np.square(
                 np.subtract(ref_result[1:], computed_result[1:]))
             avg_sqd = sqd / np.square(computed_result[1:])
             err = np.sqrt(avg_sqd).mean()
             tolerance = (self.tolerance
                          if instructions['rule'] == 'lin' else 0.25)
             self.assertTrue(
                 err <= tolerance,
                 "Distance distribution for graph {} failed:\nerr = {} > {}\
                 ".format(graph.name, err, tolerance))
     elif nngt.get_config("backend") == "nngt":
         from mpi4py import MPI
         comm = MPI.COMM_WORLD
         num_proc = comm.Get_size()
         graph_type = instructions["graph_type"]
         ref_result = self.theo_prop[graph_type](instructions)
         computed_result = self.exp_prop[graph_type](graph, instructions)
         if graph_type == 'distance_rule':
             # average degree
             self.assertTrue(
                 ref_result[0] == computed_result[0] * num_proc,
                 "Avg. deg. for graph {} failed:\nref = {} vs exp {}\
                 ".format(graph.name, ref_result[0], computed_result[0]))
             # average error on distance distribution
             sqd = np.square(
                 np.subtract(ref_result[1:], computed_result[1:]))
             avg_sqd = sqd / np.square(computed_result[1:])
             err = np.sqrt(avg_sqd).mean()
             tolerance = (self.tolerance
                          if instructions['rule'] == 'lin' else 0.25)
             self.assertTrue(
                 err <= tolerance,
                 "Distance distribution for graph {} failed:\nerr = {} > {}\
                 ".format(graph.name, err, tolerance))
예제 #5
0
파일: rng_tools.py 프로젝트: tfardet/NNGT
def seed(msd=None, seeds=None):
    '''
    Seed the random generator used by NNGT
    (i.e. the numpy `RandomState`: for details, see
    :class:`numpy.random.RandomState`).

    Parameters
    ----------
    msd : int, optional
        Master seed for numpy `RandomState`.
        Must be convertible to 32-bit unsigned integers.
    seeds : list of ints, optional
        Seeds for `RandomState` (when using MPI).
        Must be convertible to 32-bit unsigned integers, one entry per MPI
        process.
    '''
    # when using MPI numpy seeeds are sync-ed via the mpi_random decorator
    msd = np.random.randint(0, 2**31 - 1) if msd is None else msd

    # seed both random state and new generator
    np.random.seed(msd)
    nngt._rng = np.random.default_rng(msd)

    nngt._config['msd'] = msd

    nngt._seeded = True

    nngt._seeded_local = False

    # check subseeds
    if seeds is not None:
        with_mt = nngt.get_config('multithreading')
        with_mpi = nngt.get_config('mpi')
        err = 'Expected {} seeds.'

        if with_mpi:
            from mpi4py import MPI
            comm = MPI.COMM_WORLD
            size = comm.Get_size()
            assert size == len(seeds), err.format(size)
            nngt._config['seeds'] = seeds
        elif with_mt:
            num_omp = nngt.get_config('omp')
            assert num_omp == len(seeds), err.format(num_omp)
            nngt._config['seeds'] = seeds

        nngt._seeded_local = True
        nngt._used_local = False
예제 #6
0
파일: test_plots.py 프로젝트: tfardet/NNGT
def test_plot_prop():
    num_nodes = 50
    net = ng.erdos_renyi(nodes=num_nodes, avg_deg=5)

    net.set_weights(distribution="gaussian", parameters={"avg": 5, "std": 0.5})

    net.new_node_attribute("attr",
                           "int",
                           values=np.random.randint(-10, 20, num_nodes))

    nplt.degree_distribution(net, ["in", "out", "total"], show=False)

    nplt.edge_attributes_distribution(net, "weight", colors="g", show=False)

    nplt.node_attributes_distribution(net,
                                      "out-degree",
                                      colors="r",
                                      show=False)

    if nngt.get_config("backend") != "nngt":
        nplt.edge_attributes_distribution(net, ["betweenness", "weight"],
                                          colors=["g", "b"],
                                          axtitles=["Edge betw.", "Weights"],
                                          show=False)

        nplt.node_attributes_distribution(
            net, ["betweenness", "attr", "out-degree"],
            colors=["r", "g", "b"],
            show=False)
예제 #7
0
def seed(msd=None, seeds=None):
    '''
    Seed the random generator used by NNGT (i.e. the numpy `RandomState`: for
    details, see :class:`numpy.random.RandomState`).

    ..versionchanged:: 0.8
        Renamed `seed` to `msd`, added `seeds` for multithreading.

    Parameters
    ----------
    msd : int, optional
        Master seed for numpy `RandomState`.
        Must be convertible to 32-bit unsigned integers.
    seeds : array of ints, optional
        Seeds for  for `RandomState`.
        Must be convertible to 32-bit unsigned integers.
    '''
    if msd is None and nngt.get_config("mpi"):
        # when using MPI we need to sync the seeds
        msd_tmp = np.random.randint(0, 2**32 - 1)
        msd_tmp = nngt.get_config("mpi_comm").bcast(msd_tmp, root=0)
        np.random.seed(msd_tmp)
    else:
        np.random.seed(msd)

    if msd is None:
        nngt._config['msd'] = np.random.get_state()[1][0]
    else:
        nngt._config['msd'] = msd

    nngt._seeded = True

    # check subseeds
    if seeds is not None:
        with_mt = nngt.get_config('multithreading')
        with_mpi = nngt.get_config('mpi')
        err = 'Expected {} seeds.'
        if with_mpi:
            from mpi4py import MPI
            comm = MPI.COMM_WORLD
            size = comm.Get_size()
            assert size == len(seeds), err.format(size)
            nngt._config['seeds'] = seeds
        elif with_mt:
            num_omp = nngt.get_config('omp')
            assert num_omp == len(seeds), err.format(num_omp)
            nngt._config['seeds'] = seeds
예제 #8
0
class TestGraphClasses(TestBasis):
    '''
    Class testing the main methods of :class:`~nngt.Graph` and its subclasses.
    '''

    matrices = {}
    mat_gen = {
        "from_scipy_sparse_rand": ssp.rand,
        "from_numpy_randint": np.random.randint
    }

    @property
    def test_name(self):
        return "test_graphclasses"

    @unittest.skipIf(nngt.get_config('mpi'), 'Not checking for MPI')
    def gen_graph(self, graph_name):
        di_instructions = self.parser.get_graph_options(graph_name)
        mat = self.mat_gen[graph_name](**di_instructions)
        self.matrices[graph_name] = mat
        graph = nngt.Graph.from_matrix(mat)
        graph.set_name(graph_name)
        return graph, di_instructions

    @foreach_graph
    def test_adj_mat(self, graph, **kwargs):
        '''
        When generating graphs from :class:`numpy.ndarray`s or
        :class:`scipy.sparse` matrices, check that the result of
        graph.adjacency_matrix() is the same as the initial matrix.
        '''
        ref_result = ssp.csr_matrix(self.matrices[graph.get_name()])
        computed_result = graph.adjacency_matrix()
        self.assertTrue((ref_result != computed_result).nnz == 0,
                        "AdjMat test failed for graph {}:\nref = {} vs exp {}\
            ".format(graph.name, ref_result, computed_result))

    @foreach_graph
    @unittest.skipIf(
        nngt._config["backend"] == "graph-tool"
        and nngt._config["library"].__version__.startswith("2.22"),
        "Known bug with graph-tool 2.22.")
    def test_copy_clear(self, graph, **kwargs):
        '''
        Test that the copied graph is indeed the same as the original, but that
        all its properties are deep copies.
        Then check that clear_edges() removes all edges and no nodes.
        '''
        ref_result = (graph.node_nb(), graph.edge_nb(), graph.node_nb(), 0)
        copied = graph.copy()
        self.assertIsNot(copied, graph)
        computed_result = [copied.node_nb(), copied.edge_nb()]
        copied.clear_all_edges()
        computed_result.extend((copied.node_nb(), copied.edge_nb()))
        self.assertEqual(
            ref_result, tuple(computed_result),
            "Copy test failed for graph {}:\nref = {} vs exp {}\
            ".format(graph.name, ref_result, computed_result))
예제 #9
0
 def wrapper(*args, **kwargs):
     self = args[0]
     nx = nngt.get_config("graph_library") == "networkx"
     for graph_name in self.graphs:
         if nx and "corr" in graph_name:
             print("Skipping correlated attributes with networkx")
         else:
             g, di = self.gen_graph(graph_name)
             func(self, g, instructions=di, **kwargs)
예제 #10
0
def _mpi_and_random_init():
    '''
    Init MPI comm and information and seed the 
    '''
    comm = MPI.COMM_WORLD
    size = comm.Get_size()
    rank = comm.Get_rank()
    # Random number generation seeding
    if rank == 0:
        msd = nngt.get_config('msd')
    else:
        msd = None
    msd = comm.bcast(msd, root=0)
    seeds = nngt.get_config('seeds')
    seed = seeds[rank] if seeds is not None else msd + rank + 1
    np.random.seed(seed)

    return comm, size, rank
예제 #11
0
def test_connect_switch_distance_rule_max_proba():
    num_omp = nngt.get_config("omp")
    mthread = nngt.get_config("multithreading")

    # switch multithreading to False
    nngt.set_config("multithreading", False)

    pop = nngt.NeuralPop.exc_and_inhib(1000)

    radius = 100.

    shape = nngt.geometry.Shape.disk(radius)

    net = nngt.SpatialNetwork(population=pop, shape=shape)

    max_proba = 0.1

    avg, std = 10., 1.5

    weights = {"distribution": "gaussian", "avg": avg, "std": std}

    ng.connect_nodes(net,
                     pop.inhibitory,
                     pop.excitatory,
                     "distance_rule",
                     scale=5 * radius,
                     max_proba=max_proba,
                     weights=weights)

    assert net.edge_nb() <= len(pop.inhibitory) * len(
        pop.excitatory) * max_proba

    # check weights
    ww = net.get_weights()

    assert avg - 0.5 * std < ww.mean() < avg + 0.5 * std
    assert 0.75 * std < ww.std() < 1.25 * std

    # restore mt parameters
    nngt.set_config("mpi", False)
    nngt.set_config("omp", num_omp)
    nngt.set_config("multithreading", mthread)
예제 #12
0
파일: test_io.py 프로젝트: tfardet/NNGT
def teardown_function(function):
    ''' Cleanup the file '''
    if nngt.get_config("mpi"):
        from mpi4py import MPI
        comm = MPI.COMM_WORLD.Clone()

        comm.Barrier()

    try:
        os.remove(gfilename)
    except:
        pass
예제 #13
0
def _library_load(filename, fmt):
    ''' Load the file using the library functions '''
    if nngt.get_config("backend") == "networkx":
        import networkx as nx

        if fmt == "graphml":
            return nx.read_graphml(filename)
        else:
            raise NotImplementedError
    elif nngt.get_config("backend") == "igraph":
        import igraph as ig

        if fmt == "graphml":
            return ig.Graph.Read_GraphML(filename)
        else:
            raise NotImplementedError
    elif nngt.get_config("backend") == "graph-tool":
        import graph_tool as gt

        return gt.load_graph(filename, fmt=fmt)
    else:
        raise NotImplementedError
예제 #14
0
 def wrapper(*args, **kwargs):
     self = args[0]
     partial_backend = nngt.get_config("backend") in ("networkx", "nngt")
     for graph_name in self.graphs:
         if partial_backend and "corr" in graph_name:
             _log_message(logger, "DEBUG",
                          "Skipping correlated attributes with "
                          "networkx and nngt backends.")
         else:
             generated = self.gen_graph(graph_name)
             # check for None when using MPI
             if generated is not None:
                 g, di = generated
                 func(self, g, instructions=di, **kwargs)
예제 #15
0
파일: mpi_connect.py 프로젝트: tfardet/NNGT
def _mpi_and_random_init():
    '''
    Init MPI comm and information and seed the RNGs
    '''
    comm = MPI.COMM_WORLD.Clone()
    size = comm.Get_size()
    rank = comm.Get_rank()

    # Random number generation seeding
    seeds = None

    if not nngt._seeded_local:
        # no local seeds were generated, set them from initial msd
        msd = nngt.get_config("msd")
        seeds = [msd + i + 1 for i in range(size)]
        nngt._config['seeds'] = seeds
    elif not nngt._used_local:
        # local seeds were generated but not used, use them
        seeds = nngt.get_config('seeds')
    else:
        # local seeds were generated and used, generate new ones from new msd
        if rank == 0:
            msd = np.random.randint(0, 2**31 - size - 1)
        else:
            msd = None

        msd = comm.bcast(msd, root=0)
        seeds = [msd + i + 1 for i in range(size)]

    seed = seeds[rank]
    np.random.seed(seed)

    nngt._seeded_local = True
    nngt._used_local = True

    return comm, size, rank
예제 #16
0
파일: test_random.py 프로젝트: tfardet/NNGT
def test_random_unseeded():
    num_seeds = get_num_seeds()

    nngt.seed(msd=42)

    # check that seeds generated by first call indeed allow to reproduce the
    # graph in later calls
    g1 = ng.gaussian_degree(10, 1, nodes=100)

    seeds = nngt.get_config("seeds")

    nngt.seed(msd=42, seeds=seeds)
    g2 = ng.gaussian_degree(10, 1, nodes=100)

    assert np.all(g1.edges_array == g2.edges_array)
예제 #17
0
def _set_main_db():
    if nngt.get_config("db_url") is None or nngt.get_config("db_to_file"):
        # check for db_folder
        abs_dbfolder = os.path.abspath(
            os.path.expanduser(nngt.get_config("db_folder")))
        if not os.path.isdir(abs_dbfolder):
            try:
                os.mkdir(abs_dbfolder)
            except OSError as e:
                if e.errno != errno.EEXIST:
                    raise

        # create database
        db_file = abs_dbfolder + "/" + nngt.get_config("db_name") + ".db"

        nngt._main_db = SqliteDatabase(db_file,
                                       pragmas=(
                                           ('journal_mode', 'wal'),
                                           ('cache_size', -1024 * 64),
                                           ('foreign_keys', 'on'),
                                       ))
    else:
        nngt._main_db = connect(nngt.get_config('db_url'),
                                fields={'longblob': 'longblob'})
예제 #18
0
def test_group_vs_type():
    ''' Gaussian degree with groups and types '''
    # first with groups
    nngt.seed(0)

    pop = nngt.NeuralPop.exc_and_inhib(1000)

    igroup = pop["inhibitory"]
    egroup = pop["excitatory"]

    net1 = nngt.Network(population=pop)

    all_groups = list(pop.keys())  # necessary to have same order as types

    avg_e = 50
    std_e = 5
    ng.connect_groups(net1, egroup, all_groups, graph_model="gaussian_degree",
                      avg=avg_e, std=std_e, degree_type="out-degree")

    avg_i = 100
    std_i = 5
    ng.connect_groups(net1, igroup, all_groups, graph_model="gaussian_degree",
                      avg=avg_i, std=std_i, degree_type="out-degree")

    # then with types
    nngt.seed(0)

    pop = nngt.NeuralPop.exc_and_inhib(1000)

    igroup = pop["inhibitory"]
    egroup = pop["excitatory"]

    net2 = nngt.Network(population=pop)

    avg_e = 50
    std_e = 5
    ng.connect_neural_types(net2, 1, [-1, 1], graph_model="gaussian_degree",
                            avg=avg_e, std=std_e, degree_type="out-degree")

    avg_i = 100
    std_i = 5
    ng.connect_neural_types(net2, -1, [-1, 1], graph_model="gaussian_degree",
                            avg=avg_i, std=std_i, degree_type="out-degree")

    # call only on root process (for mpi) unless using distributed backend
    if nngt.on_master_process() or nngt.get_config("backend") == "nngt":
        # check that both networks are equals
        assert np.all(net1.get_degrees() == net2.get_degrees())
예제 #19
0
 def wrapper(*args, **kwargs):
     # when using MPI, make sure everyone waits for the others
     try:
         from mpi4py import MPI
         comm = MPI.COMM_WORLD
         comm.Barrier()
     except ImportError:
         pass
     # check backend ("nngt" is fully parallel, not the others)
     backend = False
     if not logging:
         backend = nngt.get_config("backend") == "nngt"
     if backend or on_master_process():
         return func(*args, **kwargs)
     else:
         return None
예제 #20
0
class TestBasics(unittest.TestCase):
    '''
    Class testing the basic methods of the Graph object.
    '''

    tolerance = 1e-6

    @property
    def test_name(self):
        return "test_basics"

    @unittest.skipIf(nngt.get_config('mpi'), 'Not checking for MPI')
    def test_node_creation(self):
        '''
        When making graphs, test node creation function.
        '''
        g = nngt.Graph(100, name="new_node_test")
        self.assertTrue(
            g.node_nb() == 100,
            '''Error on graph {}: invalid initial nodes ({} vs {} expected).
            '''.format(g.name, g.node_nb(), 100))
        n = g.new_node()
        self.assertTrue(
            g.node_nb() == 101 and n == 100,
            '''Error on graph {}: ({}, {}) vs (101, 100) expected.
            '''.format(g.name, g.node_nb(), n))
        nn = g.new_node(2)
        self.assertTrue(
            g.node_nb() == 103 and nn[0] == 101 and nn[1] == 102,
            '''Error on graph {}: ({}, {}, {}) vs (103, 101, 102) expected.
            '''.format(g.name, g.node_nb(), nn[0], nn[1]))

    def test_new_node_attr(self):
        '''
        Test node creation with attributes.
        '''
        shape = nngt.geometry.Shape.rectangle(1000., 1000.)
        g = nngt.SpatialGraph(100, shape=shape, name="new_node_spatial")
        self.assertTrue(
            g.node_nb() == 100,
            '''Error on graph {}: invalid initial nodes ({} vs {} expected).
            '''.format(g.name, g.node_nb(), 100))
        n = g.new_node(positions=[(0, 0)])
        self.assertTrue(
            np.all(np.isclose(g.get_positions(n), (0, 0), self.tolerance)),
            '''Error on graph {}: last position is ({}, {}) vs (0, 0) expected.
            '''.format(g.name, *g.get_positions(n)))
예제 #21
0
파일: gt_graph.py 프로젝트: SBottani/NNGT
 def edges_array(self):
     '''
     Edges of the graph, sorted by order of creation, as an array of
     2-tuple.
     '''
     # this dirty check is necessary to work with old versions of graph-tool
     gt = nngt.get_config('library')
     gt_major_version = int(gt.__version__[0])
     gt_minor_version = int(gt.__version__[2:4])
     edges = None
     if gt_major_version == 2 and gt_minor_version < 22:
         return np.array(
             [(int(e.source()), int(e.target())) for e in self.edges()])
     else:
         edges = self.get_edges()
         order = np.argsort(edges[:, 2])
         return edges[order, :2]
예제 #22
0
파일: test_plots.py 프로젝트: tfardet/NNGT
def test_library_plot():
    ''' Check that plotting with the underlying backend library works '''
    pop = nngt.NeuralPop.exc_and_inhib(50)
    g = ng.newman_watts(4, 0.2, population=pop)

    g.set_weights(np.random.uniform(1, 5, g.edge_nb()))

    nplt.library_draw(g, show=False)

    nplt.library_draw(g, ncolor="total-degree", ecolor="k", show=False)

    if nngt.get_config("backend") != "nngt":
        nplt.library_draw(g,
                          ncolor="in-degree",
                          ecolor="betweenness",
                          esize='weight',
                          max_esize=5,
                          show=False)

    nplt.library_draw(g,
                      nshape="s",
                      esize="weight",
                      layout="random",
                      show=False)

    nplt.library_draw(g,
                      nshape="s",
                      esize="weight",
                      layout="random",
                      show=False)

    nplt.library_draw(g,
                      ncolor="in-degree",
                      esize="weight",
                      layout="circular",
                      show=False)

    edges = g.edges_array[::5]

    nplt.library_draw(g,
                      ncolor="in-degree",
                      esize="weight",
                      layout="circular",
                      restrict_edges=edges,
                      show=False)
예제 #23
0
파일: test_random.py 프로젝트: tfardet/NNGT
def test_random_seeded():
    num_seeds = get_num_seeds()

    # test equality of graph generated with same seeds
    nngt.seed(msd=0, seeds=[i for i in range(1, num_seeds + 1)])
    g1 = ng.gaussian_degree(10, 1, nodes=100)

    nngt.seed(msd=0, seeds=[i for i in range(1, num_seeds + 1)])
    g2 = ng.gaussian_degree(10, 1, nodes=100)

    assert np.all(g1.edges_array == g2.edges_array)

    # check that subsequent graphs are different
    g3 = ng.gaussian_degree(10, 1, nodes=100)

    # with mpi onnon-distributed backends, test only on master process
    if nngt.get_config("backend") == "nngt" or nngt.on_master_process():
        if g3.edge_nb() == g2.edge_nb():
            assert np.any(g2.edges_array != g3.edges_array)
예제 #24
0
class TestExamples(unittest.TestCase):
    '''
    Class testing saving and loading functions.
    '''

    example_files = [
        example_dir + f for f in os.listdir(example_dir)
        if isfile(join(example_dir, f))
    ]

    @classmethod
    def tearDownClass(cls):
        try:
            os.remove("sp_graph.el")
        except:
            pass

    @property
    def test_name(self):
        return "test_examples"

    @unittest.skipIf(int(environ.get("OMP", 1)) == 1, 'Check only with OMP')
    @unittest.skipIf(nngt.get_config('mpi'), 'Not checking for MPI')
    def test_examples(self):
        '''
        Test that the example files execute correctly.
        '''
        for example in self.example_files:
            if example.endswith('.py'):
                try:
                    try:
                        execfile(example)
                    except NameError:  # python 3+
                        with open(example) as f:
                            code = compile(f.read(), example, 'exec')
                            exec(code, glob)
                except NotImplementedError:
                    pass  # potential IO error for gt <= 2.22
예제 #25
0
pop = nngt.NeuralPop.exc_and_inhib(num_neurons,
                                   en_model=neuron_model,
                                   in_model=neuron_model,
                                   syn_spec=synapses)

# create the network and send it to NEST
w_prop = {"distribution": "gaussian", "avg": 0.1, "std": .05}
net = nngt.generation.gaussian_degree(avg_degree,
                                      std_degree,
                                      population=pop,
                                      weights=w_prop)
'''
Send to NEST and set excitation and recorders
'''
if nngt.get_config('with_nest'):
    import nest
    import nngt.simulation as ns

    nest.ResetKernel()

    gids = net.to_nest()

    # add noise to the excitatory neurons
    excs = list(pop["excitatory"].nest_gids)
    ns.set_noise(excs, 10., 2.)

    # record
    groups = [key for key in net.population]
    recorder, record = ns.monitor_groups(groups, net)
    '''
예제 #26
0
        nngt._config["backend"] == "graph-tool"
        and nngt._config["library"].__version__.startswith("2.22"),
        "Known bug with graph-tool 2.22.")
    def test_copy_clear(self, graph, **kwargs):
        '''
        Test that the copied graph is indeed the same as the original, but that
        all its properties are deep copies.
        Then check that clear_edges() removes all edges and no nodes.
        '''
        ref_result = (graph.node_nb(), graph.edge_nb(), graph.node_nb(), 0)
        copied = graph.copy()
        self.assertIsNot(copied, graph)
        computed_result = [copied.node_nb(), copied.edge_nb()]
        copied.clear_all_edges()
        computed_result.extend((copied.node_nb(), copied.edge_nb()))
        self.assertEqual(
            ref_result, tuple(computed_result),
            "Copy test failed for graph {}:\nref = {} vs exp {}\
            ".format(graph.name, ref_result, computed_result))


# ---------- #
# Test suite #
# ---------- #

if not nngt.get_config('mpi'):
    suite = unittest.TestLoader().loadTestsFromTestCase(TestGraphClasses)

    if __name__ == "__main__":
        unittest.main()
예제 #27
0
def _gaussian_degree(source_ids,
                     target_ids,
                     avg=-1,
                     std=-1,
                     degree_type="in",
                     reciprocity=-1,
                     directed=True,
                     multigraph=False,
                     existing_edges=None,
                     **kwargs):
    ''' Connect nodes with a Gaussian distribution '''
    # mpi-related stuff
    comm, size, rank = _mpi_and_random_init()
    # switch values to float
    avg = float(avg)
    std = float(std)
    assert avg >= 0, "A positive value is required for `avg`."
    assert std >= 0, "A positive value is required for `std`."

    # use only local sources
    if degree_type == "in":
        source_ids = np.array(source_ids, dtype=int)
        target_ids = np.array(target_ids, dtype=int)[rank::size]
    else:
        source_ids = np.array(source_ids, dtype=int)[rank::size]
        target_ids = np.array(target_ids, dtype=int)
    num_source, num_target = len(source_ids), len(target_ids)
    # type of degree
    b_out = (degree_type == "out")
    b_total = (degree_type == "total")
    # compute the local number of edges
    num_degrees = num_target if degree_type == "in" else num_source
    lst_deg = np.around(np.maximum(np.random.normal(avg, std, num_degrees),
                                   0.)).astype(int)
    edges = np.sum(lst_deg)
    b_one_pop = _check_num_edges(source_ids, target_ids, edges, directed,
                                 multigraph)

    num_etotal = 0
    ia_edges = np.zeros((edges, 2), dtype=int)
    idx = 0 if b_out else 1  # differenciate source / target
    variables = targets_id if b_out else source_ids  # nodes picked randomly
    max_degree = np.inf if multigraph else len(variables)

    for i, v in enumerate(target_ids):
        degree_i = lst_deg[i]
        edges_i, ecurrent, variables_i = np.zeros((degree_i, 2)), 0, []
        if existing_edges is not None:
            with_v = np.where(existing_edges[:, idx] == v)
            variables_i.extend(existing_edges[with_v:int(not idx)])
            degree_i += len(variables_i)
            assert degree_i < max_degree, "Required degree is greater that " +\
                "maximum possible degree {}.".format(max_degree)
        rm = np.argwhere(variables == v)[0]
        rm = rm[0] if len(rm) else -1
        var_tmp = (np.array(variables, copy=True) if rm == -1 else
                   np.concatenate((variables[:rm], variables[rm + 1:])))
        num_var_i = len(var_tmp)
        ia_edges[num_etotal:num_etotal + degree_i, idx] = v
        while len(variables_i) != degree_i:
            var = var_tmp[randint(0, num_var_i, degree_i - ecurrent)]
            variables_i.extend(var)
            if not multigraph:
                variables_i = list(set(variables_i))
            ecurrent = len(variables_i)
        ia_edges[num_etotal:num_etotal + ecurrent, int(not idx)] = variables_i
        num_etotal += ecurrent

    comm.Barrier()

    _finalize_random(rank)

    # the 'nngt' backend is made to be distributed, but the others are not
    if nngt.get_config("backend") == "nngt":
        return ia_edges
    else:
        # all the data is gather on the root processus
        ia_edges = comm.gather(ia_edges, root=0)
        if rank == 0:
            ia_edges = np.concatenate(ia_edges, axis=0)
            return ia_edges
        else:
            return None
예제 #28
0
def _distance_rule(source_ids,
                   target_ids,
                   density=-1,
                   edges=-1,
                   avg_deg=-1,
                   scale=-1,
                   rule="exp",
                   max_proba=-1.,
                   shape=None,
                   positions=None,
                   directed=True,
                   multigraph=False,
                   distance=None,
                   **kwargs):
    '''
    Returns a distance-rule graph
    '''
    assert max_proba <= 0, "MPI distance_rule cannot use `max_proba` yet."
    distance = [] if distance is None else distance
    distance_tmp = []
    edges_hash = {}
    # mpi-related stuff
    comm, size, rank = _mpi_and_random_init()

    # compute the required values
    source_ids = np.array(source_ids).astype(int)
    target_ids = np.array(target_ids).astype(int)
    num_source, num_target = len(source_ids), len(target_ids)
    num_edges, _ = _compute_connections(num_source,
                                        num_target,
                                        density,
                                        edges,
                                        avg_deg,
                                        directed,
                                        reciprocity=-1)
    b_one_pop = _check_num_edges(source_ids, target_ids, num_edges, directed,
                                 multigraph)
    num_neurons = len(set(np.concatenate((source_ids, target_ids))))

    # for each node, check the neighbours that are in an area where
    # connections can be made: ± scale for lin, ± 10*scale for exp.
    # Get the sources and associated targets for each MPI process
    sources = []
    targets = []
    lim = scale if rule == 'lin' else 10 * scale
    for s in source_ids[rank::size]:
        keep = (np.abs(positions[0, target_ids] - positions[0, s]) < lim)
        keep *= (np.abs(positions[1, target_ids] - positions[1, s]) < lim)
        if b_one_pop:
            keep[s] = 0
        sources.append(s)
        targets.append(target_ids[keep])

    # the number of trials should be done depending on total number of
    # neighbours available, so we compute this number
    local_neighbours = 0

    for tgt_list in targets:
        local_neighbours += len(tgt_list)

    tot_neighbours = comm.gather(local_neighbours, root=0)
    if rank == 0:
        final_tot = np.sum(tot_neighbours)
        assert final_tot > num_edges, \
            "Scale is too small: there are not enough close neighbours to " +\
            "create the required number of connections. Increase `scale` " +\
            "or `neuron_density`."
    else:
        final_tot = None
    final_tot = comm.bcast(final_tot, root=0)

    neigh_norm = 1. / final_tot

    # try to create edges until num_edges is attained
    if rank == 0:
        ia_edges = np.zeros((num_edges, 2), dtype=int)
    else:
        ia_edges = None
    num_ecurrent = 0

    while num_ecurrent < num_edges:
        trials = []
        for tgt_list in targets:
            trials.append(
                max(
                    int(
                        len(tgt_list) * (num_edges - num_ecurrent) *
                        neigh_norm), 1))
        # try to create edges
        edges_tmp = [[], []]
        dist_local = []
        total_trials = int(np.sum(trials))
        local_sources = np.repeat(sources, trials)
        local_targets = np.zeros(total_trials, dtype=int)
        current_pos = 0
        for tgts, num_try in zip(targets, trials):
            t = np.random.randint(0, len(tgts), num_try)
            local_targets[current_pos:current_pos + num_try] = tgts[t]
            current_pos += num_try
        test = dist_rule(rule,
                         scale,
                         positions[:, local_sources],
                         positions[:, local_targets],
                         dist=dist_local)
        test = np.greater(test, np.random.uniform(size=total_trials))
        edges_tmp[0].extend(local_sources[test])
        edges_tmp[1].extend(local_targets[test])
        dist_local = np.array(dist_local)[test]

        comm.Barrier()

        # gather the result in root and assess the current number of edges
        edges_tmp = comm.gather(edges_tmp, root=0)
        dist_local = comm.gather(dist_local, root=0)

        if rank == 0:
            edges_tmp = np.concatenate(edges_tmp, axis=1).T
            dist_local = np.concatenate(dist_local)

            # if we're at the end, we'll make too many edges, so we keep only
            # the necessary fraction that we pick randomly
            num_desired = num_edges - num_ecurrent
            if num_desired < len(edges_tmp):
                chosen = {}
                while len(chosen) != num_desired:
                    idx = np.random.randint(0, len(edges_tmp),
                                            num_desired - len(chosen))
                    for i in idx:
                        chosen[i] = None
                edges_tmp = edges_tmp[list(chosen.keys())]
                dist_local = np.array(dist_local)[list(chosen.keys())]

            ia_edges, num_ecurrent = _filter(ia_edges,
                                             edges_tmp,
                                             num_ecurrent,
                                             edges_hash,
                                             b_one_pop,
                                             multigraph,
                                             distance=distance_tmp,
                                             dist_tmp=dist_local)

        num_ecurrent = comm.bcast(num_ecurrent, root=0)

        comm.Barrier()

    _finalize_random(rank)

    # the 'nngt' backend is made to be distributed, but the others are not
    if nngt.get_config("backend") == "nngt":
        local_edges = None
        if rank == 0:
            local_edges = [ia_edges[i::size, :] for i in range(size)]
            distance_tmp = [distance_tmp[i::size] for i in range(size)]
        local_edges = comm.scatter(local_edges, root=0)
        distance_tmp = comm.scatter(distance_tmp, root=0)
        distance.extend(distance_tmp)
        return local_edges
    else:
        # all the data is gather on the root processus
        if rank == 0:
            distance.extend(distance_tmp)
            return ia_edges
        else:
            return None
예제 #29
0
def connect_nodes(network,
                  sources,
                  targets,
                  graph_model,
                  density=None,
                  edges=None,
                  avg_deg=None,
                  unit='um',
                  weighted=True,
                  directed=True,
                  multigraph=False,
                  check_existing=True,
                  ignore_invalid=False,
                  **kwargs):
    '''
    Function to connect nodes with a given graph model.

    .. versionchanged:: 2.0
        Added `check_existing` and `ignore_invalid` arguments.

    Parameters
    ----------
    network : :class:`Network` or :class:`SpatialNetwork`
        The network to connect.
    sources : list
        Ids of the source nodes.
    targets : list
        Ids of the target nodes.
    graph_model : string
        The name of the connectivity model (among "erdos_renyi",
        "random_scale_free", "price_scale_free", and "newman_watts").
    check_existing : bool, optional (default: True)
        Check whether some of the edges that will be added already exist in the
        graph.
    ignore_invalid : bool, optional (default: False)
        Ignore invalid edges: they are not added to the graph and are
        silently dropped. Unless this is set to true, an error is raised
        if an existing edge is re-generated.
    **kwargs : keyword arguments
        Specific model parameters. or edge attributes specifiers such as
        `weights` or `delays`.

    Note
    ----
    For graph generation methods which set the properties of a
    specific degree (e.g. :func:`~nngt.generation.gaussian_degree`), the
    nodes which have their property sets are the `sources`.
    '''
    if network.is_spatial() and 'positions' not in kwargs:
        kwargs['positions'] = network.get_positions().astype(np.float32).T
    if network.is_spatial() and 'shape' not in kwargs:
        kwargs['shape'] = network.shape

    if graph_model in _one_pop_models:
        assert np.array_equal(sources, targets), \
            "'" + graph_model + "' can only work on a single set of nodes."

    sources = np.array(sources, dtype=np.uint)
    targets = np.array(targets, dtype=np.uint)
    distance = []

    elist = _di_gen_edges[graph_model](sources,
                                       targets,
                                       density=density,
                                       edges=edges,
                                       avg_deg=avg_deg,
                                       weighted=weighted,
                                       directed=directed,
                                       multigraph=multigraph,
                                       distance=distance,
                                       **kwargs)

    # Attributes are not set by subfunctions
    attr = {}

    if 'weights' in kwargs:
        ww = kwargs['weights']

        if isinstance(ww, dict):
            attr['weight'] = _generate_random(len(elist), ww)
        elif nonstring_container(ww):
            attr['weight'] = ww
        else:
            attr['weight'] = np.full(len(elist), ww)

    if 'delays' in kwargs:
        dd = kwargs['delays']

        if isinstance(ww, dict):
            attr['delay'] = _generate_random(len(elist), dd)
        elif nonstring_container(dd):
            attr['weight'] = dd
        else:
            attr['weight'] = np.full(len(elist), dd)

    if network.is_spatial() and distance:
        attr['distance'] = distance

    # call only on root process (for mpi) unless using distributed backend
    if nngt.on_master_process() or nngt.get_config("backend") == "nngt":
        elist = network.new_edges(elist,
                                  attributes=attr,
                                  check_duplicates=False,
                                  check_self_loops=False,
                                  check_existing=check_existing,
                                  ignore_invalid=ignore_invalid)

    if not network._graph_type.endswith('_connect'):
        network._graph_type += "_nodes_connect"

    return elist
예제 #30
0
# intra-groups (Newman-Watts)
prop_nw = {
    "coord_nb": 20,
    "proba_shortcut": 0.1
}

ng.connect_neural_groups(net, "left", "left", "newman_watts", **prop_nw)
ng.connect_neural_groups(net, "right", "right", "newman_watts", **prop_nw)


'''
Plot the graph
'''

if nngt.get_config("with_plot"):
    import matplotlib.pyplot as plt

    colors = np.zeros(num_nodes)
    colors[500:] = 1

    if nngt.get_config("backend") == "graph-tool":
        from graph_tool.draw import graph_draw, prop_to_size, sfdp_layout
        pm = net.new_vertex_property("int", colors)
        size = net.new_vertex_property("double", val=5.)
        pos = sfdp_layout(net, groups=pm, C=1., K=20, gamma=5, mu=20)
        graph_draw(net, pos=pos, vertex_fill_color=pm, vertex_color=pm,
                   vertex_size=size, nodesfirst=True,
                   edge_color=[0.179, 0.203,0.210, 0.3])
    elif nngt.get_config("backend") == "networkx":
        import networkx as nx