def ni_to_nli(compinv_timeseries_dict_list, invdicts): invariants = set() mapped_invdicts = dict() mapped_compinv_timeseries_dict_list = [] for complete_invariant_timeseries_dict in compinv_timeseries_dict_list: mapped_complete_invariant_timeseries_dict = dict() for complete_invariant in complete_invariant_timeseries_dict: nl_complete_invariant = pn.get_complete_invariant( invdicts[complete_invariant], allowed_aspects='all') if nl_complete_invariant not in mapped_invdicts: mapped_invdicts[nl_complete_invariant] = invdicts[ complete_invariant] invariants.add(nl_complete_invariant) mapped_complete_invariant_timeseries_dict[ nl_complete_invariant] = mapped_complete_invariant_timeseries_dict.get( nl_complete_invariant, dict()) for tw in complete_invariant_timeseries_dict[complete_invariant]: mapped_complete_invariant_timeseries_dict[ nl_complete_invariant][ tw] = mapped_complete_invariant_timeseries_dict[ nl_complete_invariant].get( tw, 0) + complete_invariant_timeseries_dict[ complete_invariant][tw] mapped_compinv_timeseries_dict_list.append( mapped_complete_invariant_timeseries_dict) return mapped_compinv_timeseries_dict_list, invariants, mapped_invdicts
def subtrahend(orbit1, orbit2, nets, auts, invs, allowed_aspects='all'): ''' Returns the subtrahend for orbit2 in orbit equations (the value that is substracted in the upper part of the binomial coefficient on theleft sides of the orbit equation) Parameters ---------- orbit1, orbit2 : tuple (n_nodes, net_index, node_orbit_index) These can extract from the output of orbit_equations, n_nodex, net_index, and node_orbit_index should match those of parameter auts nets : dict (key: n_nodes, value: list of networks) graphlets, as produced by graphlets auts : dd (key: (n_nodes, net_index, node), value: node_orbit_index) as produced by automorphism_orbits Returns ------- sub_max : int Notes ----- assumes orbit2 has at most the same number of nodes as orbit1 ''' sub_max = 0 n_nodes1 = orbit1[0] n_nodes2 = orbit2[0] net1 = nets[n_nodes1][orbit1[1]] net2 = nets[n_nodes2][orbit2[1]] the_node = orbit1[2] layers = net1.slices[1] nodes = net1.slices[0] - set([the_node]) for partition in partitions_with_remainder(nodes, n_nodes2 - 1): sub = 0 for nodes_s in partition: nodes_g = set(nodes_s) | set([the_node]) sub_net = pymnet.subnet(net1, nodes_g, layers) ci_sub = str( pymnet.get_complete_invariant(sub_net, allowed_aspects=allowed_aspects)) if ci_sub in invs and invs[ci_sub] == (n_nodes2, orbit2[1]): iso = pymnet.get_isomorphism(sub_net, net2, allowed_aspects=allowed_aspects) if the_node in iso[0]: iso_node = iso[0][the_node] else: iso_node = the_node if auts[n_nodes2, orbit2[1], iso_node] == orbit2[2]: sub += 1 sub_max = max(sub_max, sub) return sub_max
def test_find_isomorphism_classes_agg_dict_node_isomorphism_example_dicts( self): # test a) aggregated dict, b) node isomorphism, c) example generation dd = collections.defaultdict(dict) dd_e = dict() subgraph_classification.find_isomorphism_classes( self.testnet, 2, 2, 'this_file_should_not_exist', [0], dd, dd_e) self.assertEqual(len(dd), 3) self.assertEqual(dd[self.node_compinv1], {(0, 1): 2, (2, 3): 1}) self.assertEqual(dd[self.node_compinv2], {(2, 3): 1}) self.assertEqual(dd[self.node_compinv3], {(1, 2): 1}) self.assertEqual(len(dd_e), 3) self.assertEqual( pn.get_complete_invariant(dd_e[self.node_compinv1], [0]), self.node_compinv1) self.assertEqual( pn.get_complete_invariant(dd_e[self.node_compinv2], [0]), self.node_compinv2) self.assertEqual( pn.get_complete_invariant(dd_e[self.node_compinv3], [0]), self.node_compinv3) self.assertEqual(pn.get_complete_invariant(dd_e[self.node_compinv1]), self.compinv1) self.assertEqual(pn.get_complete_invariant(dd_e[self.node_compinv2]), self.compinv2) self.assertEqual(pn.get_complete_invariant(dd_e[self.node_compinv3]), self.compinv1)
def save_subnet_with_complete_invariant(M, nodes, layers, writefile, examples_dict, allowed_aspects): if allowed_aspects != 'all': # relabel layers to 0...k sorted_layers = tuple(sorted(layers)) relabeling = dict() for ii, orig_layer in enumerate(sorted_layers): relabeling[orig_layer] = ii subnet = pn.transforms.relabel(pn.subnet(M, nodes, layers), layerNames=relabeling) complete_invariant = pn.get_complete_invariant( subnet, allowed_aspects=allowed_aspects) else: subnet = pn.subnet(M, nodes, layers) complete_invariant = pn.get_complete_invariant( subnet, allowed_aspects=allowed_aspects) writefile.write( str(nodes) + '\t' + str(layers) + '\t' + str(complete_invariant) + '\n') if isinstance(examples_dict, dict): if complete_invariant not in examples_dict: examples_dict[complete_invariant] = subnet return
def orbit_counts(n, node0, net, nets, orbits, auts, invs, orbit_list, allowed_aspects='all'): ''' Computes the orbit counts for node0 in net Parameters ---------- node0 : node net : network nets : dict (key: n_nodes, value: list of networks) graphlets orbits : dd (key: (node, orbit), value: count) dictionary where the counts will be stored auts : dd (key: (n_nodes, net_index, node), value: node) automorphism orbits invs : dict (key: str(complete invariant), value: tuple(n_nodes, net_index in nets)) complete invariants of the graphlets orbit_list : list of orbits allowed_aspects : list, string the aspects that can be permutated when computing isomorphisms ''' for orbit in orbit_list: orbits[node0, orbit] = 0 layers = net.slices[1] node_sets = touching_orbit_nodes(node0, net, n) for nodes_s in node_sets: sub_net = pymnet.subnet(net, nodes_s, layers) ci_sub = str( pymnet.get_complete_invariant(sub_net, allowed_aspects=allowed_aspects)) i = invs[ci_sub][1] n_nodes = invs[ci_sub][0] nw = nets[n_nodes][i] iso = pymnet.get_isomorphism(sub_net, nw, allowed_aspects=allowed_aspects) if node0 in iso[0]: orbits[node0, (n_nodes, i, auts[n_nodes, i, iso[0][node0]])] += 1 else: orbits[node0, (n_nodes, i, auts[n_nodes, i, node0])] += 1
def add_subnet_to_aggregated_dict(M, nodes, layers, aggregated_dict, examples_dict, allowed_aspects): # modifies aggregated_dict directly sorted_layers = tuple(sorted(layers)) if allowed_aspects != 'all': # relabel layers to 0...k relabeling = dict() for ii, orig_layer in enumerate(sorted_layers): relabeling[orig_layer] = ii subnet = pn.transforms.relabel(pn.subnet(M, nodes, layers), layerNames=relabeling) complete_invariant = pn.get_complete_invariant( subnet, allowed_aspects=allowed_aspects) else: subnet = pn.subnet(M, nodes, layers) complete_invariant = pn.get_complete_invariant( subnet, allowed_aspects=allowed_aspects) aggregated_dict[complete_invariant][ sorted_layers] = aggregated_dict[complete_invariant].get( sorted_layers, 0) + 1 if isinstance(examples_dict, dict): if complete_invariant not in examples_dict: examples_dict[complete_invariant] = subnet return
def orbit_name(node, net, nets, invs, auts, allowed_aspects='all'): ''' finds the name of the orbit given node and net ''' ci = str( pymnet.get_complete_invariant(net, allowed_aspects=allowed_aspects)) i, j = invs[ci] net_i = nets[i][j] iso = pymnet.get_isomorphism(net, net_i, allowed_aspects=allowed_aspects, include_fixed=True) k = auts[i, j, iso[0][node]] return (i, j, k)
def compute_uniqueness(net): """ This function computes the percentage of unique structures in a network (with one layers). It extracts the neighborhood of every node and maps them to an isomorphism class, represented by complete graph invariant (equivalent to a canonical labelling). It then stores the number of neighborhoods for each isomorphism class (in a dictionary with the complete invariant as a key), and return the number of classes occcuring just one time Parameters ---------- net : Multilayer network (also single-layer networks are acceptable) the network Returns -------- float the percentage of unique neighborhoods in the graph (e.g.: 1.00 if all the neighborhoods have unique structures, 0.00 if there no unique structures) """ dic_layer_1_neigh = {} #dictionary to store the list of neighbors for every node for n in list(net): #list of nodes dic_layer_1_neigh[n] = [] #store the list of neighbors of every node for e in list(net.edges): if e[0] != e[1]: dic_layer_1_neigh[e[0]].append(e[1]) dic_layer_1_neigh[e[1]].append(e[0]) dic_count_n = {} #dictionary to store the number of occurences for each isomorphism class for k in dic_layer_1_neigh.keys(): #go through all nodes neigh_net = pymnet.MultilayerNetwork(aspects=0) #create a temporary network to store the neighborhood of a node for neigh in dic_layer_1_neigh[k]: #go through the neighbors for sec_neigh in dic_layer_1_neigh[neigh]: #go trough the neighbors of the neighbor if sec_neigh in dic_layer_1_neigh[k]: #if the node neigh_net[neigh, sec_neigh] = 1 #this adds an edge between the two nodes compl_inv_n = str(pymnet.get_complete_invariant(neigh_net)) #compute the complete invariant #increment the count of isomorphism classes try: dic_count_n[compl_inv_n] += 1 except KeyError, e: dic_count_n[compl_inv_n] = 1
class test_subgraph_classification(unittest.TestCase): testnet = pn.MultilayerNetwork(aspects=1, fullyInterconnected=False) testnet[1, 2, 0, 0] = 1 testnet[1, 1, 0, 1] = 1 testnet[3, 3, 1, 2] = 1 testnet[3, 4, 2, 2] = 1 testnet[1, 5, 0, 0] = 1 testnet[6, 7, 2, 2] = 1 testnet[6, 6, 2, 3] = 1 testnet[7, 7, 2, 3] = 1 testnet[8, 9, 2, 2] = 1 testnet[9, 9, 2, 3] = 1 subnet1 = pn.MultilayerNetwork(aspects=1, fullyInterconnected=False) subnet1['a', 'b', 0, 0] = 1 subnet1['a', 'a', 0, 1] = 1 subnet2 = pn.MultilayerNetwork(aspects=1, fullyInterconnected=False) subnet2['a', 'b', 0, 0] = 1 subnet2['a', 'a', 0, 1] = 1 subnet2['b', 'b', 0, 1] = 1 subnet3 = pn.MultilayerNetwork(aspects=1, fullyInterconnected=False) subnet3['a', 'b', 1, 1] = 1 subnet3['a', 'a', 0, 1] = 1 # nodelayer isomorphisms compinv1 = pn.get_complete_invariant(subnet1) compinv2 = pn.get_complete_invariant(subnet2) # node isomorphisms node_compinv1 = pn.get_complete_invariant(subnet1, [0]) node_compinv2 = pn.get_complete_invariant(subnet2, [0]) node_compinv3 = pn.get_complete_invariant(subnet3, [0]) def test_find_isomorphism_classes_with_aggregated_dict(self): dd = collections.defaultdict(dict) subgraph_classification.find_isomorphism_classes( self.testnet, 2, 2, 'this_file_should_not_exist', 'all', dd, None) self.assertEqual(len(dd), 2) self.assertEqual(dd[self.compinv1], {(0, 1): 2, (1, 2): 1, (2, 3): 1}) self.assertEqual(dd[self.compinv2], {(2, 3): 1}) def test_find_isomorphism_classes_agg_dict_node_isomorphism_example_dicts( self): # test a) aggregated dict, b) node isomorphism, c) example generation dd = collections.defaultdict(dict) dd_e = dict() subgraph_classification.find_isomorphism_classes( self.testnet, 2, 2, 'this_file_should_not_exist', [0], dd, dd_e) self.assertEqual(len(dd), 3) self.assertEqual(dd[self.node_compinv1], {(0, 1): 2, (2, 3): 1}) self.assertEqual(dd[self.node_compinv2], {(2, 3): 1}) self.assertEqual(dd[self.node_compinv3], {(1, 2): 1}) self.assertEqual(len(dd_e), 3) self.assertEqual( pn.get_complete_invariant(dd_e[self.node_compinv1], [0]), self.node_compinv1) self.assertEqual( pn.get_complete_invariant(dd_e[self.node_compinv2], [0]), self.node_compinv2) self.assertEqual( pn.get_complete_invariant(dd_e[self.node_compinv3], [0]), self.node_compinv3) self.assertEqual(pn.get_complete_invariant(dd_e[self.node_compinv1]), self.compinv1) self.assertEqual(pn.get_complete_invariant(dd_e[self.node_compinv2]), self.compinv2) self.assertEqual(pn.get_complete_invariant(dd_e[self.node_compinv3]), self.compinv1)
def orbit_equations(n, nets, auts, invs, allowed_aspects='all'): ''' Generate orbit equations for up to n nodes The equations are in following formatting: orbits : this represents node orbits of graphlets Parameters ---------- n : int maximum number of nodes nets : dict (key: n_nodes, value: list of nets) graphlets, as returned by graphlets auts : dd (key: (n_nodes, net_index, node), value: node) automorphisms, as returned by automorphism_orbits invs : dict (key: str(complete invariant), value: tuple(n_nodes, net_index in nets)) complete invariants of the graphlets, as returned by graphlets allowed_aspects : list, string the aspects that can be permutated when computing isomorphisms Returns ------- orbit_eqs : dict (key: orbits, value: dict (key: orbit, value: coefficient)) ''' orbit_eqs = dd() orbit_lists = list_orbits(auts) for n_nodes1 in range(2, min(n + 1, 4)): for orbit in orbit_lists[n_nodes1]: node1 = orbit[2] for n_nodes in orbit_lists: comb_n_nodes = n_nodes1 + n_nodes - 1 if comb_n_nodes <= n: for orbit2 in orbit_lists[n_nodes]: if ((orbit, 1), (orbit2, 1)) in orbit_eqs: continue new_nets = {} new_orbits = set() comb_nets = combine_orbits( orbit, orbit2, nets, allowed_aspects=allowed_aspects) if comb_nets == None: continue for k in range(len(comb_nets)): comb_nets[k] = (comb_nets[k], [node1]) merge_nets = {} min_nodes = max([n_nodes1, n_nodes]) + 1 merge_nets[comb_n_nodes] = comb_nets for m in range( comb_n_nodes, min_nodes, -1 ): #TODO: make this merge thingy smarter, use combinations merge_nets[m - 1] = [] for m_net in merge_nets[m]: merge_nets[m - 1] += merge_nodes( m_net[1], m_net[0], allowed_aspects=allowed_aspects) comb_nets += merge_nets[m - 1] add_e_nets = [] for k in range(len(comb_nets)): c_net = comb_nets[k][0] both_orbit_nodes = comb_nets[k][1] nets_e = add_possible_edges( both_orbit_nodes, c_net) for net_e in nets_e: add_e_nets.append((net_e, both_orbit_nodes)) comb_nets += add_e_nets for comb_net in comb_nets: ci_comb = str( pymnet.get_complete_invariant( comb_net[0], allowed_aspects=allowed_aspects)) iso_net = invs[ci_comb] iso = pymnet.get_isomorphism( comb_net[0], nets[iso_net[0]][iso_net[1]], allowed_aspects=allowed_aspects) if node1 in iso[0]: node_o = iso[0][node1] else: node_o = node1 new_orbit = (iso_net[0], iso_net[1], auts[iso_net[0], iso_net[1], node_o]) if not new_orbit in new_orbits: new_orbits.add(new_orbit) new_nets[new_orbit] = comb_net if orbit == orbit2: times = 2 key = ((orbit, times)) else: times = 1 key = ((orbit2, 1), (orbit, 1)) orbit_eqs[key] = {} for i in new_orbits: coef = coefficient(node1, new_nets[i][1], orbit, orbit2, new_nets[i][0], nets, auts, invs, allowed_aspects=allowed_aspects) if coef > 0: orbit_eqs[key][i] = coef return orbit_eqs
def merge_nodes(both_orbit_nodes, net, allowed_aspects='all'): ''' Merges nodes from different orbits, each returned network has different combination of nodes merged, merges only one pair of nodes Parameters ---------- both_orbit_nodes : list of nodes net : network allowed_aspects : list, string the aspects that can be permutated when computing isomorphisms Returns ------- new_nets_and_nodes : list of tuples (net, both_orbit_nodes) Notes ----- assumes negative nodes belong to the same orbit works for both multiplex and multilayer networks (1 aspect) ''' nodes_a = net.slices[0] nodes = nodes_a - set(both_orbit_nodes) nodes1 = [] nodes2 = [] for node in nodes: if node < 0: nodes2.append(node) else: nodes1.append(node) layers = net.slices[1] new_nets_and_nodes = [] new_nets = [] new_invs = set() for comb in itertools.product(nodes1, nodes2): node1 = comb[0] node2 = comb[1] l1 = set() l2 = set() for nl in net.iter_node_layers(): if nl[0] == node1: l1.add(nl[1]) elif nl[0] == node2: l2.add(nl[1]) if not (l1 <= l2 and l1 >= l2): #nodes not present in the same layers continue nodes_s1 = both_orbit_nodes + [node1] nodes_s2 = both_orbit_nodes + [node2] sub1 = pymnet.subnet(net, nodes_s1, layers) sub2 = pymnet.subnet(net, nodes_s2, layers) if not pymnet.is_isomorphic( sub1, sub2, allowed_aspects=[0]): #not same links to the_node continue nodes_s = nodes_a - set([node2]) new_net = pymnet.subnet(net, nodes_s, layers) for layer in layers: node2_o = net.__getitem__((node2, layer)) for neighbor in node2_o.iter_total(): if neighbor[0] != node2: new_net[node1, neighbor[0], layer, neighbor[1]] = 1 ci = str( pymnet.get_complete_invariant(new_net, allowed_aspects=allowed_aspects)) if not ci in new_invs: new_nets.append(new_net) new_nets_and_nodes.append((new_net, both_orbit_nodes + [node1])) new_invs.add(ci) return new_nets_and_nodes
def combine_orbits(orbit1, orbit2, nets, allowed_aspects='all'): ''' Combines orbits orbit1 and orbit2 Parameters ---------- orbit1, orbit2: tuple (n_nodes, net_index, node) nets: dict (key: n_nodes, value: list of networks) graphlets allowed_aspects : list, string the aspects that can be permutated when computing isomorphisms Returns ------- new_nets: list of networks, None networks obtained by combining the orbits (no links added, no merging of nodes), returns None if orbits cannot be combined (graphlets have different layers) Notes ----- atm works only with node-layer isomorphisms, now also vertex isomorphisms node1 will be the_node ''' net1 = nets[orbit1[0]][orbit1[1]] net2 = nets[orbit2[0]][orbit2[1]] node1 = orbit1[2] node2 = orbit2[2] nodeNames = {} layerNames = {} nodeNames[node2] = node1 nodes2 = net2.slices[0] n_nodes2 = len(nodes2) nodes1 = net1.slices[0] layers1 = net1.slices[1] layers2 = net2.slices[1] if layers1 != layers2: return None for (nodeName, newName) in zip( nodes2 - set([node2]), range(-2, -n_nodes2 - 1, -1)): # could be changed to range(-1,-n_nodes2,-1)? nodeNames[nodeName] = newName new_nets = [] new_invs = set() new_net = pymnet.subnet(net1, nodes1, layers1) net2_r = pymnet.transforms.relabel(net2, nodeNames, layerNames) for e in net2_r.edges: if e[0] != e[1]: new_net[e[0], e[1], e[2], e[3]] = e[4] new_nets.append(new_net) ci = str( pymnet.get_complete_invariant(new_net, allowed_aspects=allowed_aspects)) new_invs.add(ci) if allowed_aspects != [0]: for perm in itertools.permutations(layers2, len(layers2)): for i in range(len(perm)): layerNames[perm[i - 1]] = perm[i] new_net = pymnet.subnet(net1, nodes1, layers1) net2_r = pymnet.transforms.relabel(net2, nodeNames, layerNames) for e in net2_r.edges: if e[0] != e[1]: new_net[e[0], e[1], e[2], e[3]] = e[4] ci = str( pymnet.get_complete_invariant(new_net, allowed_aspects=allowed_aspects)) if not ci in new_invs: new_nets.append(new_net) new_invs.add(ci) return new_nets
def coefficient_help(nodes, the_node, both_orbit_nodes, orbit1, orbit2, net, nets, auts, invs, allowed_aspects='all'): ''' helper function for coefficient ''' coef = 0 nodes_a = net.slices[0] layers = net.slices[1] net1 = nets[orbit1[0]][orbit1[1]] net2 = nets[orbit2[0]][orbit2[1]] n_nodes1 = len(net1.slices[0]) for node_comb in itertools.combinations(nodes, n_nodes1 - len(both_orbit_nodes)): nodes_s2 = nodes_a - set(node_comb) nodes_s1 = (nodes_a - nodes_s2) | set(both_orbit_nodes) sub1 = pymnet.subnet(net, nodes_s1, layers) sub2 = pymnet.subnet(net, nodes_s2, layers) ci_sub1 = str( pymnet.get_complete_invariant(sub1, allowed_aspects=allowed_aspects)) ci_sub2 = str( pymnet.get_complete_invariant(sub2, allowed_aspects=allowed_aspects)) if not ci_sub1 in invs or not ci_sub2 in invs: continue if invs[ci_sub1] == (orbit1[0], orbit1[1]) and invs[ci_sub2] == (orbit2[0], orbit2[1]): iso1 = pymnet.get_isomorphism(sub1, net1, allowed_aspects=allowed_aspects) iso2 = pymnet.get_isomorphism(sub2, net2, allowed_aspects=allowed_aspects) if the_node in iso1[0]: iso_node1 = iso1[0][the_node] else: iso_node1 = the_node if the_node in iso2[0]: iso_node2 = iso2[0][the_node] else: iso_node2 = the_node if auts[orbit1[0], orbit1[1], iso_node1] == orbit1[2] and auts[orbit2[0], orbit2[1], iso_node2] == orbit2[2]: coef += 1 return coef
def plot_complete_invariant_average_time_series(subnet_filename_list, title, xlabel, ylabel, savename=None, examples_filename=None, map_ni_to_nli=False, yscale='log', colormap=plt.cm.jet, **kwargs): compinv_timeseries_dict_list = [] layersets = set() invariants = set() for filename in subnet_filename_list: f = open(filename, 'r') complete_invariant_timeseries_dict = pickle.load(f) f.close() for key in complete_invariant_timeseries_dict: invariants.add(key) layersets.update( [key2 for key2 in complete_invariant_timeseries_dict[key]]) compinv_timeseries_dict_list.append(complete_invariant_timeseries_dict) if examples_filename is not None: invdicts = complete_invariant_dicts.load_example_nets_file( examples_filename) else: nnodes = int(subnet_filename_list[0].split('/')[-1].strip()[0]) nlayers = int(subnet_filename_list[0].split('/')[-1].strip()[2]) example_nets_filename = 'example_nets/' + str(nnodes) + '_' + str( nlayers) + '.pickle' invdicts = complete_invariant_dicts.load_example_nets_file( example_nets_filename) layersets = list(layersets) layersets.sort() full_range = zip(*(range(layersets[0][0], layersets[-1][-1] + 1)[ii:] for ii in range(len(layersets[0])))) if layersets != full_range: layersets = full_range x_axis = list(range(layersets[0][0], layersets[-1][1])) if map_ni_to_nli: invariants = set() mapped_invdicts = dict() mapped_compinv_timeseries_dict_list = [] for complete_invariant_timeseries_dict in compinv_timeseries_dict_list: mapped_complete_invariant_timeseries_dict = dict() for complete_invariant in complete_invariant_timeseries_dict: nl_complete_invariant = pn.get_complete_invariant( invdicts[complete_invariant]) if nl_complete_invariant not in mapped_invdicts: mapped_invdicts[nl_complete_invariant] = invdicts[ complete_invariant] invariants.add(nl_complete_invariant) mapped_complete_invariant_timeseries_dict[ nl_complete_invariant] = mapped_complete_invariant_timeseries_dict.get( nl_complete_invariant, dict()) for tw in complete_invariant_timeseries_dict[ complete_invariant]: mapped_complete_invariant_timeseries_dict[ nl_complete_invariant][ tw] = mapped_complete_invariant_timeseries_dict[ nl_complete_invariant].get( tw, 0) + complete_invariant_timeseries_dict[ complete_invariant][tw] mapped_compinv_timeseries_dict_list.append( mapped_complete_invariant_timeseries_dict) compinv_timeseries_dict_list = mapped_compinv_timeseries_dict_list invdicts = mapped_invdicts number_of_invariants = len(invariants) grid_side_length = 0 while grid_side_length**2 < number_of_invariants: grid_side_length = grid_side_length + 1 ax_locs = list( itertools.product(range(grid_side_length), range(grid_side_length, 2 * grid_side_length))) fig = plt.figure(figsize=(12, 6)) main_ax = plt.subplot2grid((grid_side_length, 2 * grid_side_length), (0, 0), rowspan=grid_side_length, colspan=grid_side_length) colorcycler = plt.cycler('color', colormap(np.linspace(0, 1, number_of_invariants))) main_ax.set_prop_cycle(colorcycler) for ii, compinv in enumerate(sorted(invariants)): y_values = [] std_values = [] for layerset in layersets: temp_layerset_vals = [] for compinv_timeseries_dict in compinv_timeseries_dict_list: if compinv in compinv_timeseries_dict: temp_layerset_vals.append( compinv_timeseries_dict[compinv].get(layerset, 0)) else: temp_layerset_vals.append(0) y_values.append(np.mean(temp_layerset_vals)) std_values.append(np.std(temp_layerset_vals)) line = main_ax.plot(x_axis, y_values, label=str(ii)) main_ax.fill_between(x_axis, np.subtract(y_values, std_values), np.add(y_values, std_values), facecolor=line[0].get_color(), alpha=0.2) compinv_ax = plt.subplot2grid((grid_side_length, 2 * grid_side_length), ax_locs[ii], projection='3d') M = invdicts[compinv] pn.draw(M, layout='shell', alignedNodes=True, ax=compinv_ax, layerLabelRule={}, nodeLabelRule={}) if grid_side_length < 3: legend_loc = 'lower left' else: legend_loc = (0, 0) leg = compinv_ax.legend(labels=[''], loc=legend_loc, handles=line, frameon=False) plt.setp(leg.get_lines(), linewidth=4) main_ax.set_xticks(x_axis) main_ax.set_xticklabels(layersets, rotation=90, fontsize='small') main_ax.set_yscale(yscale) main_ax.set_xlabel(xlabel) main_ax.set_ylabel(ylabel) main_ax.set_title(title) main_ax.margins(y=0.2) main_ax.set_xlim([x_axis[0], x_axis[-1]]) plt.tight_layout() if savename == None: plt.show() else: plt.savefig(savename, format='pdf')
def plot_complete_invariant_time_series(subnet_filename, title, xlabel, ylabel, savename=None, examples_filename=None, map_ni_to_nli=False, colormap=plt.cm.jet, **kwargs): M = pn.MultilayerNetwork(aspects=1, fullyInterconnected=False) M['a', 'b', 0, 0] = 1 M['a', 'a', 0, 1] = 1 #layersetwise_complete_invariants = dict() complete_invariant_timeseries_dict = dict() layersets = set() invariants = set() if subnet_filename.strip()[-10:] == 'agg.pickle': f = open(subnet_filename, 'r') complete_invariant_timeseries_dict = pickle.load(f) f.close() for key in complete_invariant_timeseries_dict: invariants.add(key) layersets.update( [key2 for key2 in complete_invariant_timeseries_dict[key]]) else: for subnet_data in subgraph_classification.yield_subnet_with_complete_invariant( subnet_filename): nodes = tuple(subnet_data[0]) layers = tuple(sorted(subnet_data[1])) complete_invariant = subnet_data[2] layersets.add(layers) invariants.add(complete_invariant) #layersetwise_complete_invariants[layers] = layersetwise_complete_invariants.get(layers,dict()) #layersetwise_complete_invariants[layers][complete_invariant] = layersetwise_complete_invariants[layers].get(complete_invariant,0) + 1 complete_invariant_timeseries_dict[ complete_invariant] = complete_invariant_timeseries_dict.get( complete_invariant, dict()) complete_invariant_timeseries_dict[complete_invariant][ layers] = complete_invariant_timeseries_dict[ complete_invariant].get(layers, 0) + 1 layersets = list(layersets) layersets.sort() full_range = zip(*(range(layersets[0][0], layersets[-1][-1] + 1)[ii:] for ii in range(len(layersets[0])))) if layersets != full_range: layersets = full_range x_axis = list(range(layersets[0][0], layersets[-1][1])) # load example networks if examples_filename is not None: f = open(examples_filename, 'r') invdicts = pickle.load(f) f.close() else: nnodes = int(subnet_filename.split('/')[-1].strip()[0]) nlayers = int(subnet_filename.split('/')[-1].strip()[2]) example_nets_filename = 'example_nets/' + str(nnodes) + '_' + str( nlayers) + '.pickle' invdicts = complete_invariant_dicts.load_example_nets_file( example_nets_filename) # map node isomorphisms to nodelayer isomorphisms: if map_ni_to_nli: invariants = set() mapped_invdicts = dict() mapped_complete_invariant_timeseries_dict = dict() for complete_invariant in complete_invariant_timeseries_dict: nl_complete_invariant = pn.get_complete_invariant( invdicts[complete_invariant]) if nl_complete_invariant not in mapped_invdicts: mapped_invdicts[nl_complete_invariant] = invdicts[ complete_invariant] invariants.add(nl_complete_invariant) mapped_complete_invariant_timeseries_dict[ nl_complete_invariant] = mapped_complete_invariant_timeseries_dict.get( nl_complete_invariant, dict()) for tw in complete_invariant_timeseries_dict[complete_invariant]: mapped_complete_invariant_timeseries_dict[ nl_complete_invariant][ tw] = mapped_complete_invariant_timeseries_dict[ nl_complete_invariant].get( tw, 0) + complete_invariant_timeseries_dict[ complete_invariant][tw] complete_invariant_timeseries_dict = mapped_complete_invariant_timeseries_dict invdicts = mapped_invdicts # needed numbers of example figures number_of_invariants = len(invariants) grid_side_length = 0 while grid_side_length**2 < number_of_invariants: grid_side_length = grid_side_length + 1 ax_locs = list( itertools.product(range(grid_side_length), range(grid_side_length, 2 * grid_side_length))) # figure fig = plt.figure(figsize=(12, 6)) main_ax = plt.subplot2grid((grid_side_length, 2 * grid_side_length), (0, 0), rowspan=grid_side_length, colspan=grid_side_length) colorcycler = plt.cycler('color', colormap(np.linspace(0, 1, number_of_invariants))) main_ax.set_prop_cycle(colorcycler) # side_ax = plt.subplot2grid((2,4),(0,2),projection='3d') # side_ax2 = plt.subplot2grid((2,4),(0,3),projection='3d') #plt.hold(True) # identifiers for legend ids = range(len(invariants)) for ii, compinv in enumerate( sorted(complete_invariant_timeseries_dict.iterkeys())): y_values = [] for layerset in layersets: y_values.append(complete_invariant_timeseries_dict[compinv].get( layerset, 0)) #main_ax = plt.subplot2grid((2,4),(0,0),rowspan=2,colspan=2) #main_ax.plot(x_axis,y_values,label=str(compinv)) line = main_ax.plot(x_axis, y_values, label=str(ii)) compinv_ax = plt.subplot2grid((grid_side_length, 2 * grid_side_length), ax_locs[ii], projection='3d') #example_ax = plt.gcf().add_axes((1.1,0,0.5,0.5),projection='3d') M = invdicts[compinv] pn.draw(M, layout='shell', alignedNodes=True, ax=compinv_ax, layerLabelRule={}, nodeLabelRule={}) #compinv_ax.text2D(0,0,str(ii),None,False,transform=compinv_ax.transAxes) if grid_side_length < 3: legend_loc = 'lower left' else: legend_loc = (0, 0) leg = compinv_ax.legend(labels=[''], loc=legend_loc, handles=line, frameon=False) plt.setp(leg.get_lines(), linewidth=4) # if ii==0: # pn.draw(M,ax=side_ax) # else: # pn.draw(M,ax=side_ax2) #plt.sca(fig.gca()) # plt.xticks(x_axis,layersets,rotation=90,fontsize='small') # plt.xlabel(xlabel) # plt.ylabel(ylabel) # plt.title(title) # plt.legend(bbox_to_anchor=(1.05,1.),loc=0,fontsize='xx-small') # plt.yscale('log') # plt.margins(y=0.2) # plt.xlim([x_axis[0],x_axis[-1]]) # plt.tight_layout() # plt.show() main_ax.set_xticks(x_axis) main_ax.set_xticklabels(layersets, rotation=90, fontsize='small') main_ax.set_yscale('log') main_ax.set_xlabel(xlabel) main_ax.set_ylabel(ylabel) main_ax.set_title(title) #main_ax.legend(bbox_to_anchor=(1.05,0),loc='upper left',ncol=number_of_invariants,fontsize='small') #main_ax.yscale('log') main_ax.margins(y=0.2) main_ax.set_xlim([x_axis[0], x_axis[-1]]) plt.tight_layout() if savename == None: plt.show() else: plt.savefig(savename, format='pdf')
def orbit_counts_all(net, n, nets, invs, auts, orbit_list, allowed_aspects='all'): ''' Computes the orbit counts for all the nodes in net Parameters ---------- net : network n : int max number of nodes nets : dict (key: n_nodes, value: list of networks) Graphlets, as produced by graphlets invs : dict (key: str(complete invariant), value: tuple(n_nodes, net_index in nets)) complete invariants of the graphlets, as produced by graphlet auts : dd (key: (n_nodes, net_index, node), value: node) automorphisms, as produced by automorphism_orbits orbit_list : list of orbits as returned by ordered_orbit_list allowed_aspects : list, string the aspects that can be permutated when computing isomorphisms Returns ------- orbits : dd (key: (node, orbit), value: count) Orbit counts for all the nodes Notes ----- Should be faster than orbit_counts if the counts are computed for all (/ most of) the nodes ''' nodes = net.slices[0] layers = net.slices[1] orbits = dd() for node in nodes: for orbit in orbit_list: orbits[node, orbit] = 0 processed = set() for node0 in nodes: node_sets = set() set_p = set([frozenset([node0])]) for _ in range(n - 1): set_c = set() for p in set_p: for node_p in p: for layer in layers: node_o = net.__getitem__((node_p, layer)) for neighbor in node_o.iter_total(): if not (neighbor[0] in p or neighbor[0] in processed): set_n = frozenset(p | set([neighbor[0]])) set_c.add(set_n) node_sets = node_sets.union(set_c) set_p = set_c.copy() processed.add(node0) for node_comb in node_sets: sub_net = pymnet.subnet(net, node_comb, layers) ci_sub = str( pymnet.get_complete_invariant(sub_net, allowed_aspects=allowed_aspects)) if ci_sub not in invs: pymnet.draw(sub_net) print(len(invs)) i = invs[ci_sub][0] j = invs[ci_sub][1] nw = nets[i][j] iso = pymnet.get_isomorphism(sub_net, nw, allowed_aspects=allowed_aspects) for node in node_comb: if node in iso[0]: orbits[node, (i, j, auts[i, j, iso[0][node]])] += 1 else: orbits[node, (i, j, auts[i, j, node])] += 1 for layer in layers: nls = list(net[node0, :, layer]) for node1 in nls: net[node0, node1[0], layer] = 0 #remove edges return orbits
def graphlets(n, layers, n_l=None, couplings=None, allowed_aspects="all"): ''' Generate graphlets up to n nodes Parameters ---------- n : int maximum number of nodes layers : list of layers n_l : int Number of layers in the generated graphlets, can be smaller than or equal to the number of elements in layers couplings : list, str, tuple, None, MultilayerNetwork Parameter determining how the layers are coupled, i.e. what inter-layer edges are present. allowed_aspects : list, string the aspects that can be permutated when computing isomorphisms Returns ------- nets : dict (key: n_nodes, value: list of MultiplexNetwork objects) graphlets invariants : dict (key: str(complete invariant), value: tuple(index in 'nets': n_nodes, index in the list of multiplex networks)) complete invariants of the graphlets, the values can be used to match the graphlets in 'nets' ''' if n_l == None: n_l = len(layers) nets = {} invariants = {} nets2 = [] for net_layers in itertools.combinations(layers, n_l): layer_combs = layer_combinations(net_layers) for layer_comb in layer_combs: net = pymnet.MultiplexNetwork(couplings=couplings, fullyInterconnected=True) for layer in layer_comb: net[0, 1, layer] = 1 for layer in net_layers: net.add_layer(layer) ci = pymnet.get_complete_invariant(net, allowed_aspects=allowed_aspects) ci_s = str(ci) if not ci_s in invariants: invariants[ci_s] = (2, len(nets2)) nets2.append(net) nets[2] = nets2 for i in range(2, n): nets_i = nets[i] nets_i_1 = [] for net in nets_i: net_nodes = net.slices[0] net_layers = list(net.slices[1]) net_layers.sort() layer_combs = layer_combinations(net_layers) for n_n in range(1, i + 1): for node_comb in itertools.combinations(range(i), n_n): node_layers = [layer_combs] * n_n for node_layer_comb in itertools.product(*node_layers): new_net = pymnet.subnet(net, net_nodes, net_layers) for node_i in range(n_n): node = node_comb[node_i] for layer in node_layer_comb[node_i]: new_net[node, i, layer] = 1 for layer in net_layers: new_net.add_layer(layer) # check if isomorphic with a previous graph & add only if not isomorphic ci = pymnet.get_complete_invariant( new_net, allowed_aspects=allowed_aspects) ci_s = str(ci) if not ci_s in invariants: invariants[ci_s] = (i + 1, len(nets_i_1)) nets_i_1.append(new_net) nets[i + 1] = nets_i_1 return nets, invariants