def gcoef(W): #strength s = np.sum(W, axis=1) #neighbor community affiliation Gc = np.inner((W != 0), np.diag(ci)) #community specific neighbors Sc2 = np.zeros((n,)) #extra modular weighting ksm = np.zeros((n,)) #intra modular wieghting centm = np.zeros((n,)) if centrality_type == 'degree': cent = s.copy() elif centrality_type == 'betweenness': cent = betweenness_wei(invert(W)) nr_modules = int(np.max(ci)) for i in range(1, nr_modules+1): ks = np.sum(W * (Gc == i), axis=1) print(np.sum(ks)) Sc2 += ks ** 2 for j in range(1, nr_modules+1): #calculate extramodular weights ksm[ci == j] += ks[ci == j] / np.sum(ks[ci == j]) #calculate intramodular weights centm[ci == i] = np.sum(cent[ci == i]) #print(Gc) #print(centm) #print(ksm) #print(ks) centm = centm / max(centm) #calculate total weights gs = (1 - ksm * centm) ** 2 Gw = 1 - Sc2 * gs / s ** 2 Gw[np.where(np.isnan(Gw))] = 0 Gw[np.where(np.logical_not(Gw))] = 0 return Gw
def gcoef(W): #strength s = np.sum(W, axis=1) #neighbor community affiliation Gc = np.inner((W != 0), np.diag(ci)) #community specific neighbors Sc2 = np.zeros((n, )) #extra modular weighting ksm = np.zeros((n, )) #intra modular wieghting centm = np.zeros((n, )) if centrality_type == 'degree': cent = s.copy() elif centrality_type == 'betweenness': cent = betweenness_wei(invert(W)) nr_modules = int(np.max(ci)) for i in range(1, nr_modules + 1): ks = np.sum(W * (Gc == i), axis=1) print(np.sum(ks)) Sc2 += ks**2 for j in range(1, nr_modules + 1): #calculate extramodular weights ksm[ci == j] += ks[ci == j] / np.sum(ks[ci == j]) #calculate intramodular weights centm[ci == i] = np.sum(cent[ci == i]) #print(Gc) #print(centm) #print(ksm) #print(ks) centm = centm / max(centm) #calculate total weights gs = (1 - ksm * centm)**2 Gw = 1 - Sc2 * gs / s**2 Gw[np.where(np.isnan(Gw))] = 0 Gw[np.where(np.logical_not(Gw))] = 0 return Gw
def efficiency_wei(Gw, local=False): ''' The global efficiency is the average of inverse shortest path length, and is inversely related to the characteristic path length. The local efficiency is the global efficiency computed on the neighborhood of the node, and is related to the clustering coefficient. Parameters ---------- W : NxN np.ndarray undirected weighted connection matrix (all weights in W must be between 0 and 1) local : bool If True, computes local efficiency instead of global efficiency. Default value = False. Returns ------- Eglob : float global efficiency, only if local=False Eloc : Nx1 np.ndarray local efficiency, only if local=True Notes ----- The efficiency is computed using an auxiliary connection-length matrix L, defined as L_ij = 1/W_ij for all nonzero L_ij; This has an intuitive interpretation, as higher connection weights intuitively correspond to shorter lengths. The weighted local efficiency broadly parallels the weighted clustering coefficient of Onnela et al. (2005) and distinguishes the influence of different paths based on connection weights of the corresponding neighbors to the node in question. In other words, a path between two neighbors with strong connections to the node in question contributes more to the local efficiency than a path between two weakly connected neighbors. Note that this weighted variant of the local efficiency is hence not a strict generalization of the binary variant. Algorithm: Dijkstra's algorithm ''' def distance_inv_wei(G): n = len(G) D = np.zeros((n, n)) # distance matrix D[np.logical_not(np.eye(n))] = np.inf for u in range(n): # distance permanence (true is temporary) S = np.ones((n,), dtype=bool) G1 = G.copy() V = [u] while True: S[V] = 0 # distance u->V is now permanent G1[:, V] = 0 # no in-edges as already shortest for v in V: W, = np.where(G1[v, :]) # neighbors of smallest nodes td = np.array( [D[u, W].flatten(), (D[u, v] + G1[v, W]).flatten()]) D[u, W] = np.min(td, axis=0) if D[u, S].size == 0: # all nodes reached break minD = np.min(D[u, S]) if np.isinf(minD): # some nodes cannot be reached break V, = np.where(D[u, :] == minD) np.fill_diagonal(D, 1) D = 1 / D np.fill_diagonal(D, 0) return D n = len(Gw) Gl = invert(Gw, copy=True) # connection length matrix A = np.array((Gw != 0), dtype=int) if local: E = np.zeros((n,)) # local efficiency for u in range(n): # V,=np.where(Gw[u,:]) #neighbors # k=len(V) #degree # if k>=2: #degree must be at least 2 # e=(distance_inv_wei(Gl[V].T[V])*np.outer(Gw[V,u],Gw[u,V]))**1/3 # E[u]=np.sum(e)/(k*k-k) # find pairs of neighbors V, = np.where(np.logical_or(Gw[u, :], Gw[:, u].T)) # symmetrized vector of weights sw = cuberoot(Gw[u, V]) + cuberoot(Gw[V, u].T) # inverse distance matrix e = distance_inv_wei(Gl[np.ix_(V, V)]) # symmetrized inverse distance matrix se = cuberoot(e) + cuberoot(e.T) numer = np.sum(np.outer(sw.T, sw) * se) / 2 if numer != 0: # symmetrized adjacency vector sa = A[u, V] + A[V, u].T denom = np.sum(sa)**2 - np.sum(sa * sa) # print numer,denom E[u] = numer / denom # local efficiency else: e = distance_inv_wei(Gl) E = np.sum(e) / (n * n - n) return E
def efficiency_wei(Gw, local=False): ''' The global efficiency is the average of inverse shortest path length, and is inversely related to the characteristic path length. The local efficiency is the global efficiency computed on the neighborhood of the node, and is related to the clustering coefficient. Parameters ---------- W : NxN np.ndarray undirected weighted connection matrix (all weights in W must be between 0 and 1) local : bool If True, computes local efficiency instead of global efficiency. Default value = False. Returns ------- Eglob : float global efficiency, only if local=False Eloc : Nx1 np.ndarray local efficiency, only if local=True Notes ----- The efficiency is computed using an auxiliary connection-length matrix L, defined as L_ij = 1/W_ij for all nonzero L_ij; This has an intuitive interpretation, as higher connection weights intuitively correspond to shorter lengths. The weighted local efficiency broadly parallels the weighted clustering coefficient of Onnela et al. (2005) and distinguishes the influence of different paths based on connection weights of the corresponding neighbors to the node in question. In other words, a path between two neighbors with strong connections to the node in question contributes more to the local efficiency than a path between two weakly connected neighbors. Note that this weighted variant of the local efficiency is hence not a strict generalization of the binary variant. Algorithm: Dijkstra's algorithm ''' def distance_inv_wei(G): n = len(G) D = np.zeros((n, n)) # distance matrix D[np.logical_not(np.eye(n))] = np.inf for u in xrange(n): # distance permanence (true is temporary) S = np.ones((n,), dtype=bool) G1 = G.copy() V = [u] while True: S[V] = 0 # distance u->V is now permanent G1[:, V] = 0 # no in-edges as already shortest for v in V: W, = np.where(G1[v, :]) # neighbors of smallest nodes td = np.array( [D[u, W].flatten(), (D[u, v] + G1[v, W]).flatten()]) D[u, W] = np.min(td, axis=0) if D[u, S].size == 0: # all nodes reached break minD = np.min(D[u, S]) if np.isinf(minD): # some nodes cannot be reached break V, = np.where(D[u, :] == minD) np.fill_diagonal(D, 1) D = 1 / D np.fill_diagonal(D, 0) return D n = len(Gw) Gl = invert(Gw, copy=True) # connection length matrix A = np.array((Gw != 0), dtype=int) if local: E = np.zeros((n,)) # local efficiency for u in xrange(n): # V,=np.where(Gw[u,:]) #neighbors # k=len(V) #degree # if k>=2: #degree must be at least 2 # e=(distance_inv_wei(Gl[V].T[V])*np.outer(Gw[V,u],Gw[u,V]))**1/3 # E[u]=np.sum(e)/(k*k-k) # find pairs of neighbors V, = np.where(np.logical_or(Gw[u, :], Gw[:, u].T)) # symmetrized vector of weights sw = cuberoot(Gw[u, V]) + cuberoot(Gw[V, u].T) # inverse distance matrix e = distance_inv_wei(Gl[np.ix_(V, V)]) # symmetrized inverse distance matrix se = cuberoot(e) + cuberoot(e.T) numer = np.sum(np.outer(sw.T, sw) * se) / 2 if numer != 0: # symmetrized adjacency vector sa = A[u, V] + A[V, u].T denom = np.sum(sa)**2 - np.sum(sa * sa) # print numer,denom E[u] = numer / denom # local efficiency else: e = distance_inv_wei(Gl) E = np.sum(e) / (n * n - n) return E