Coverage for scipy\sparse\csgraph\_laplacian.py: 0%

# Coverage for scipy\sparse\csgraph\_laplacian.py : 0%

## 51 statements 0 run 51 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | """ Laplacian of a compressed-sparse graph """ # Authors: Aric Hagberg <hagberg@lanl.gov> # Gael Varoquaux <gael.varoquaux@normalesup.org> # Jake Vanderplas <vanderplas@astro.washington.edu> # License: BSD from __future__ import division, print_function, absolute_import import numpy as np from scipy.sparse import isspmatrix ############################################################################### # Graph laplacian def laplacian(csgraph, normed=False, return_diag=False, use_out_degree=False): """ Return the Laplacian matrix of a directed graph. Parameters ---------- csgraph : array_like or sparse matrix, 2 dimensions compressed-sparse graph, with shape (N, N). normed : bool, optional If True, then compute normalized Laplacian. return_diag : bool, optional If True, then also return an array related to vertex degrees. use_out_degree : bool, optional If True, then use out-degree instead of in-degree. This distinction matters only if the graph is asymmetric. Default: False. Returns ------- lap : ndarray or sparse matrix The N x N laplacian matrix of csgraph. It will be a numpy array (dense) if the input was dense, or a sparse matrix otherwise. diag : ndarray, optional The length-N diagonal of the Laplacian matrix. For the normalized Laplacian, this is the array of square roots of vertex degrees or 1 if the degree is zero. Notes ----- The Laplacian matrix of a graph is sometimes referred to as the "Kirchoff matrix" or the "admittance matrix", and is useful in many parts of spectral graph theory. In particular, the eigen-decomposition of the laplacian matrix can give insight into many properties of the graph. Examples -------- >>> from scipy.sparse import csgraph >>> G = np.arange(5) * np.arange(5)[:, np.newaxis] >>> G array([[ 0, 0, 0, 0, 0], [ 0, 1, 2, 3, 4], [ 0, 2, 4, 6, 8], [ 0, 3, 6, 9, 12], [ 0, 4, 8, 12, 16]]) >>> csgraph.laplacian(G, normed=False) array([[ 0, 0, 0, 0, 0], [ 0, 9, -2, -3, -4], [ 0, -2, 16, -6, -8], [ 0, -3, -6, 21, -12], [ 0, -4, -8, -12, 24]]) """ if csgraph.ndim != 2 or csgraph.shape[0] != csgraph.shape[1]: raise ValueError('csgraph must be a square matrix or array') if normed and (np.issubdtype(csgraph.dtype, np.signedinteger) or np.issubdtype(csgraph.dtype, np.uint)): csgraph = csgraph.astype(float) create_lap = _laplacian_sparse if isspmatrix(csgraph) else _laplacian_dense degree_axis = 1 if use_out_degree else 0 lap, d = create_lap(csgraph, normed=normed, axis=degree_axis) if return_diag: return lap, d return lap def _setdiag_dense(A, d): A.flat[::len(d)+1] = d def _laplacian_sparse(graph, normed=False, axis=0): if graph.format in ('lil', 'dok'): m = graph.tocoo() needs_copy = False else: m = graph needs_copy = True w = m.sum(axis=axis).getA1() - m.diagonal() if normed: m = m.tocoo(copy=needs_copy) isolated_node_mask = (w == 0) w = np.where(isolated_node_mask, 1, np.sqrt(w)) m.data /= w[m.row] m.data /= w[m.col] m.data *= -1 m.setdiag(1 - isolated_node_mask) else: if m.format == 'dia': m = m.copy() else: m = m.tocoo(copy=needs_copy) m.data *= -1 m.setdiag(w) return m, w def _laplacian_dense(graph, normed=False, axis=0): m = np.array(graph) np.fill_diagonal(m, 0) w = m.sum(axis=axis) if normed: isolated_node_mask = (w == 0) w = np.where(isolated_node_mask, 1, np.sqrt(w)) m /= w m /= w[:, np.newaxis] m *= -1 _setdiag_dense(m, 1 - isolated_node_mask) else: m *= -1 _setdiag_dense(m, w) return m, w