Skip to content

Commit 2550b64

Browse files
rossbarpkuppensdschult
authored andcommitted
Handle edge cases in Laplacian centrality (networkx#6938)
* networkx#6571 laplacian_centrality not working for graphs with single nodes * networkx#6571 PR code review comments. * Minor test cleanup. * More minor test cleanup. * avoid checking == 0.0, move up check and use empty_graph in tests --------- Co-authored-by: Pieter Kuppens <[email protected]> Co-authored-by: Dan Schult <[email protected]>
1 parent 1081de4 commit 2550b64

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

networkx/algorithms/centrality/laplacian.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ def laplacian_centrality(
8080
------
8181
NetworkXPointlessConcept
8282
If the graph `G` is the null graph.
83+
ZeroDivisionError
84+
If the graph `G` has no edges (is empty) and normalization is requested.
8385
8486
References
8587
----------
@@ -98,8 +100,12 @@ def laplacian_centrality(
98100

99101
if len(G) == 0:
100102
raise nx.NetworkXPointlessConcept("null graph has no centrality defined")
103+
if G.size(weight=weight) == 0:
104+
if normalized:
105+
raise ZeroDivisionError("graph with no edges has zero full energy")
106+
return {n: 0 for n in G}
101107

102-
if nodelist != None:
108+
if nodelist is not None:
103109
nodeset = set(G.nbunch_iter(nodelist))
104110
if len(nodeset) != len(nodelist):
105111
raise nx.NetworkXError("nodelist has duplicate nodes or nodes not in G")
@@ -126,7 +132,11 @@ def laplacian_centrality(
126132
new_diag = lap_matrix.diagonal() - abs(lap_matrix[:, i])
127133
np.fill_diagonal(A_2, new_diag[all_but_i])
128134

129-
new_energy = np.power(sp.linalg.eigh(A_2, eigvals_only=True), 2).sum()
135+
if len(all_but_i) > 0: # catches degenerate case of single node
136+
new_energy = np.power(sp.linalg.eigh(A_2, eigvals_only=True), 2).sum()
137+
else:
138+
new_energy = 0.0
139+
130140
lapl_cent = full_energy - new_energy
131141
if normalized:
132142
lapl_cent = lapl_cent / full_energy

networkx/algorithms/centrality/tests/test_laplacian_centrality.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,38 @@
66
sp = pytest.importorskip("scipy")
77

88

9+
def test_laplacian_centrality_null_graph():
10+
G = nx.Graph()
11+
with pytest.raises(nx.NetworkXPointlessConcept):
12+
d = nx.laplacian_centrality(G, normalized=False)
13+
14+
15+
def test_laplacian_centrality_single_node():
16+
"""See gh-6571"""
17+
G = nx.empty_graph(1)
18+
assert nx.laplacian_centrality(G, normalized=False) == {0: 0}
19+
with pytest.raises(ZeroDivisionError):
20+
nx.laplacian_centrality(G, normalized=True)
21+
22+
23+
def test_laplacian_centrality_unconnected_nodes():
24+
"""laplacian_centrality on a unconnected node graph should return 0
25+
26+
For graphs without edges, the Laplacian energy is 0 and is unchanged with
27+
node removal, so::
28+
29+
LC(v) = LE(G) - LE(G - v) = 0 - 0 = 0
30+
"""
31+
G = nx.empty_graph(3)
32+
assert nx.laplacian_centrality(G, normalized=False) == {0: 0, 1: 0, 2: 0}
33+
34+
35+
def test_laplacian_centrality_empty_graph():
36+
G = nx.empty_graph(3)
37+
with pytest.raises(ZeroDivisionError):
38+
d = nx.laplacian_centrality(G, normalized=True)
39+
40+
941
def test_laplacian_centrality_E():
1042
E = nx.Graph()
1143
E.add_weighted_edges_from(

0 commit comments

Comments
 (0)