Skip to content

Commit

Permalink
Generalized node-edge centrality (#165)
Browse files Browse the repository at this point in the history
Added lambda function default arguments for $f$, $g$, $\varphi$, $\psi$ as defined by Tudisco and Higham. Default behavior is identical as before.
  • Loading branch information
nwlandry authored Sep 8, 2022
1 parent 1c7cd86 commit 20ce1b8
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 9 deletions.
27 changes: 22 additions & 5 deletions xgi/algorithms/centrality.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,13 +157,33 @@ def apply(H, x, g=lambda v, e: np.sum(v[list(e)])):
return new_x


def node_edge_centrality(H, max_iter=100, tol=1e-6):
def node_edge_centrality(
H,
f=lambda x: np.power(x, 2),
g=lambda x: np.power(x, 0.5),
phi=lambda x: np.power(x, 2),
psi=lambda x: np.power(x, 0.5),
max_iter=100,
tol=1e-6,
):
"""Computes the node and edge centralities
Parameters
----------
H : Hypergraph
The hypergraph of interest
f : lambda function, default: x^2
The function f as described in Tudisco and Higham.
Must accept a numpy array.
g : lambda function, default: x^0.5
The function g as described in Tudisco and Higham.
Must accept a numpy array.
phi : lambda function, default: x^2
The function phi as described in Tudisco and Higham.
Must accept a numpy array.
psi : lambda function, default: x^0.5
The function psi as described in Tudisco and Higham.
Must accept a numpy array.
max_iter : int, default: 100
Number of iterations at which the algorithm terminates
if convergence is not reached.
Expand Down Expand Up @@ -199,12 +219,9 @@ def node_edge_centrality(H, max_iter=100, tol=1e-6):

check = np.inf

f = lambda x: np.power(x, 2)
g = lambda x: np.power(x, 0.5)

for iter in range(max_iter):
u = np.multiply(x, g(I * f(y)))
v = np.multiply(y, g(I.T * f(x)))
v = np.multiply(y, psi(I.T * phi(x)))
new_x = u / norm(u)
new_y = v / norm(v)

Expand Down
27 changes: 25 additions & 2 deletions xgi/stats/edgestats.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"""

import numpy as np

import xgi

__all__ = [
Expand Down Expand Up @@ -180,7 +182,16 @@ def size(net, bunch, degree=None):
}


def node_edge_centrality(net, bunch, max_iter=100, tol=1e-6):
def node_edge_centrality(
net,
bunch,
f=lambda x: np.power(x, 2),
g=lambda x: np.power(x, 0.5),
phi=lambda x: np.power(x, 2),
psi=lambda x: np.power(x, 0.5),
max_iter=100,
tol=1e-6,
):
"""Computes edge centralities.
Parameters
Expand All @@ -189,6 +200,18 @@ def node_edge_centrality(net, bunch, max_iter=100, tol=1e-6):
The hypergraph of interest
bunch : Iterable
Edges in `net`
f : lambda function, default: x^2
The function f as described in Tudisco and Higham.
Must accept a numpy array.
g : lambda function, default: x^0.5
The function g as described in Tudisco and Higham.
Must accept a numpy array.
phi : lambda function, default: x^2
The function phi as described in Tudisco and Higham.
Must accept a numpy array.
psi : lambda function, default: x^0.5
The function psi as described in Tudisco and Higham.
Must accept a numpy array.
max_iter : int, default: 100
Number of iterations at which the algorithm terminates
if convergence is not reached.
Expand All @@ -215,5 +238,5 @@ def node_edge_centrality(net, bunch, max_iter=100, tol=1e-6):
Francesco Tudisco & Desmond J. Higham,
https://doi.org/10.1038/s42005-021-00704-2
"""
_, c = xgi.node_edge_centrality(net, max_iter, tol)
_, c = xgi.node_edge_centrality(net, f, g, phi, psi, max_iter, tol)
return {e: c[e] for e in c if e in bunch}
27 changes: 25 additions & 2 deletions xgi/stats/nodestats.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
"""

import numpy as np

import xgi

__all__ = [
Expand Down Expand Up @@ -318,7 +320,16 @@ def hec_centrality(net, bunch, max_iter=10, tol=1e-6):
return {n: c[n] for n in c if n in bunch}


def node_edge_centrality(net, bunch, max_iter=100, tol=1e-6):
def node_edge_centrality(
net,
bunch,
f=lambda x: np.power(x, 2),
g=lambda x: np.power(x, 0.5),
phi=lambda x: np.power(x, 2),
psi=lambda x: np.power(x, 0.5),
max_iter=100,
tol=1e-6,
):
"""Computes node centralities.
Parameters
Expand All @@ -327,6 +338,18 @@ def node_edge_centrality(net, bunch, max_iter=100, tol=1e-6):
The hypergraph of interest
bunch : Iterable
Edges in `net`
f : lambda function, default: x^2
The function f as described in Tudisco and Higham.
Must accept a numpy array.
g : lambda function, default: x^0.5
The function g as described in Tudisco and Higham.
Must accept a numpy array.
phi : lambda function, default: x^2
The function phi as described in Tudisco and Higham.
Must accept a numpy array.
psi : lambda function, default: x^0.5
The function psi as described in Tudisco and Higham.
Must accept a numpy array.
max_iter : int, default: 100
Number of iterations at which the algorithm terminates
if convergence is not reached.
Expand Down Expand Up @@ -355,5 +378,5 @@ def node_edge_centrality(net, bunch, max_iter=100, tol=1e-6):
Francesco Tudisco & Desmond J. Higham,
https://doi.org/10.1038/s42005-021-00704-2
"""
c, _ = xgi.node_edge_centrality(net, max_iter, tol)
c, _ = xgi.node_edge_centrality(net, f, g, phi, psi, max_iter, tol)
return {n: c[n] for n in c if n in bunch}

0 comments on commit 20ce1b8

Please sign in to comment.