Skip to content

Commit

Permalink
Fix fencepost errors in uniform_erdos_renyi_hypergraph (#653)
Browse files Browse the repository at this point in the history
* Fixed fencepost errors in uniform_erdos_renyi_hypergraph and added test case that orginally alerted us to error.

* added `fast_random_hypergraph`

---------

Co-authored-by: Nicholas Landry <[email protected]>
  • Loading branch information
tlarock and nwlandry authored Feb 3, 2025
1 parent d14e3e5 commit a8bf185
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
8 changes: 8 additions & 0 deletions benchmarks/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,11 @@ def erdos_renyi():
xgi.random_hypergraph(100, [0.1, 0.001])

benchmark.pedantic(erdos_renyi, rounds=rounds, iterations=iterations)


def test_fast_erdos_renyi(benchmark):

def fast_erdos_renyi():
xgi.fast_random_hypergraph(100, [0.1, 0.001])

benchmark.pedantic(fast_erdos_renyi, rounds=rounds, iterations=iterations)
7 changes: 7 additions & 0 deletions tests/generators/test_uniform.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,10 @@ def test_uniform_erdos_renyi_hypergraph():
n = 10
k = 2
xgi.uniform_erdos_renyi_hypergraph(n, m, k, p_type="test")

# test specific case that caused failure previously
n = 200
k = 2
p = 0.0185
s = 5
xgi.uniform_erdos_renyi_hypergraph(n, k, p, p_type="prob", seed=s)
17 changes: 11 additions & 6 deletions tests/linalg/test_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,21 +257,26 @@ def test_adjacency_matrix(edgelist1, edgelist4):
assert np.all(A7 == A7_sp.todense())


def test_fix_649(): # make sure diagonal is fully zero when sparse
def test_fix_649(): # make sure diagonal is fully zero when sparse

H = xgi.load_xgi_data(dataset="email-enron")
H.cleanup(isolates=True, singletons=False, connected=True, relabel=False, multiedges=False)
H.cleanup(
isolates=True, singletons=False, connected=True, relabel=False, multiedges=False
)

weighted = True
order = 1

adj = xgi.adjacency_matrix(H, order=order, sparse=False, weighted=weighted, index=False)
adj = xgi.adjacency_matrix(
H, order=order, sparse=False, weighted=weighted, index=False
)

adj_sparse = xgi.adjacency_matrix(H, order=order, sparse=True, weighted=weighted, index=False)
adj_sparse = xgi.adjacency_matrix(
H, order=order, sparse=True, weighted=weighted, index=False
)
adj_sparse = adj_sparse.todense()

assert np.all(np.diag(adj_sparse)==0)

assert np.all(np.diag(adj_sparse) == 0)


def test_laplacian(edgelist2, edgelist6):
Expand Down
15 changes: 13 additions & 2 deletions xgi/generators/uniform.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,10 @@ def uniform_erdos_renyi_hypergraph(n, m, p, p_type="prob", multiedges=False, see
H.add_nodes_from(range(n))

if multiedges:
max_index = n**m
max_index = n**m - 1
f = _index_to_edge_prod
else:
max_index = comb(n, m, exact=True)
max_index = comb(n, m, exact=True) - 1
f = _index_to_edge_comb

index = np.random.geometric(q) - 1 # -1 b/c zero indexing
Expand Down Expand Up @@ -461,6 +461,12 @@ def _index_to_edge_prod(index, n, m):
----------
https://stackoverflow.com/questions/53834707/element-at-index-in-itertools-product
"""
if index < 0 or index >= n**m:
warnings.warn(
f"_index_to_edge_prod was given index {index} >= {n}**{m}={n**m}."
f"Returned hyperedge ({ [(index // (n**r) % n) for r in range(m - 1, -1, -1)] }) may not be correct."
)

return [(index // (n**r) % n) for r in range(m - 1, -1, -1)]


Expand Down Expand Up @@ -501,6 +507,11 @@ def _index_to_edge_comb(index, n, m):
----------
https://math.stackexchange.com/questions/1227409/indexing-all-combinations-without-making-list
"""
if index < 0 or index >= comb(n, m, exact=True):
warnings.warn(
f"index {index} >= comb({n}, {m}, exact=True) = {comb(n, m,exact=True)}."
)

c = []
r = index + 1 # makes it zero indexed
j = -1
Expand Down
6 changes: 1 addition & 5 deletions xgi/linalg/laplacian_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,7 @@
from scipy.sparse import csr_array, diags_array, eye_array

from ..exception import XGIError
from .hypergraph_matrix import (
adjacency_matrix,
degree_matrix,
incidence_matrix,
)
from .hypergraph_matrix import adjacency_matrix, degree_matrix, incidence_matrix

__all__ = [
"laplacian",
Expand Down

0 comments on commit a8bf185

Please sign in to comment.