def test_group_structure(): metagroup = nngt.Group(100, metagroup=True) g1 = nngt.Group(50) g2 = nngt.Group(80, name="group2") struct = nngt.Structure.from_groups((g1, g2)) with pytest.raises(AssertionError): g = nngt.Graph(100, structure=struct) struct.create_meta_group(range(20, 70), name="meta2") g = nngt.Graph(structure=struct) nngt.generation.connect_groups(g, g1, g1, "all_to_all") nngt.generation.connect_groups(g, struct, g1, "erdos_renyi", avg_deg=5, ignore_invalid=True) nngt.generation.connect_groups(g, g2, struct, "erdos_renyi", avg_deg=5, ignore_invalid=True)
def test_betweenness(): ''' Check betweenness results for all backends ''' num_nodes = 5 # UNDIRECTED edge_list = [(0, 1), (0, 2), (0, 3), (1, 3), (2, 3), (2, 4), (3, 4)] weights = [0.1, 0.3, 1.5, 0.8, 5.6, 4., 2.3] nb_expect = [0.083333, 0.0, 0.083333, 0.3333333, 0.0] eb_expect = [0.15, 0.2, 0.15, 0.25, 0.15, 0.15, 0.25] nb_exp_wght = [0.5, 2 / 3, 0, 0.5, 0] eb_exp_wght = [0.6, 0.4, 0, 0.6, 0, 0, 0.4] for bckd in backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes, directed=False) g.new_edges(edge_list, attributes={"weight": weights}) nb, eb = nngt.analyze_graph["betweenness"](g) assert np.all(np.isclose(nb, nb_expect)) assert np.all(np.isclose(eb, eb_expect)) # weighted nb, eb = nngt.analyze_graph["betweenness"](g, weights=True) assert np.all(np.isclose(nb, nb_exp_wght)) assert np.all(np.isclose(eb, eb_exp_wght)) # DIRECTED edge_list = [(0, 1), (0, 2), (0, 3), (1, 3), (3, 2), (3, 4), (4, 2), (4, 0)] weights = [0.1, 0.3, 1.5, 0.8, 5.6, 4., 2.3, 0.9] nb_expect = [0.25, 0, 0, 1 / 3, 0.25] eb_expect = [0.15, 0.05, 0.15, 0.2, 0.1, 0.3, 0.05, 0.3] nb_exp_wght = [0.5, 0.25, 0, 1 / 3, 5 / 12] eb_exp_wght = [0.3, 0.2, 0, 0.35, 0, 0.4, 0, 0.45] for bckd in backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes, directed=True) g.new_edges(edge_list, attributes={"weight": weights}) nb, eb = nngt.analyze_graph["betweenness"](g) assert np.all(np.isclose(nb, nb_expect)) assert np.all(np.isclose(eb, eb_expect)) # weighted nb, eb = nngt.analyze_graph["betweenness"](g, weights=True) assert np.all(np.isclose(nb, nb_exp_wght)) assert np.all(np.isclose(eb, eb_exp_wght))
def test_all_to_all(): ''' Test all-to-all connection scheme ''' num_nodes = 4 # via direct generation call g = ng.all_to_all(nodes=num_nodes, directed=False) assert np.array_equal(g.edges_array, [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]) g = ng.all_to_all(nodes=num_nodes, directed=True) assert np.array_equal(g.edges_array, [(0, 1), (0, 2), (0, 3), (1, 0), (1, 2), (1, 3), (2, 0), (2, 1), (2, 3), (3, 0), (3, 1), (3, 2)]) # via connector call g = nngt.Graph(num_nodes) ng.connect_nodes(g, [0, 1], [2, 3], "all_to_all") assert np.array_equal(g.edges_array, [(0, 2), (0, 3), (1, 2), (1, 3)]) g = nngt.Graph(num_nodes) ng.connect_nodes(g, [0, 1], [1, 2, 3], "all_to_all") assert np.array_equal(g.edges_array, [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3)])
def test_binary_shortest_paths(): ''' Test shortests paths with BFS algorithm ''' for bckd in backends: nngt.use_backend(bckd) num_nodes = 5 # UNDIRECTED edge_list = [(0, 1), (0, 3), (1, 2), (1, 4), (2, 3), (3, 4)] g = nngt.Graph(num_nodes, directed=False) g.new_edges(edge_list) assert na.shortest_path(g, 0, 0) == [0] assert na.shortest_path(g, 0, 1) == [0, 1] assert na.shortest_path(g, 0, 2) in ([0, 1, 2], [0, 3, 2]) count = 0 for p in na.all_shortest_paths(g, 4, 2): assert p in ([4, 1, 2], [4, 3, 2]) count += 1 assert count == 2 count = 0 for p in na.all_shortest_paths(g, 1, 1): assert p == [1] count += 1 assert count == 1 # DIRECTED edge_list = [(0, 1), (0, 3), (1, 2), (1, 4), (3, 2), (4, 3)] g = nngt.Graph(num_nodes, directed=True) g.new_edges(edge_list) assert na.shortest_path(g, 0, 0) == [0] assert na.shortest_path(g, 2, 4) == [] assert na.shortest_path(g, 0, 2) in ([0, 1, 2], [0, 3, 2]) count = 0 for p in na.all_shortest_paths(g, 4, 2): assert p == [4, 3, 2] count += 1 assert count == 1 count = 0 for p in na.all_shortest_paths(g, 1, 1): assert p == [1] count += 1 assert count == 1
def test_components(): ''' Check connected components for all backends ''' num_nodes = 8 edge_list = [(0, 1), (0, 2), (1, 2)] for i in range(3, num_nodes - 1): edge_list.append((i, i + 1)) edge_list.append((7, 3)) for bckd in all_backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes, directed=True) g.new_edges(edge_list) # scc cc, hist = \ nngt.analyze_graph["connected_components"](g, ctype="scc") idx = np.array([i for i in range(num_nodes)], dtype=int) # nodes are assigned to the correct components assert np.all(cc[0] not in cc[1:]) # 3 first are isolated assert np.all(cc[1] not in cc[idx != 1]) # 3 first are isolated assert np.all(cc[2] not in cc[idx != 2]) # 3 first are isolated assert np.all(cc[3:] == cc[3]) # 5 last together # hence counts should be 1, 1, 1, and 5 assert hist[cc[0]] == 1 assert hist[cc[1]] == 1 assert hist[cc[2]] == 1 assert hist[cc[5]] == 5 # wcc cc, hist = \ nngt.analyze_graph["connected_components"](g, ctype="wcc") # nodes are assigned to the correct components assert np.all(cc[:3] == cc[0]) # 3 first together assert np.all(cc[3:] == cc[3]) # 5 last together # hence counts should be 3 and 5 assert hist[cc[0]] == 3 assert hist[cc[5]] == 5 # undirected g = nngt.Graph(nodes=num_nodes, directed=False) g.new_edges(edge_list) cc, hist = \ nngt.analyze_graph["connected_components"](g) # nodes are assigned to the correct components assert np.all(cc[:3] == cc[0]) # 3 first together assert np.all(cc[3:] == cc[3]) # 5 last together # hence counts should be 3 and 5 assert hist[cc[0]] == 3 assert hist[cc[5]] == 5
def test_degrees_neighbors(): ''' Check ``Graph.get_degrees`` method. ''' edge_list = [(0, 1), (0, 2), (0, 3), (1, 3), (3, 2), (3, 4), (4, 2)] weights = [0.54881, 0.71518, 0.60276, 0.54488, 0.42365, 0.64589, 0.43758] out_degrees = np.array([3, 1, 0, 2, 1]) in_degrees = np.array([0, 1, 3, 2, 1]) tot_degrees = in_degrees + out_degrees out_strengths = np.array([1.86675, 0.54488, 0, 1.06954, 0.43758]) in_strengths = np.array([0, 0.54881, 1.57641, 1.14764, 0.64589]) tot_strengths = in_strengths + out_strengths # DIRECTED g = nngt.Graph(5, directed=True) g.new_edges(edge_list, attributes={"weight": weights}) assert np.all(g.get_degrees(mode="in") == in_degrees) assert np.all(g.get_degrees(mode="out") == out_degrees) assert np.all(g.get_degrees() == tot_degrees) assert np.all( np.isclose(g.get_degrees(mode="in", weights=True), in_strengths)) assert np.all( np.isclose(g.get_degrees(mode="out", weights=True), out_strengths)) assert np.all(np.isclose(g.get_degrees(weights="weight"), tot_strengths)) assert g.neighbours(3, "in") == {0, 1} assert g.neighbours(3, "out") == {2, 4} assert g.neighbours(3, "all") == {0, 1, 2, 4} # UNDIRECTED g = nngt.Graph(5, directed=False) g.new_edges(edge_list, attributes={"weight": weights}) assert np.all(g.get_degrees(mode="in") == tot_degrees) assert np.all(g.get_degrees(mode="out") == tot_degrees) assert np.all(g.get_degrees() == tot_degrees) assert np.all( np.isclose(g.get_degrees(mode="in", weights=True), tot_strengths)) assert np.all( np.isclose(g.get_degrees(mode="out", weights=True), tot_strengths)) assert np.all(np.isclose(g.get_degrees(weights="weight"), tot_strengths)) assert g.neighbours(3, "in") == {0, 1, 2, 4} assert g.neighbours(3, "out") == {0, 1, 2, 4} assert g.neighbours(3, "all") == {0, 1, 2, 4}
def test_structure(): # with a structure room1 = nngt.Group(25) room2 = nngt.Group(50) room3 = nngt.Group(40) room4 = nngt.Group(35) names = ["R1", "R2", "R3", "R4"] struct = nngt.Structure.from_groups((room1, room2, room3, room4), names) g = nngt.Graph(structure=struct) for fmt in formats: g.to_file(gfilename, fmt=fmt) h = nngt.load_from_file(gfilename, fmt=fmt) assert g.structure == h.structure # with a neuronal population g = nngt.Network.exc_and_inhib(100) for fmt in formats: g.to_file(gfilename, fmt=fmt) h = nngt.load_from_file(gfilename, fmt=fmt) assert g.population == h.population
def test_iedges(): ''' Check the computation of the number of inhibitory edges ''' num_nodes = 5 edge_list = [(0, 3), (1, 0), (1, 2), (2, 4), (4, 1), (4, 3)] types = [1, -1, 1, 1, -1, 1] for directed in (True, False): g = nngt.Graph(nodes=num_nodes, directed=directed) g.new_edges(edge_list) # from list g.set_types(types) assert na.num_iedges(g) == 2 # from node list nodes = [1, 2] num_inhib = 3 g.set_types(-1, nodes=nodes) assert na.num_iedges(g) == 3 # from edge fraction g.set_types(-1, fraction=0.5) assert na.num_iedges(g) == 3
def test_custom_attributes(self): ''' Test that custom attributes are saved and loaded correctly ''' num_nodes = 1000 avg_deg = 100 g = nngt.Graph(nodes=num_nodes) g.new_edge_attribute("test_attr", "int") num_edges = 0 for i in range(num_nodes): targets = np.unique(np.random.randint(0, num_nodes, avg_deg)) elist = np.zeros((len(targets), 2), dtype=int) elist[:, 0] = i elist[:, 1] = targets ids = np.random.randint(0, avg_deg * num_nodes, len(targets)) ids *= 2 * np.random.randint(0, 2, len(targets)) - 1 g.new_edges(elist, attributes={"test_attr": ids}) num_edges = g.edge_nb() g.to_file('test.el') h = nngt.Graph.from_file('test.el') allclose = np.allclose(g.get_edge_attributes(name="test_attr"), h.get_edge_attributes(name="test_attr")) if not allclose: print("Results differed for '{}'.".format(g.name)) print(g.get_edge_attributes(name="test_attr")) print(h.get_edge_attributes(name="test_attr")) self.assertTrue(allclose)
def test_assortativity(): ''' Check assortativity result for all backends ''' # DIRECTED num_nodes = 5 edge_list = [(0, 3), (1, 0), (1, 2), (2, 4), (4, 1), (4, 3), (4, 2)] weights = [0.53, 0.45, 0.8, 0.125, 0.66, 0.31, 0.78] # expected results assort_unweighted = -0.47140452079103046 assort_weighted = -0.5457956719785911 for bckd in backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes) g.new_edges(edge_list, attributes={"weight": weights}) assert np.isclose(nngt.analyze_graph["assortativity"](g, "in"), assort_unweighted) # not check weighted version for networkx for now assert np.isclose( nngt.analyze_graph["assortativity"](g, "in", weights=True), assort_weighted) # UNDIRECTED edge_list = [(0, 3), (1, 0), (1, 2), (2, 4), (4, 1), (4, 3)] weights = weights[:len(edge_list)] # expected results assort_unweighted = -0.33333333333333215 assort_weighted = -0.27351320394915296 for bckd in backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes, directed=False) g.new_edges(edge_list, attributes={"weight": weights}) assert np.isclose(nngt.analyze_graph["assortativity"](g, "in"), assort_unweighted) # not check weighted version for networkx for now if bckd != "networkx": assert np.isclose( nngt.analyze_graph["assortativity"](g, "in", weights=True), assort_weighted)
def all_to_all(nodes=0, weighted=True, directed=True, multigraph=False, name="AlltoAll", shape=None, positions=None, population=None, **kwargs): """ Generate a graph where all nodes are connected. .. versionadded:: 1.0 Parameters ---------- nodes : int, optional (default: None) The number of nodes in the graph. reciprocity : double, optional (default: -1 to let it free) Fraction of edges that are bidirectional (only for directed graphs -- undirected graphs have a reciprocity of 1 by definition) weighted : bool, optional (default: True) Whether the graph edges have weights. directed : bool, optional (default: True) Whether the graph is directed or not. multigraph : bool, optional (default: False) Whether the graph can contain multiple edges between two nodes. name : string, optional (default: "ER") Name of the created graph. shape : :class:`~nngt.geometry.Shape`, optional (default: None) Shape of the neurons' environment. positions : :class:`numpy.ndarray`, optional (default: None) A 2D or 3D array containing the positions of the neurons in space. population : :class:`~nngt.NeuralPop`, optional (default: None) Population of neurons defining their biological properties (to create a :class:`~nngt.Network`). Note ---- `nodes` is required unless `population` is provided. Returns ------- graph_all : :class:`~nngt.Graph`, or subclass A new generated graph. """ nodes = nodes if population is None else population.size matrix = np.ones((nodes, nodes)) graph_all = nngt.Graph(name=name, nodes=nodes, directed=directed, **kwargs) _set_options(graph_all, population, shape, positions) # add edges if nodes > 1: ids = np.arange(nodes, dtype=np.uint) edges = _all_to_all(ids, ids, directed, multigraph) graph_all.new_edges(ia_edges) graph_all._graph_type = "all_to_all" return graph_all
def test_reciprocity(): ''' Check reciprocity result ''' num_nodes = 5 edge_list1 = [(0, 3), (1, 0), (1, 2), (2, 4), (4, 1), (4, 3), (4, 2)] edge_list2 = [(0, 3), (1, 0), (1, 2), (2, 4), (4, 1), (4, 3)] recip = 2 / 7 # directed g = nngt.Graph(nodes=num_nodes, directed=True) g.new_edges(edge_list1) assert np.isclose(nngt.analyze_graph["reciprocity"](g), recip) # undirected g = nngt.Graph(nodes=num_nodes, directed=False) g.new_edges(edge_list2) assert nngt.analyze_graph["reciprocity"](g) == 1.
def test_autoclass(): ''' Check that Graph is automatically converted to Network or SpatialGraph if the relevant arguments are provided. ''' pop = nngt.NeuralPop.exc_and_inhib(100) g = nngt.Graph(population=pop) assert isinstance(g, nngt.Network) shape = nngt.geometry.Shape.disk(50.) g = nngt.Graph(shape=shape) assert isinstance(g, nngt.SpatialGraph) g = nngt.Graph(population=pop, shape=shape) assert isinstance(g, nngt.SpatialNetwork)
def test_empty_out_degree(): g = nngt.Graph(2) g.new_edge(0, 1) for fmt in formats: nngt.save_to_file(g, gfilename, fmt=fmt) h = nngt.load_from_file(gfilename, fmt=fmt) assert np.array_equal(g.edges_array, h.edges_array)
def test_diameter(): ''' Check connected components for all backends ''' # unconnected num_nodes = 8 edge_list = [(0, 1), (0, 2), (1, 2)] for i in range(3, num_nodes - 1): edge_list.append((i, i + 1)) edge_list.append((7, 3)) weights = [0.58, 0.59, 0.88, 0.8, 0.61, 0.66, 0.62, 0.28] for bckd in backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes, directed=True) g.new_edges(edge_list, attributes={"weight": weights}) assert np.isinf(nngt.analyze_graph["diameter"](g, weights=None)) assert np.isinf(nngt.analyze_graph["diameter"](g, weights=True)) # connected num_nodes = 5 edge_list = [(0, 1), (0, 3), (1, 3), (2, 0), (3, 2), (3, 4), (4, 2)] weights = [0.58, 0.59, 0.88, 0.8, 0.61, 0.66, 0.28] for bckd in backends: nngt.set_config("backend", bckd) g = nngt.Graph(nodes=num_nodes, directed=True) g.new_edges(edge_list, attributes={"weight": weights}) d = nngt.analyze_graph["diameter"](g) assert nngt.analyze_graph["diameter"](g, weights=None) == 3 assert np.isclose(nngt.analyze_graph["diameter"](g, weights="weight"), 2.29)
def test_binary_undirected_clustering(): ''' Check that directed local clustering returns undirected value if graph is not directed. ''' # pre-defined graph num_nodes = 5 edge_list = [(0, 3), (1, 0), (1, 2), (2, 4), (4, 1), (4, 3), (4, 2), (4, 0)] # expected results loc_clst = [2 / 3., 2 / 3., 1., 1., 0.5] glob_clst = 0.6428571428571429 # create graph g = nngt.Graph(nodes=num_nodes) g.new_edges(edge_list) # check all 3 ways of computing the local clustering assert np.all( np.isclose(na.local_clustering_binary_undirected(g), loc_clst)) assert np.all(np.isclose(na.local_clustering(g, directed=False), loc_clst)) assert np.all( np.isclose(nngt.analyze_graph["local_clustering"](g, directed=False), loc_clst)) # check all 4 ways of computing the global clustering assert np.isclose(na.global_clustering(g, directed=False), glob_clst) assert np.isclose(na.transitivity(g, directed=False), glob_clst) assert np.isclose(na.global_clustering_binary_undirected(g), glob_clst) assert np.isclose( nngt.analyze_graph["global_clustering"](g, directed=False), glob_clst) # check that self-loops are ignore g.new_edge(0, 0, self_loop=True) assert np.all( np.isclose(na.local_clustering_binary_undirected(g), loc_clst)) assert np.isclose(na.global_clustering_binary_undirected(g), glob_clst) # sanity check for local clustering on undirected unweighted graph g = ng.erdos_renyi(avg_deg=10, nodes=100, directed=False) ccu = na.local_clustering_binary_undirected(g) cc = na.local_clustering(g) assert np.all(np.isclose(cc, ccu))
def test_str_attr(): ''' Check string attributes ''' g = nngt.Graph(5) # set node attribute node_names = ["aa", "b", "c", "dddd", "eee"] g.new_node_attribute("name", "string", values=node_names) # set edges edges = [(0, 1), (1, 3), (1, 4), (2, 0), (3, 2), (4, 1)] g.new_edges(edges) # set edge attribute eattr = ["a" * i for i in range(len(edges))] g.new_edge_attribute("edata", "string", values=eattr) # check attributes assert list(g.node_attributes["name"]) == node_names assert list(g.edge_attributes["edata"]) == eattr # save and load string attributes current_dir = os.path.dirname(os.path.abspath(__file__)) + '/' filename = current_dir + "g.el" g.to_file(filename) h = nngt.load_from_file(filename) assert list(h.node_attributes["name"]) == node_names assert list(h.edge_attributes["edata"]) == eattr os.remove(filename) # change an attribute node_names[2] = "cc" h.set_node_attribute("name", values=node_names) assert not np.array_equal(h.node_attributes["name"], g.node_attributes["name"]) assert list(h.node_attributes["name"]) == node_names eattr[0] = "l" h.set_edge_attribute("edata", values=eattr) assert not np.array_equal(h.edge_attributes["edata"], g.edge_attributes["edata"]) assert list(h.edge_attributes["edata"]) == eattr
def test_density(): # directed num_nodes = 3 g = nngt.Graph(num_nodes) edges = [(0, 1), (1, 2), (2, 0)] g.new_edges(edges) assert np.isclose(g.get_density(ignore_loops=True), 1 / 3) assert np.isclose(g.get_density(ignore_loops=False), 0.5) # undirected g = nngt.Graph(num_nodes, directed=False) edges = [(0, 1), (1, 2), (2, 0)] g.new_edges(edges) assert np.isclose(g.get_density(ignore_loops=True), 0.5) assert np.isclose(g.get_density(ignore_loops=False), 1)
def test_node_attr(self): ''' When generating graphs with weights, check that the expected properties are indeed obtained. ''' g = nngt.Graph(100) ref_result = np.random.uniform(-1, 4, g.node_nb()) g.set_node_attribute("nud", values=ref_result, value_type="double") computed_result = g.get_node_attributes(name="nud") self.assertTrue(np.allclose(ref_result, computed_result), '''Error on graph {}: unequal 'nud' attribute for tolerance {}. '''.format(g.name, self.tolerance))
def test_has_edges_edge_id(): ''' Test the ``has_edge`` and ``edge_id`` methods ''' num_nodes = 10 # DIRECTED edges = [(0, 1), (2, 4)] g = nngt.Graph(num_nodes) g.new_edges(edges) for i, e in enumerate(edges): assert g.has_edge(e) assert g.edge_id(e) == i # UNDIRECTED g = nngt.Graph(num_nodes, directed=False) g.new_edges(edges) for i, e in enumerate(edges): assert g.has_edge(e) assert g.edge_id(e) == i assert g.has_edge(e[::-1]) assert g.edge_id(e[::-1]) == i
def test_get_edges(): ''' Check that correct edges are returned ''' # directed g = nngt.Graph(4, directed=True) edges = [(0, 1), (1, 0), (1, 2), (2, 3)] g.new_edges(edges) def to_set(ee): return {tuple(e) for e in ee} assert g.get_edges(source_node=0) == [(0, 1)] assert g.get_edges(target_node=2) == [(1, 2)] assert to_set(g.get_edges(source_node=[0, 1])) == to_set(edges[:3]) assert to_set(g.get_edges(target_node=[0, 1])) == to_set(edges[:2]) assert to_set(g.get_edges(source_node=[0, 2], target_node=[0, 1])) == {(0, 1)} # undirected g = nngt.Graph(4, directed=False) edges = [(0, 1), (1, 2), (2, 3)] g.new_edges(edges) res = {(0, 1), (1, 2)} assert g.get_edges(source_node=0) == [(0, 1)] assert to_set(g.get_edges(target_node=2)) == {(1, 2), (2, 3)} assert to_set(g.get_edges(source_node=[0, 1])) == res assert to_set(g.get_edges(target_node=[0, 1])) == res assert to_set(g.get_edges(source_node=[0, 2], target_node=[0, 1])) == res assert to_set(g.get_edges(source_node=0, target_node=1)) == {(0, 1)} assert to_set(g.get_edges(source_node=0, target_node=[0, 1])) == {(0, 1)}
def test_global_clustering(): num_nodes = 3 g = nngt.Graph(num_nodes) g.new_edges([(0, 1), (0, 2), (2, 1)]) with pytest.raises(AssertionError): na.global_clustering(g, method='plop') modes = ('total', 'cycle', 'middleman', 'fan-in', 'fan-out') results = (0.5, 0, 1, 0.5, 0.5) for m in methods: for mode, res in zip(modes, results): gc = na.global_clustering(g, method=m, mode=mode) assert gc == res
def test_custom_attributes(self): ''' Test that custom attributes are saved and loaded correctly ''' num_nodes = 100 avg_deg = 10 g = nngt.Graph(nodes=num_nodes) g.new_edge_attribute("test_attr", "int") for i in range(num_nodes): targets = np.random.choice(num_nodes, size=avg_deg, replace=False) elist = np.zeros((len(targets), 2), dtype=int) elist[:, 0] = i elist[:, 1] = targets ids = np.random.randint(0, avg_deg * num_nodes, len(targets)) ids *= 2 * np.random.randint(0, 2, len(targets)) - 1 g.new_edges(elist, attributes={"test_attr": ids}, check_duplicates=False, check_self_loops=False, check_existing=False) old_edges = g.edges_array for ft in filetypes: g.to_file(current_dir + 'test.' + ft) h = nngt.Graph.from_file(current_dir + 'test.' + ft) # for neighbour list, we need to give the edge list to have # the edge attributes in the same order as the original graph allclose = np.allclose( g.get_edge_attributes(name="test_attr"), h.get_edge_attributes(edges=old_edges, name="test_attr")) if not allclose: print("Results differed for '{}'.".format(g.name)) print("using file 'test.{}'.".format(ft)) print(g.get_edge_attributes(name="test_attr")) print(h.get_edge_attributes(edges=old_edges, name="test_attr")) with open(current_dir + 'test.' + ft, 'r') as f: for line in f.readlines(): print(line.strip()) self.assertTrue(allclose)
def test_weighted_degrees(): g = nngt.Graph() g.new_node(10) ww = [5.] * 4 g.new_edges([(0, 4), (8, 2), (7, 0), (1, 3)], attributes={"weight": ww}) # check degrees in_deg = [1., 0., 1., 1., 1., 0., 0., 0., 0., 0.] out_deg = [1., 1., 0., 0., 0., 0., 0., 1., 1., 0.] tot_deg = [2., 1., 1., 1., 1., 0., 0., 1., 1., 0.] assert np.all(g.get_degrees("in") == in_deg) assert np.all( g.get_degrees("in", weights=True) == np.multiply(ww[0], in_deg)) assert np.all(g.get_degrees("out") == out_deg) assert np.all(g.get_degrees("total") == tot_deg) # set all weights to zero g.set_weights(0.) assert set(g.get_weights()) == {0.} assert set(g.get_edge_attributes(name="weight")) == {0.} assert not np.any(g.get_degrees("in", weights=True)) # set two edges to 2. elist = [(0, 4), (8, 2)] g.set_weights(2., elist=elist) assert set(g.get_weights()) == {0., 2.} assert set(g.get_edge_attributes(name="weight")) == {0., 2.} # test new weighted degree w_indeg = [0., 0., 2., 0., 2., 0., 0., 0., 0., 0.] w_outdeg = [2., 0., 0., 0., 0., 0., 0., 0., 2., 0.] assert np.all(g.get_degrees("in", weights=True) == w_indeg) assert np.all(g.get_degrees("out", weights=True) == w_outdeg) # check the node and edges assert g.node_nb() == 10 assert g.edge_nb() == 4
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_nattr_default_values(self): g2 = nngt.Graph() # add a new node with attributes attributes = {'size': 2., 'color': 'blue', 'a': 5, 'blob': []} attribute_types = { 'size': 'double', 'color': 'string', 'a': 'int', 'blob': 'object' } g2.new_node(attributes=attributes, value_types=attribute_types) g2.new_node(2) g2.new_node(3, attributes={ 'size': [4., 5., 1.], 'color': ['r', 'g', 'b'] }, value_types={ 'size': 'double', 'color': 'string' }) # check all values # for the doubles: # NaN == NaN is false, so we need to check separately equality between # non-NaN entries and position of NaN entries double_res = np.array([2., np.NaN, np.NaN, 4., 5., 1.]) isnan1 = np.isnan(g2.node_attributes['size']) isnan2 = np.isnan(double_res) self.assertTrue(np.all(isnan1 == isnan2)) self.assertTrue( np.all( np.isclose(g2.node_attributes['size'][~isnan1], double_res[~isnan2]))) # for the others, just compare the lists self.assertEqual(g2.node_attributes['color'].tolist(), ['blue', '', '', 'r', 'g', 'b']) self.assertEqual(g2.node_attributes['a'].tolist(), [5, 0, 0, 0, 0, 0]) self.assertEqual(g2.node_attributes['blob'].tolist(), [[], None, None, None, None, None])
def test_undirected_adjacency(): ''' Check undirected adjacency matrix ''' num_nodes = 5 edge_list = [(0, 1), (0, 3), (1, 3), (2, 0), (3, 2), (3, 4), (4, 2)] weights = [0.54881, 0.71518, 0.60276, 0.54488, 0.42365, 0.64589, 0.43758] etypes = [-1, 1, 1, -1, -1, 1, 1] g = nngt.Graph(num_nodes, directed=False) g.new_edges(edge_list, attributes={"weight": weights}) g.new_edge_attribute("type", "int", values=etypes) adj_mat = np.array([[0, 1, 1, 1, 0], [1, 0, 0, 1, 0], [1, 0, 0, 1, 1], [1, 1, 1, 0, 1], [0, 0, 1, 1, 0]]) assert np.all( np.isclose(g.adjacency_matrix(weights=False).todense(), adj_mat)) w_mat = np.array([[0, 0.54881, 0.54488, 0.71518, 0], [0.54881, 0, 0, 0.60276, 0], [0.54488, 0, 0, 0.42365, 0.43758], [0.71518, 0.60276, 0.42365, 0, 0.64589], [0, 0, 0.43758, 0.64589, 0]]) assert np.all(np.isclose( g.adjacency_matrix(weights=True).todense(), w_mat)) # for typed edges tpd_mat = np.array([[0, -1, -1, 1, 0], [-1, 0, 0, 1, 0], [-1, 0, 0, -1, 1], [1, 1, -1, 0, 1], [0, 0, 1, 1, 0]]) assert np.all(np.isclose( g.adjacency_matrix(types=True).todense(), tpd_mat)) wt_mat = np.array([[0, -0.54881, -0.54488, 0.71518, 0], [-0.54881, 0, 0, 0.60276, 0], [-0.54488, 0, 0, -0.42365, 0.43758], [0.71518, 0.60276, -0.42365, 0, 0.64589], [0, 0, 0.43758, 0.64589, 0]]) assert np.all( np.isclose( g.adjacency_matrix(types=True, weights=True).todense(), wt_mat))
def test_combined_attr(): ''' Check combined attributes ''' g = nngt.Graph(3) g.new_edges(((0, 1), (1, 1), (1, 2), (2, 1)), check_self_loops=False) ww = (0.1, 1, 0.5, 0.2) dd = (2., 0., 0.3, 0.3) rr = (0.8, 0.4, -0.5, 0.5) g.set_weights(ww) g.new_edge_attribute("distance", "double", dd) g.new_edge_attribute("rnd", "double", rr) combine = {"weight": "max", "distance": "mean", "rnd": "sum"} u = g.to_undirected(combine) assert np.all(u.get_weights() == (0.1, 1, 0.5)) assert np.all(u.edge_attributes["distance"] == (2, 0, 0.3)) assert np.all(u.edge_attributes["rnd"] == (0.8, 0.4, 0))
def test_node_creation(): ''' When making graphs, test node creation function. ''' g = nngt.Graph(100, name="new_node_test") assert g.node_nb() == 100, \ "Error on '{}': invalid initial nodes ({} vs {} expected).".format( g.name, g.node_nb(), 100) n = g.new_node() assert g.node_nb() == 101 and n == 100, \ "Error on '{}': ({}, {}) vs (101, 100) expected.".format( g.name, g.node_nb(), n) nn = g.new_node(2) assert g.node_nb() == 103 and tuple(nn) == (101, 102), \ "Error on '{}': ({}, {}, {}) vs (103, 101, 102) expected.".format( g.name, g.node_nb(), nn[0], nn[1])
def test_str_attributes(): g = nngt.Graph(2) g.new_edge(0, 1) g.new_edge_attribute("type", "string") g.set_edge_attribute("type", val='odd') g.new_node_attribute("rnd", "string") g.set_node_attribute("rnd", values=["s'adf", 'sd fr"']) for fmt in formats: nngt.save_to_file(g, gfilename, fmt=fmt) h = nngt.load_from_file(gfilename, fmt=fmt) assert np.array_equal(g.edges_array, h.edges_array) assert np.array_equal(g.edge_attributes["type"], h.edge_attributes["type"]) assert np.array_equal(g.node_attributes["rnd"], h.node_attributes["rnd"])