def diffusion_matrix(G, nodeList, npyFile, gamma=8): """ compute inverse of Laplacian matrix and symmetrize. (default gamma is arbitrary) the higher the influence, the closer we expect function to be, so let distances be reciprocal. """ if not npyFile or not os.path.isfile(npyFile): L = np.array(nx.laplacian_matrix(G,nodeList)) # depending on version of networkx, might get sparse matrix instead. if so, do this: if np.shape(L) == (): L = np.array(nx.laplacian_matrix(G,nodeList).todense()) m, n = np.shape(L) L = L + (np.eye(m, n)*gamma) D = np.linalg.inv(L) n = len(nodeList) for i in xrange(n): for j in xrange(i+1,n): D[i][j] = D[j][i] = 1/(min(D[i][j], D[j][i])) if npyFile: np.save(npyFile, D) else: D = np.load(npyFile) return D
def cheb_spectral_cut(CAC, start, F, G, beta, k, n, ind): """ Fast spectral cut implementation using chebyshev polynomials. Input: * CAC: C*A*C where C is the Laplacian of a complete graph and A is a pairwise squared difference matrix * start: initialization * F: graph signal * G: graph * L: graph laplacian matrix * beta: regularization parameter * k: max edges cut * n: number of polynomials * ind: vertex index vertex: unique integer Output: * res: dictionary with following fields: - x: indicator vector - size: number of edges cut - score: cut score - energy: cut energy """ L = networkx.laplacian_matrix(G) M = chebyshev_approx_2d(n, beta, CAC, L) eigvec = power_method(-M, start, 10) x = chebyshev_approx_1d(n, beta, eigvec, L) (x, score, size, energy) = sweep_opt(x, beta, F, G, k, ind) res = {} res["x"] = numpy.array(x) res["size"] = size res["score"] = score res["energy"] = energy return res
def create_laplacian_matrix(G): row = [] column = [] value = [] for t in range(G.num_snaps()): Lg = networkx.laplacian_matrix(G.snap(t)) for (i,j) in zip(*scipy.nonzero(Lg)): row.append(G.size()*t + i) column.append(G.size()*t + j) if i != j: value.append(Lg[i,j]) else: if t > 0 and t < G.num_snaps() - 1: value.append(Lg[i,j] + 2 * G.swap_cost()) else: value.append(Lg[i,j] + 1 * G.swap_cost()) for t in range(G.num_snaps()-1): for v in range(G.size()): row.append(t*G.size() + v) column.append((t+1)*G.size() + v) value.append(-1 * G.swap_cost()) column.append(t*G.size() + v) row.append((t+1)*G.size() + v) value.append(-1 * G.swap_cost()) sz = G.num_snaps() * G.size() return scipy.sparse.csr_matrix((value, (row, column)), shape=(sz, sz), dtype=float)
def MinCut(G): #Calcula a matriz laplaciana do grafo G #Opcionalmente, pode-se usar a laplaciana normalizada #lap = nx.normalized_laplacian(G) lap = nx.laplacian_matrix(G) eigenValues, eigenVectors = la.eigh(lap) orthoVector = [] #pega-se entao os componentes orthonormais dos #autovetores e cria-se um novo vetor for vectors in eigenVectors: orthoVector.append(vectors[1]) #para o Ratio-cut, usa-se a mediana para dividir #o grafo. #med = np.median(eigenVectors[1]) nodesleft = [] nodesright = [] #divide-se entao o grafo em 2 componentes, baseado no sinal #do vetor orthonormal. Compara-se a lista de nodos com o vetor. #Se o valor for maior que zero, vai pra uma componente, caso contrario, #vai pra outra. for node, vec in zip(G.nodes(), orthoVector): if(vec > 0): nodesleft.append(node) else: nodesright.append(node) return (nodesleft, nodesright)
def laplacian_spectrum(G, weight="weight"): """Return eigenvalues of the Laplacian of G Parameters ---------- G : graph A NetworkX graph weight : string or None, optional (default='weight') The edge data key used to compute each value in the matrix. If None, then each edge has weight 1. Returns ------- evals : NumPy array Eigenvalues Notes ----- For MultiGraph/MultiDiGraph, the edges weights are summed. See to_numpy_matrix for other options. See Also -------- laplacian_matrix """ try: import numpy as np except ImportError: raise ImportError("laplacian_spectrum() requires NumPy: http://scipy.org/ ") return np.linalg.eigvals(nx.laplacian_matrix(G, weight=weight))
def effective_resistance_project(G, beacons): from numpy.linalg import pinv projection = np.zeros((G.number_of_nodes() - len(beacons), len(beacons))) L = nx.laplacian_matrix(G) B = nx.incidence_matrix(G).T B_e = B.copy() L_pseudo = pinv(L) for i in xrange(B.shape[0]): min_ace = np.min(np.where(B[i,:] ==1)[1]) B_e[i, min_ace] = -1 for i,beacon in enumerate(beacons): node_index = 0 for j,node in enumerate(G.nodes()): if node in beacons: continue battery = np.zeros((B_e.shape[1],1)) battery[i] = 1 battery[node_index] = -1 p = L_pseudo * battery projection[node_index][i] = abs(p[i] - p[j]) node_index += 1 return projection
def etape(self, frontier, i_graph): """ Calculates the most probable seed within the infected nodes""" # Taking the actual submatrix, not the laplacian matrix. The change # lies in the total number of connections (The diagonal terms) for the # infected nodes connected to uninfected ones in the initial graph i_laplacian_matrix = nx.laplacian_matrix(i_graph) for i in range(0, len(i_graph.nodes())): if frontier.has_node(i_graph.nodes()[i]): i_laplacian_matrix[i, i] +=\ frontier.node[i_graph.nodes()[i]]['clear'] # SymPy Lm = Matrix(i_laplacian_matrix.todense()) i = self.Sym2NumArray(Matrix(Lm.eigenvects()[0][2][0])).argmax() # NumPy # val, vect = linalg.eigh(i_laplacian_matrix.todense()) #i = vect[0].argmax() # SciPY # val, vect = eigs(i_laplacian_matrix.rint()) # i = vect[:, 0].argmax() seed = (i_graph.nodes()[i]) return seed
def eig_vis_opt(G, F, beta): """ Computes first and second eigenvector of sqrt(C+beta*L)^T CAC sqrt(C+beta*L) matrix for visualization. Input: * G: graph * F: graph signal * beta: regularization parameter Output: * v1: first eigenvector * v2: second eigenvector """ ind = {} i = 0 for v in G.nodes(): ind[v] = i i = i + 1 C = laplacian_complete(networkx.number_of_nodes(G)) A = weighted_adjacency_complete(G, F, ind) CAC = numpy.dot(numpy.dot(C,A), C) L = networkx.laplacian_matrix(G).todense() isqrtCL = sqrtmi( C + beta * L) M = numpy.dot(numpy.dot(isqrtCL, CAC), isqrtCL) (eigvals, eigvecs) = scipy.linalg.eigh(M,eigvals=(0,1)) x1 = numpy.asarray(numpy.dot(eigvecs[:,0], isqrtCL))[0,:] x2 = numpy.asarray(numpy.dot(eigvecs[:,1], isqrtCL))[0,:] return x1, x2
def laplacian_spectrum(G, weight='weight'): """Return eigenvalues of the Laplacian of G Parameters ---------- G : graph A NetworkX graph weight : string or None, optional (default='weight') The edge data key used to compute each value in the matrix. If None, then each edge has weight 1. Returns ------- evals : NumPy array Eigenvalues Notes ----- For MultiGraph/MultiDiGraph, the edges weights are summed. See to_numpy_matrix for other options. See Also -------- laplacian_matrix """ from scipy.linalg import eigvals return eigvals(nx.laplacian_matrix(G,weight=weight).todense())
def test_abbreviation_of_method(self): G = nx.path_graph(8) A = nx.laplacian_matrix(G) sigma = 2 - sqrt(2 + sqrt(2)) ac = nx.algebraic_connectivity(G, tol=1e-12, method='tracemin') assert_almost_equal(ac, sigma) x = nx.fiedler_vector(G, tol=1e-12, method='tracemin') check_eigenvector(A, sigma, x)
def eig_vis_nc(G): L = networkx.laplacian_matrix(G).todense() (eigvals, eigvecs) = scipy.linalg.eigh(L,eigvals=(1,2)) x1 = numpy.asarray(eigvecs[:,0]) x2 = numpy.asarray(eigvecs[:,1]) return x1, x2
def ematrix(G,nodes): L = np.array(nx.laplacian_matrix(G,nodes)) # not using eig. gives very strange results for non-invertible matrices # which don't agree with matlab's eig. svd however gives sensible results u,s,vt = np.linalg.svd(L) s = 1/s s[np.where(np.abs(s)>1e9)]=0 s = np.sqrt(s) return np.dot(u,np.diag(s))
def test_cycle(self): G = nx.cycle_graph(8) A = nx.laplacian_matrix(G) sigma = 2 - sqrt(2) for method in self._methods: ac = nx.algebraic_connectivity(G, tol=1e-12, method=method) assert_almost_equal(ac, sigma) x = nx.fiedler_vector(G, tol=1e-12, method=method) check_eigenvector(A, sigma, x)
def my_algebraic_connectivity(graph, normalise=False): if normalise: eigvals, eigvecs = sp.sparse.linalg.eigsh(nx.normalized_laplacian_matrix(graph).asfptype(), 2, which='SA') a = eigvals[1] else: eigvals, eigvecs = sp.sparse.linalg.eigsh(nx.laplacian_matrix(graph).asfptype(), 2, which='SA') a = eigvals[1] if a < MACHINE_EPSILON: a = 0.0 return a
def test_problematic_graph_issue_2381(self): G = nx.path_graph(4) G.add_edges_from([(4, 2), (5, 1)]) A = nx.laplacian_matrix(G) sigma = 0.438447187191 for method in self._methods: ac = nx.algebraic_connectivity(G, tol=1e-12, method=method) assert_almost_equal(ac, sigma) x = nx.fiedler_vector(G, tol=1e-12, method=method) check_eigenvector(A, sigma, x)
def test_two_nodes(self): G = nx.Graph() G.add_edge(0, 1, weight=1) A = nx.laplacian_matrix(G) for method in self._methods: assert_almost_equal(nx.algebraic_connectivity( G, tol=1e-12, method=method), 2) x = nx.fiedler_vector(G, tol=1e-12, method=method) check_eigenvector(A, 2, x) G = nx.MultiGraph() G.add_edge(0, 0, spam=1e8) G.add_edge(0, 1, spam=1) G.add_edge(0, 1, spam=-2) A = -3 * nx.laplacian_matrix(G, weight='spam') for method in self._methods: assert_almost_equal(nx.algebraic_connectivity( G, weight='spam', tol=1e-12, method=method), 6) x = nx.fiedler_vector(G, weight='spam', tol=1e-12, method=method) check_eigenvector(A, 6, x)
def write_adj_mat(G, fileobj=sys.stdout): """Write G to a sparse matrix format that Julia and Matlab can read.""" lapmatrix = nx.laplacian_matrix(G) norm_lapl = nx.normalized_laplacian_matrix(G) adjmatrix = nx.adjacency_matrix(G) mdict = {'laplacian': lapmatrix, 'norm_lapl': norm_lapl, 'adjacency': adjmatrix} sio.savemat(fileobj, mdict) return mdict
def one_d_search(G, F, k, ind): """ Cut computation. Perform 1-D search for beta using golden search. Input: * G: graph * F: graph signal * k: max edges to be cut * n: number of chebyshev polynomials * ind: vertex index vertex: unique integer Output: * cut """ C = laplacian_complete(networkx.number_of_nodes(G)) A = weighted_adjacency_complete(G,F, ind) CAC = numpy.dot(numpy.dot(C,A), C) start = numpy.ones(networkx.number_of_nodes(G)) L = networkx.laplacian_matrix(G).todense() #Upper and lower bounds for search a = 0. b = 1000. c=b-gr*(b-a) d=a+gr*(b-a) #Tolerance tol = 1. resab = {} resab["size"] = k + 1 #golden search while abs(c-d)>tol or resab["size"] > k: resc = spectral_cut(CAC, L, C, A, start, F, G, c, k, ind) resd = spectral_cut(CAC, L, C, A, start, F, G, d, k, ind) if resc["size"] <= k: if resc["score"] > resd["score"]: start = numpy.array(resc["x"]) b = d d = c c=b-gr*(b-a) else: start = numpy.array(resd["x"]) a=c c=d d=a+gr*(b-a) else: start = numpy.array(resc["x"]) a=c c=d d=a+gr*(b-a) resab = spectral_cut(CAC, L, C, A, start, F, G, (b+a) / 2, k, ind) return resab
def spectral_clustering(A, args): ''' Function uses dimension reduction by spectral clustering to cluster with some cluster algorithm ''' if type(A) == np.ndarray: print 'Building graph...' G = nx.from_numpy_matrix(A) laplacian = nx.laplacian_matrix(G) elif type(A) == scsp.csc.csc_matrix: print 'Building graph...' G = nx.from_scipy_sparse_matrix(A) laplacian = nx.laplacian_matrix(G) print 'Start finding reduction...' max_eigvals = scspl.eigs(laplacian * 1.0, return_eigenvectors=False, k=args['dim'] + 10) alpha = np.amax(max_eigvals) modif_laplacian = alpha * scsp.eye(laplacian.shape[0], laplacian.shape[1]) - laplacian lap_eigval, lap_eigvec = scspl.eigs(modif_laplacian * 1.0, k=20) if args['show_eigenvalues']: print 'Show eigenvalues...' plt.scatter(np.array(range(len(lap_eigval))) + 1, np.sort(-lap_eigval.real + alpha, reverse = True), marker='.', s=90) plt.show() U = lap_eigvec[:, 0:args['dim']].real print 'Start clustering...' if U.shape[0] < 1000: clustering = skcl.KMeans(n_clusters=args['number_of_clusters']) clustering.fit(U) else: clustering = skcl.MiniBatchKMeans(n_clusters=args['number_of_clusters']) clustering.fit(U) center_person_cluster_id = clustering.labels_[args['index']] center_person_cluster = [i for i in xrange(len(clustering.labels_)) if clustering.labels_[i] == center_person_cluster_id] cluster = [[i for i in xrange(len(clustering.labels_)) if clustering.labels_[i] == j] for j in xrange(args['number_of_clusters'])] return center_person_cluster, cluster
def directED(G,nodes): # compute effective resistance directly. # when doing an entire graph, this is faster than the ELD approach L = nx.laplacian_matrix(G,nodes) Lplus = np.linalg.pinv(L) E = np.zeros(np.shape(L)) n = np.shape(L)[0] for i in xrange(n): for j in xrange(n): E[i,j] = Lplus[i,i]+Lplus[j,j]-Lplus[i,j]-Lplus[j,i] return E
def run(args): # Load input graph print "* Loading input graph..." with open(args.edgelist_file) as infile: G = nx.Graph() G.add_edges_from([map(int, l.rstrip().split()[:2]) for l in infile]) print "\t{} nodes with {} edges".format(len(G.nodes()), len(G.edges())) # Remove self-loops and zero degree nodes, and # restrict to the largest connected component print "* Removing self-loops, zero degree nodes, and ", print "restricting to the largest connected component" G.remove_edges_from([(u,v) for u, v in G.edges() if u == v]) G.remove_nodes_from([n for n in G.nodes() if G.degree(n) == 0]) G = G.subgraph(sorted(nx.connected_components( G ), key=lambda cc: len(cc), reverse=True)[0]) print "\t{} nodes with {} edges remaining".format(len(G.nodes()), len(G.edges())) # Load gene index indexToGene = hnio.load_index(args.gene_index_file) # Compute and save Laplacian if not os.path.exists(args.output_dir): os.makedirs(args.output_dir) print "* Computing Laplacian..." L = nx.laplacian_matrix(G) # Exponentiate the Laplacian for the given time and save it print "* Computing diffusion matrix..." Li = expm_eig( -args.time * L.todense() ) #Li = sp.sparse.linalg.expm( -args.time * L) output_prefix = "{}/{}_inf_{}".format(args.output_dir, args.prefix, args.time) if args.format == 'hdf5': hnio.save_hdf5(output_prefix + ".h5", dict(Li=Li)) elif args.format == 'npy': np.save(output_prefix + ".npy", Li) # Save the index to gene mapping indexOutputFile = "{}/{}_index_genes".format(args.output_dir, args.prefix) nodes = G.nodes() geneIndexOutput = ["{} {}".format(i+args.start_index, indexToGene[node]) for i, node in enumerate(nodes)] hnio.write_file(indexOutputFile, "\n".join(geneIndexOutput)) # Create edge list with revised indices edgeIndices = [] for u, v in G.edges(): i = nodes.index(u) + args.start_index j = nodes.index(v) + args.start_index edgeIndices.append( sorted([i, j]) ) edgeOutputFile = "{}/{}_edge_list".format(args.output_dir, args.prefix) edgeOutput = ["{} {} 1".format(u, v) for u, v in edgeIndices] hnio.write_file(edgeOutputFile, "\n".join(edgeOutput))
def eigenratio (G): if nx.is_connected(G): # Calculate the eigenrato (lambda_N/lambda_2) L = nx.laplacian_matrix(G) eigenvalues, eigenvectors = np.linalg.eig(L) idx = eigenvalues.argsort() eigenvalues = eigenvalues[idx] return eigenvalues[-1] / eigenvalues[1] else: # If the network is not connected it is not valid return float('inf')
def find_resistance(G, node): G1 = G.copy() weight = 'weight' for (u, v, d) in G1.edges(data=True): d[weight] = 1 / d[weight] L = nx.laplacian_matrix(G1, weight='weight').todense() M = np.linalg.pinv(L) re = [] for i in range(len(node)): re.append(M[node[i, 0], node[i, 0]] + M[node[i, 1], node[i, 1]] - 2 * M[node[i, 1], node[i, 0]]) return (re)
def reduce_graph_naively(nx_graph, output_dim, eigendecomp_strategy="exact"): """ Run PCA on the ETCD of a NetworkX graph using a slow but precise method This is the method that calculates the actual ETCD. It calculates the Moore-Penrose pseudoinverse of the Laplacian of the input graph. We return the first output_dim dimensions of the ETCD, ordered by decreasing eigenvalue. This method starts to take a very, very long time as graph size reaches into the thousands due to the matrix inversion. Parameters ---------- nx_graph : :class:`nx.Graph` or :class:`nx.DiGraph` The graph to be reduced output_dim : int The number of dimensions to reduce to eigendecomp_strategy : 'exact' | 'sparse' | 'smart' Chooses the eigendecomp strategy. 'exact' uses `numpy.linalg.eigh` on a dense matrix. Calculates all eigenpairs and then strips to just the necessary ones. 'sparse' uses `numpy.sparse.linalg.eigsh` on a sparse matrix. Calculates just the necessary eigenpairs. Is an iterative- approximative algorithm, and so sometimes yields things that are not amazing, especially for edge cases. 'smart' uses 'exact' if n < 1000, 'sparse' otherwise. Returns ------- :class:`numpy.ndarray` The reduced data in output_dim dimensions """ LOG.debug("Entering naive_reduce_graph") L = nx.laplacian_matrix(nx_graph).todense() LOG.info("Calculating Moore-Penrose inverse of the Laplacian L") Li = np.linalg.pinv(L) LOG.info( "Calculating largest eigenvalues of L-inverse & corresponding eigenvectors" ) (E, U) = _eigendecomp(eigendecomp_strategy, Li, output_dim, which="LM") # Flip so largest eigen first E = E[::-1] U = np.fliplr(U) LOG.debug("Eigenvalues: {}".format(E)) LOG.info("Assembling PCA result") # Assemble into the right structure X = np.zeros((output_dim, len(nx_graph))) sqrtE = np.sqrt(E) for i in range(output_dim): X[i, :] = sqrtE[i] * U[:, i] return X
def __init__(self, graph: nx.Graph): """ Hierarchicall Structural Distance model. :param graph: nx.Graph """ self.graph = graph self.adjacent = nx.adjacency_matrix(graph).todense() self.laplacian = nx.laplacian_matrix(graph).todense() self.nodes = list(nx.nodes(graph)) self.idx2node, self.node2idx = util.build_node_idx_map(graph) self.eigenvalues, self.eigenvectors = np.linalg.eigh(self.laplacian) self.wavelets = None
def solve_picos(self): #http://www.orsj.or.jp/archive2/or63-12/or63_12_755.pdf #とけてるのかどうかわからん p = pic.Problem() X = p.add_variable('X', (self.n, self.n), 'symmetric') gL = nx.laplacian_matrix(self.G, weight='w', nodelist=self.G.nodes) gL = gL.toarray().astype(np.double) L = pic.new_param('L', 1 / 4 * gL) p.add_constraint(pic.diag_vect(X) == 1) p.add_constraint(X >> 0) p.set_objective('max', L | X) p.solve() print('bound from the SDP relaxation: {0}'.format(p.obj_value()))
def feidler_vector(self, G, eps=1e-10): L = nx.laplacian_matrix(G) L = L.toarray() ev, lv, rv = la.eig(L, left=True, right=True) ev = np.real(ev) ev = list(map(self.adjust_eps, ev)) z = zip(ev, rv) sorted_eigs = sorted(z, key=lambda t: t[0]) min_ev = min(ev) new_evs = filter(lambda x: x != min_ev, sorted(ev)) l2 = list(new_evs)[0] second_vector = list(filter(lambda t: t[0] == l2, sorted_eigs))[0] return l2, second_vector
def dbscan_cluster(self, opinion_ids: set, eps=0.94) -> Dict[int, set]: sgraph = self.similarity.internal_similarity(opinion_ids) slaplacian = nx.laplacian_matrix(sgraph).toarray() slaplacian += 1 sdist = slaplacian * (1 - np.identity(slaplacian.shape[0])) labels = DBSCAN(eps=eps, min_samples=1, metric="precomputed").fit(sdist).labels_ output = {} for c, l in zip(opinion_ids, labels): if not l in output: output[l] = set() output[l].add(c) return output
def test_eigenvectors(self): try: import numpy as N eigenval=N.linalg.eigvals except ImportError: raise SkipTest('NumPy not available.') cs='ddiiddid' G=nxt.threshold_graph(cs) (tgeval,tgevec)=nxt.eigenvectors(cs) dot=N.dot assert_equal([ abs(dot(lv,lv)-1.0)<1e-9 for lv in tgevec ], [True]*8) lapl=nx.laplacian_matrix(G)
def steady_flows(self): """ The fixed points are given by: \sum_j (p_j-p_i) """ L = nx.laplacian_matrix(self).toarray() I = np.array([self.node[n]['input'] for n in self.nodes()]) pressures = np.insert(np.linalg.solve(L[1:, 1:], I[1:]), 0, 0) node_indices = {node: idx for idx, node in enumerate(self.nodes())} flows = FlowDict({(u, v): (pressures[node_indices[u]] - pressures[node_indices[v]]) * dat.get( self.weight_attr, 1) for (u, v, dat) in self.edges(data=True)}) return flows
def _ct(self, nodes): ord1 = self.G_ord1(nodes) g = nx.Graph() g.add_nodes_from(nodes.tolist()) g.add_edges_from(ord1) n_list = sorted(g.nodes()) g_id = { val:idx for idx,val in enumerate(n_list)} L = nx.laplacian_matrix(g, nodelist=sorted(g.nodes)) CTK = np.linalg.pinv(L.toarray()) i,j = g_id[nodes[0]], g_id[nodes[1]] return len(g.edges) * (CTK[i,i] + CTK[j,j] - 2 * CTK[i,j])
def run(nodes, edges, k, m): """ This is the main function of the project """ g, cc, aff = nx.Graph(), None, None try: valid_param(nodes, edges, k, m) except Exception as e: logging.error(str(e)) return None # load the graph logging.info("Loading graph!") try: g = load_graph(nodes, edges) except Exception as e: logging.error("There has been an error while trying to load data" + str(e)) exit(-1) # Run the appropriate algorithm specified by the user logging.info("Running the clustering algorithm") start_time = time.time() if m in ['modspectral', 'spectral']: if m == 'spectral': data_points = nx.laplacian_matrix(g).toarray() cc, aff = sc(data_points, k) else: data_points = nx.laplacian_matrix(g).toarray() cc, aff = ikmeans(data_points) else: data_points = nx.adjacency_matrix(g).toarray() cc, aff = kmeans(data_points, k) end_time = time.time() logging.info("Calculating the clustering quality") cc_index = np.unique(aff).tolist() for i in range(len(aff)): aff[i] = cc_index.index(aff[i]) k = len(cc_index) int_q, ext_q = c_int_ext(k, aff, nx.adjacency_matrix(g).toarray(), threads_nb=4) return end_time - start_time, aff, int_q, ext_q
def got_align(g1, g2): N1 = len(g1) N2 = len(g2) l1 = nx.laplacian_matrix(g1, range(N1)) l1 = np.array(l1.todense()) l1 = np.double(l1) l2 = nx.laplacian_matrix(g2, range(N2)) l2 = np.array(l2.todense()) l2 = np.double(l2) sbm_x_inv, sbm_y_inv, sbm_P = find_permutation(l1, l2, it=10, tau=2, n_samples=20, epochs=600, lr=0.5, loss_type='w', alpha=0.1, ones=True) return sbm_P
def monte_carlo_regular(r, nodes): counter = 0 for i in range(nodes): # size of the monte carlo simulation rrg = nx.random_regular_graph(r, nodes) L = nx.laplacian_matrix(rrg, nodelist=range(len(rrg.nodes))).todense() eighenvalues = np.linalg.eig(L)[0] sec_small_eig = np.sort(eighenvalues)[1] if sec_small_eig > 0: counter += 1 else: pass return counter / nodes
def check_effres(g): L = nx.laplacian_matrix(g).todense() LInv = np.linalg.pinv(L) ea = np.zeros((len(g.nodes), 1)) ea[10] = 1 eb = np.zeros((len(g.nodes), 1)) eb[15] = 1 Rab = np.matmul(np.matmul((ea - eb).T, LInv), (ea - eb)) Rabdist = nx.algorithms.distance_measures.resistance_distance(g, 10, 15) return Rab, Rabdist
def test_two_nodes(self): G = nx.Graph() G.add_edge(0, 1, weight=1) A = nx.laplacian_matrix(G) for method in self._methods: assert almost_equal( nx.algebraic_connectivity(G, tol=1e-12, method=method), 2) x = nx.fiedler_vector(G, tol=1e-12, method=method) check_eigenvector(A, 2, x) G = nx.MultiGraph() G.add_edge(0, 0, spam=1e8) G.add_edge(0, 1, spam=1) G.add_edge(0, 1, spam=-2) A = -3 * nx.laplacian_matrix(G, weight='spam') for method in self._methods: assert almost_equal( nx.algebraic_connectivity(G, weight='spam', tol=1e-12, method=method), 6) x = nx.fiedler_vector(G, weight='spam', tol=1e-12, method=method) check_eigenvector(A, 6, x)
def test_two_nodes_multigraph(self, method): G = nx.MultiGraph() G.add_edge(0, 0, spam=1e8) G.add_edge(0, 1, spam=1) G.add_edge(0, 1, spam=-2) A = -3 * nx.laplacian_matrix(G, weight="spam") assert almost_equal( nx.algebraic_connectivity(G, weight="spam", tol=1e-12, method=method), 6) x = nx.fiedler_vector(G, weight="spam", tol=1e-12, method=method) check_eigenvector(A, 6, x)
def _create_sparse_matrix(self, network, normalize=False): """ :param network: :param normalize: :return: """ if normalize: return csc_matrix(networkx.normalized_laplacian_matrix(network), dtype=constants.DEFAULT_DATA_TYPE) else: return csc_matrix(networkx.laplacian_matrix(network), dtype=constants.DEFAULT_DATA_TYPE)
def log_number_trees(G): m = nx.laplacian_matrix(G)[1:, 1:] m = csc_matrix(m) splumatrix = scipy.sparse.linalg.splu(m) diag_L = np.diag(splumatrix.L.A) diag_U = np.diag(splumatrix.U.A) try: S_log_L = [np.log(np.abs(s)) for s in diag_L] S_log_U = [np.log(np.abs(s)) for s in diag_U] except Warning: print(diag_U) LU_prod = np.sum(S_log_U) + np.sum(S_log_L) return LU_prod
def ACT(g, ebunch=None): # Laplacian matrix Laplac = nx.laplacian_matrix(g) # pinv of L pinvL = np.linalg.pinv(Laplac.toarray()) pinvL_diag = np.diag(pinvL) # [deg(1), deg(2), ...] matrix_one = np.ones(shape=Laplac.shape) pinvL_xx = pinvL_diag * matrix_one similarity_matrix = pinvL_xx + pinvL_xx.T - (2 * pinvL) similarityMatrix = 1 / similarity_matrix similarityMatrix[similarityMatrix < 0] = 0 return apply_prediction(g, similarityMatrix, ebunch)
def lambdan_over_lambda2(G): """ calculate the fraction of lambda_n over lambda_2. lambda_i s are the eigen values of laplacian matrix """ L = nx.laplacian_matrix(G) eig = np.linalg.eigvals(L.A) eig = np.sort(eig) r = eig[-1] / float(eig[1]) return r
def normalize_adjacency(graph, args): """ Method to calculate a sparse degree normalized adjacency matrix. :param graph: Sparse graph adjacency matrix. :return A: Normalized adjacency matrix. """ ind = range(len(graph.nodes())) degs = [1.0 / graph.degree(node) for node in graph.nodes()] L = sparse.csr_matrix(nx.laplacian_matrix(graph), dtype=np.float32) degs = sparse.csr_matrix( sparse.coo_matrix((degs, (ind, ind)), shape=L.shape, dtype=np.float32)) args = sparse.eye(L.shape[0]) - args.gamma * degs.dot(L) return L
def run(args): # Load input graph print "* Loading input graph..." G = nx.Graph() G.add_edges_from([map(int, l.rstrip().split()[:2]) for l in open(args.edgelist_file)]) print "\t{} nodes with {} edges".format(len(G.nodes()), len(G.edges())) # Remove self-loops and zero degree nodes, and # restrict to the largest connected component print "* Removing self-loops, zero degree nodes, and ", print "restricting to the largest connected component" G.remove_edges_from([(u,v) for u, v in G.edges() if u == v]) G.remove_nodes_from([n for n in G.nodes() if G.degree(n) == 0]) G = G.subgraph(sorted(nx.connected_components( G ), key=lambda cc: len(cc), reverse=True)[0]) print "\t{} nodes with {} edges remaining".format(len(G.nodes()), len(G.edges())) # Load gene index index2gene = hnio.load_index(args.gene_index_file) # Compute and save Laplacian if not os.path.exists(args.output_dir): os.makedirs(args.output_dir) print "* Computing Laplacian..." L = nx.laplacian_matrix(G) scipy.io.savemat("{}/{}_laplacian.mat".format(args.output_dir, args.prefix), dict(L=L),oned_as='column') # Exponentiate the Laplacian for the given time and save it from scipy.linalg import expm Li = expm( -args.time * L ) scipy.io.savemat("{}/{}_inf_{}.mat".format(args.output_dir, args.prefix, args.time), dict(Li=Li), oned_as='column') # Save the index to gene mapping index_output_file = "{}/{}_index_genes".format(args.output_dir, args.prefix) nodes = G.nodes() gene_index_output = ["{} {}".format(i+args.start_index, index2gene[node]) for i, node in enumerate(nodes)] hnio.write_file(index_output_file, "\n".join(gene_index_output)) # Create edge list with revised indices edge_indices = [] for u, v in G.edges(): i = nodes.index(u) + args.start_index j = nodes.index(v) + args.start_index edge_indices.append( sorted([i, j]) ) edge_output_file = "{}/{}_edge_list".format(args.output_dir, args.prefix) edge_output = ["{} {} 1".format(u, v) for u, v in edge_indices] hnio.write_file(edge_output_file, "\n".join(edge_output))
def LHT_Index (graph, matrix, nodes_num, m, phi): w, v = LAD.eig(matrix) eig = max(w) # laplacian_matrix <==> L = D - A degree_matrix = nx.laplacian_matrix(graph) + matrix idn = np.identity(nodes_num) if(LAD.det(degree_matrix) == 0): print("\nLHT_Index:\nPrzy próbie obliczania odwrotności macierzy, napotkano wyznacznik równy 0.") else: deg_inv = LAD.inv(degree_matrix) phi_mul = (phi * matrix) / eig # nie jestem pewien znaczenia wspolczynnika m - zostawiam go jako param S_LHT = 2 * m * eig * deg_inv * (LAD.inv(idn - (phi_mul))) * deg_inv return S_LHT
def plot_network_and_spectral_basic(network, coordinates, title="", savepath="", showfig="False", view_thet=30, view_phi=30): basic_coordinates = get_spectral_coordinates( nx.laplacian_matrix(network).todense(), dim=3) basic_coordinates = pd.DataFrame(rmsd.kabsch_rotate( basic_coordinates.values, coordinates.values), columns=["x", "y", "z"]) fig = plt.figure() ax = fig.add_subplot(111, projection='3d') ax.scatter(coordinates["x"], coordinates["y"], coordinates["z"], label="Originale") ax.scatter(basic_coordinates["x"], basic_coordinates["y"], basic_coordinates["z"], label="Spectral Basic") for edge in list(network.edges): ax.plot( (coordinates.iloc[edge[0]]["x"], coordinates.iloc[edge[1]]["x"]), (coordinates.iloc[edge[0]]["y"], coordinates.iloc[edge[1]]["y"]), (coordinates.iloc[edge[0]]["z"], coordinates.iloc[edge[1]]["z"]), c="grey", alpha=0.7) ax.plot((basic_coordinates.iloc[edge[0]]["x"], basic_coordinates.iloc[edge[1]]["x"]), (basic_coordinates.iloc[edge[0]]["y"], basic_coordinates.iloc[edge[1]]["y"]), (basic_coordinates.iloc[edge[0]]["z"], basic_coordinates.iloc[edge[1]]["z"]), c="red", alpha=0.4) ax.legend() ax.set_xlabel("X") ax.set_ylabel("Y") ax.set_zlabel("Z") if title != "": ax.set_title(title) if showfig: ax.view_init(view_thet, view_phi) plt.show() if savepath != "": ax.view_init(view_thet, view_phi) plt.savefig(savepath, dpi=300) plt.clf()
def find_NST(graph): ''' NEED TO CHANGE THIS TO PARKER'S FUNCTION! To find the number of spanning trees on a graph, build the Laplacian matrix (will be a sparse matrix), delete the first row and column, and take the determinant. Input: Networkx graph. Output: Int. ''' lap = nx.laplacian_matrix(graph) lap = delete_from_csr(lap, row_indices=[0], col_indices=[0]) lap = lap.toarray() NST = round(np.linalg.det(lap)) return NST
def __init__(self, G, q): self.G = G self.H = nx.DiGraph() self.nv = G.number_of_nodes() self.q = q self.L = nx.laplacian_matrix(self.G).toarray() # set edge attribute weight with weight 1 self.H.add_weighted_edges_from([(u, v, 1.0) for u, v in G.edges()]) self.H.add_weighted_edges_from([(v, u, 1.0) for u, v in G.edges()]) # add links from all nodes in the original graph to the root with weight q self.root = self.nv self.H.add_weighted_edges_from([(u, self.root, q) for u in G.nodes()])
def spectral_clustering(G, k): ################## # your code here # ################## L = nx.laplacian_matrix(G).astype(float) eig_val, eig_vect = eigsh(L, k) kmeans = KMeans(n_clusters=k).fit_predict(eig_vect) clustering = { 'node': [n for n in G.nodes()], 'cluster': [k for k in kmeans] } return clustering
def fit(self, Y, Z, G, inplace=False, **kwargs): if inplace: self.G = G else: self.G = copy.deepcopy(G) L = nx.laplacian_matrix(self.G) nodelist = self.G.nodes() K = L.shape[0] shape = (1,) theta_shape = (K,) + shape # preprocess data for y, z in zip(Y, Z): vertex = self.G.node[z] if 'Y' in vertex: vertex['Y'] += [y] else: vertex['Y'] = [y] S = np.zeros((K, 1)) N = np.zeros((K, 1)) for i, node in enumerate(nodelist): vertex = self.G.node[node] if 'Y' in vertex: S[i] = np.sum(vertex['Y']) N[i] = len(vertex['Y']) del vertex['Y'] def l_prox(lambd, eta, warm_start, pool): a = np.ones(eta.shape) * -1 b = eta + 1 c = lambd * N - eta d = -S * lambd coefs = np.hstack([a, b, c, d]) theta = np.array(pool.map(find_solution, coefs))[:, np.newaxis] return np.clip(theta, self.min_theta, self.max_theta) def r_prox(lambd, eta, warm_start, pool): return np.clip(eta, self.min_theta, self.max_theta) data = G_to_data(self.G, theta_shape) result, info = fit_stratified_model( L, shape, l_prox, r_prox, data=data, **kwargs) transfer_result_to_G(result, self.G) return info
def community_covd(features, G, subgraphs): L = nx.laplacian_matrix(G) delta_features = L.dot(features) data = np.hstack((features, delta_features)) #it has 16 features covdata = [] # will contain a list for each community for g in subgraphs: nodes = [int(n) for n in g] dataset = data[nodes] covmat = np.cov(dataset, rowvar=False) covdata.append(covmat) return covdata
def reduce_graph_naively(nx_graph, output_dim, eigendecomp_strategy='exact'): """ Run PCA on the ETCD of a NetworkX graph using a slow but precise method This is the method that calculates the actual ETCD. It calculates the Moore-Penrose pseudoinverse of the Laplacian of the input graph. We return the first output_dim dimensions of the ETCD, ordered by decreasing eigenvalue. This method starts to take a very, very long time as graph size reaches into the thousands due to the matrix inversion. Parameters ---------- nx_graph : :class:`nx.Graph` or :class:`nx.DiGraph` The graph to be reduced output_dim : int The number of dimensions to reduce to eigendecomp_strategy : 'exact' | 'sparse' | 'smart' Chooses the eigendecomp strategy. 'exact' uses `numpy.linalg.eigh` on a dense matrix. Calculates all eigenpairs and then strips to just the necessary ones. 'sparse' uses `numpy.sparse.linalg.eigsh` on a sparse matrix. Calculates just the necessary eigenpairs. Is an iterative- approximative algorithm, and so sometimes yields things that are not amazing, especially for edge cases. 'smart' uses 'exact' if n < 1000, 'sparse' otherwise. Returns ------- :class:`numpy.ndarray` The reduced data in output_dim dimensions """ LOG.debug('Entering naive_reduce_graph') L = nx.laplacian_matrix(nx_graph).todense() LOG.info('Calculating Moore-Penrose inverse of the Laplacian L') Li = np.linalg.pinv(L) LOG.info('Calculating largest eigenvalues of L-inverse & corresponding eigenvectors') (E, U) = _eigendecomp(eigendecomp_strategy, Li, output_dim, which='LM') # Flip so largest eigen first E = E[::-1] U = np.fliplr(U) LOG.debug('Eigenvalues: {}'.format(E)) LOG.info('Assembling PCA result') # Assemble into the right structure X = np.zeros((output_dim, len(nx_graph))) sqrtE = np.sqrt(E) for i in range(output_dim): X[i, :] = sqrtE[i] * U[:, i] return X
def print_all(G, ks=[2, 3, 4, 5], step=10, nv=100, seed=1): print("normalized laplacian:") M = nx.normalized_laplacian_matrix(G) for k in ks: print(f"k:{k}") print(f"\t slq:{slq_spenet(M, k, step=step, nv=nv, seed=seed)}") print(f"\t exact:{exact_spenet(M, k, method='eig')}") print("laplacian:") M = nx.laplacian_matrix(G) for k in ks: print(f"k:{k}") print(f"\t slq:{slq_spenet(M, k, step=step, nv=nv, seed=seed)}") print(f"\t exact:{exact_spenet(M, k, method='eig')}")
def get_spectral(graph, n=10, t=5): #This function has bugs I have not fixed. """ Function that performs spectral clustering on the weighted graph. Cluster number, k, is determined by finding the first eigengap that is some amount t larger than preceding eigengaps. graph : NetworkX graph. Weighted graph representation of all alignments n: int. Number of eigenvalues (DG splits) to consider threshold t: int. Multiplicity of median eigengap threshold Returns align_dg_dict, dg_ind: dict, int requires KMeans, networkx functions: connected_components(),subgraph.nodes(), subgraph.degree(), etc. """ dg_ind = 0 align_dg_dict = {} subgraphs = [graph.subgraph(c) for c in nx.connected_components(graph)] for subgraph in subgraphs: k = 1 if len(subgraph) > 1: L = nx.laplacian_matrix(subgraph, nodelist=sorted( subgraph.nodes())).todense() D = np.diag( [subgraph.degree[node] for node in sorted(subgraph.nodes())]) w, v = sp.linalg.eigh(L, D, type=1) # Since L always symmetric eigengaps = np.diff(w[:(n + 1)]) if len(eigengaps) > 2: if (w[1] > 1) and (w[1] >= 10 * np.median(eigengaps[1:])): k = 2 else: # ignore divide by 0 warning if eigengaps median is 0 np.seterr(divide='ignore', invalid='ignore') eigenratios = np.copy(eigengaps) eigenratios[1:] = np.array([ eigengaps[i] / np.median(eigengaps[:i]) for i in range(1, len(eigengaps)) ]) if max(eigenratios) >= t: k = np.argmax(eigenratios >= t) + 2 Y = np.transpose(v[:k]) kmeans = KMeans(n_clusters=k, random_state=0).fit(Y) kmeans.labels_ += dg_ind subgraph_dict = dict(zip(sorted(subgraph.nodes()), kmeans.labels_)) else: subgraph_dict = {list(subgraph)[0]: dg_ind} align_dg_dict = { **align_dg_dict, **subgraph_dict } dg_ind += k return align_dg_dict #asignment of alignment IDs to DG numbers.
def log_number_trees(G): #Kirkoffs is the determinant of the minor.. #at some point this should be replaced with a Cholesky decomposition based algorithm, which is supposedly faster. m = nx.laplacian_matrix(G)[1:, 1:] m = csc_matrix(m) splumatrix = scipy.sparse.linalg.splu(m) diag_L = np.diag(splumatrix.L.A) diag_U = np.diag(splumatrix.U.A) S_log_L = [np.log(s) for s in diag_L] #Seems like the upper diagonal of L is always 1.... so this may be unnecessary. S_log_U = [np.log(s) for s in diag_U] #LU_prod = np.sum(S_log_U) LU_prod = np.sum(S_log_U) + np.sum(S_log_L) return LU_prod
def get_laplacian_matrix(frame, normalized=True, show=False, figure_index=0, figure_type='flipped_figures'): """ LAPLACIAN: compute the Delaunay triangulation between keypoints, then use the connections to build an adjacency matrix, which is then converted to its (normalized) Laplacian matrix (a single matrix that encapsulates the degree of each node and the connections between the nodes). Then you can subtract a pose's Laplacian from another's to get a measure of the degree of similarity or difference between them. """ if figure_type not in frame or figure_index > len( frame[figure_type]) - 1 or frame[figure_type][ figure_index].data.shape[0] == 0: return None all_points = frame[figure_type][figure_index].data # For visualization, remove all [x,y,0] (unknown) coordinates. nonzero = (all_points != 0).all(axis=1) nz_points = all_points[nonzero] points = nz_points[:, :2] total_points = len(points) try: tri = Delaunay(points) except: # Not sure why this happens -- maybe the points are all in a line or something print("Error computing Delaunay triangulation") return None if show: plot_delaunay(frame[figure_type][figure_index]) adjacency_matrix = lil_matrix((total_points, total_points), dtype=int) for i in np.arange(0, np.shape(tri.simplices)[0]): for j in tri.simplices[i]: if j < total_points: adjacency_matrix[j, tri.simplices[i][ tri.simplices[i] < total_points]] = 1 adjacency_graph = nx.from_scipy_sparse_matrix(adjacency_matrix) if normalized: lm = nx.normalized_laplacian_matrix(adjacency_graph) else: lm = nx.laplacian_matrix(adjacency_graph) return lm
def test_two_nodes_multigraph(self, method): pytest.importorskip("scipy") G = nx.MultiGraph() G.add_edge(0, 0, spam=1e8) G.add_edge(0, 1, spam=1) G.add_edge(0, 1, spam=-2) A = -3 * nx.laplacian_matrix(G, weight="spam") assert nx.algebraic_connectivity(G, weight="spam", tol=1e-12, method=method) == pytest.approx( 6, abs=1e-7) x = nx.fiedler_vector(G, weight="spam", tol=1e-12, method=method) check_eigenvector(A, 6, x)
def test_exact_eigendomp_same_as_sparse(self): g = nx.erdos_renyi_graph(10, 0.5) l = nx.laplacian_matrix(g).astype('d') # Test for smallest eigs Eb, Ub = graphpca._sparse_eigendecomp(l, 4, which='SM') Es, Us = graphpca._exact_eigendecomp(l, 4, which='SM') self.assertTrue(np.allclose(Eb, Es), 'Big vals: {}\nSmall vals: {}\n'.format(Eb, Es)) self.assertTrue(np.allclose(Ub, Us, rtol=1e-09, atol=1e-09), 'Big vecs:\n{}\nSmall vecs:\n{}\n'.format(Ub, Us)) # Test for biggest eigs Eb, Ub = graphpca._sparse_eigendecomp(l, 4, which='LM') Es, Us = graphpca._exact_eigendecomp(l, 4, which='LM') self.assertTrue(np.allclose(Eb, Es), 'Big vals: {}\nSmall vals: {}\n'.format(Eb, Es)) self.assertTrue(np.allclose(Ub, Us, rtol=1e-09, atol=1e-09), 'Big vecs:\n{}\nSmall vecs:\n{}\n'.format(Ub, Us))
def simple_spectral_cut(CAC, start, F, G, beta, k, n, ind): L = networkx.laplacian_matrix(G) M = chebyshev_approx_2d(n, beta, CAC, L) eigvec = power_method(-M, start, 10) x = chebyshev_approx_1d(n, beta, eigvec, L) (x, score, size, energy) = sweep_vec(x, beta, F, G, k, ind) res = {} res["x"] = numpy.array(x) res["size"] = size res["score"] = score res["energy"] = energy return res
def test_bethe_hessian(self): "Bethe Hessian matrix" H = numpy.array([[ 4, -2, 0], [-2, 5, -2], [ 0, -2, 4]]) permutation = [2, 0, 1] # Bethe Hessian gives expected form assert_equal(nx.bethe_hessian_matrix(self.P, r=2).todense(), H) # nodelist is correctly implemented assert_equal(nx.bethe_hessian_matrix(self.P, r=2, nodelist=permutation).todense(), H[numpy.ix_(permutation, permutation)]) # Equal to Laplacian matrix when r=1 assert_equal(nx.bethe_hessian_matrix(self.G, r=1).todense(), nx.laplacian_matrix(self.G).todense()) # Correct default for the regularizer r assert_equal(nx.bethe_hessian_matrix(self.G).todense(), nx.bethe_hessian_matrix(self.G, r=1.25).todense())