Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add assortativity module #122

Merged
merged 19 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
style: run isort and black
  • Loading branch information
nwlandry committed Jun 14, 2022
commit b04e1eb6365ccf67288ccc38e95fe9b71f2952f2
8 changes: 4 additions & 4 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,19 +191,19 @@
(
master_doc,
"xgi.tex",
u"XGI Documentation",
u"Nicholas W. Landry and Leo Torres",
"XGI Documentation",
"Nicholas W. Landry and Leo Torres",
"manual",
),
]

man_pages = [(master_doc, "xgi", u"XGI Documentation", [author], 1)]
man_pages = [(master_doc, "xgi", "XGI Documentation", [author], 1)]

texinfo_documents = [
(
master_doc,
"XGI",
u"XGI Documentation",
"XGI Documentation",
author,
"XGI",
"One line description of project.",
Expand Down
3 changes: 2 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import xgi
import networkx as nx
import numpy as np
import pandas as pd
import pytest

import xgi


@pytest.fixture
def edgelist1():
Expand Down
3 changes: 2 additions & 1 deletion tests/stats/test_edgestats.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import pandas as pd
import pytest

import xgi
from xgi.exception import IDNotFound

Expand Down
3 changes: 2 additions & 1 deletion tests/stats/test_nodestats.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import pandas as pd
import pytest

import xgi
from xgi.exception import IDNotFound

Expand Down
4 changes: 2 additions & 2 deletions xgi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
generators,
linalg,
readwrite,
utils,
stats,
utils,
)
from .algorithms import *
from .classes import *
Expand All @@ -18,7 +18,7 @@
from .generators import *
from .linalg import *
from .readwrite import *
from .utils import *
from .stats import *
from .utils import *

__version__ = pkg_resources.require("xgi")[0].version
48 changes: 28 additions & 20 deletions xgi/algorithms/assortativity.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import random
from itertools import combinations

import numpy as np

import xgi
from xgi.exception import XGIError
from itertools import combinations
import random

__all__ = [
"dynamical_assortativity",
"degree_assortativity"
]
__all__ = ["dynamical_assortativity", "degree_assortativity"]


def dynamical_assortativity(H):
""" Gets the dynamical assortativity of a uniform hypergraph.
"""Gets the dynamical assortativity of a uniform hypergraph.

Parameters
----------
Expand All @@ -29,19 +29,27 @@ def dynamical_assortativity(H):
"""
if not xgi.is_uniform(H):
raise XGIError("Hypergraph must be uniform!")

degs = H.degree()
k1 = np.mean([degs[n] for n in H.nodes])
k2 = np.mean([degs[n]**2 for n in H.nodes])
kk1 = np.mean([degs[n1]*degs[n2] for e in H.edges for n1, n2 in combinations(H.edges.members(e), 2)])

return kk1*k1**2/k2**2 - 1
k2 = np.mean([degs[n] ** 2 for n in H.nodes])
kk1 = np.mean(
[
degs[n1] * degs[n2]
for e in H.edges
for n1, n2 in combinations(H.edges.members(e), 2)
]
)

return kk1 * k1**2 / k2**2 - 1


def degree_assortativity(H, type="uniform", exact=False, num_samples=1000):
degs = H.degree()
if exact:
k1k2 = [choose_nodes(e, degs, type) for e in H.edges if len(H.edges.members(e)) > 1]
k1k2 = [
choose_nodes(e, degs, type) for e in H.edges if len(H.edges.members(e)) > 1
]
else:
edges = list([e for e in H.edges if len(H.edges.members(e)) > 1])
nwlandry marked this conversation as resolved.
Show resolved Hide resolved
k1k2 = list()
Expand All @@ -60,17 +68,17 @@ def choose_nodes(e, k, type="uniform"):
j = i
while i == j:
j = np.random.randint(len(e))
return (np.array([k[e[i]], k[e[j]]]))
return np.array([k[e[i]], k[e[j]]])

elif type == "top-2":
degs = sorted([k[i] for i in e])[-2:]
random.shuffle(degs)
return (degs)
return degs

elif type == "top-bottom":
degs = sorted([k[i] for i in e])[::len(e)-1]
degs = sorted([k[i] for i in e])[:: len(e) - 1]
random.shuffle(degs)
return (degs)
return degs

else:
raise XGIError("Invalid choice function!")
4 changes: 1 addition & 3 deletions xgi/classes/reportviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
"""
from collections.abc import Mapping, Set

import numpy as np

from xgi.stats import NodeStatDispatcher, EdgeStatDispatcher
from xgi.exception import IDNotFound, XGIError
from xgi.stats import EdgeStatDispatcher, NodeStatDispatcher

__all__ = [
"NodeView",
Expand Down
9 changes: 4 additions & 5 deletions xgi/stats/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,15 @@

"""

from collections import defaultdict
from typing import Callable

import numpy as np
import pandas as pd
from typing import Callable
from collections import defaultdict

from xgi.exception import IDNotFound

from . import nodestats
from . import edgestats

from . import edgestats, nodestats

__all__ = ["nodestat_func", "edgestat_func", "EdgeStatDispatcher", "NodeStatDispatcher"]

Expand Down