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

Introduce and use decorators for graph sanitizers #289

Merged
merged 3 commits into from
Feb 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 3 additions & 7 deletions netrd/distance/communicability_jsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@
import networkx as nx
import numpy as np
from .base import BaseDistance
from ..utilities import entropy, ensure_undirected, ensure_unweighted
from ..utilities import entropy, undirected, unweighted


class CommunicabilityJSD(BaseDistance):
"""Jensen-Shannon divergence between communicability sequences."""

@undirected
@unweighted
def dist(self, G1, G2):
r"""Compares the communicability matrix of two graphs.

Expand Down Expand Up @@ -83,12 +85,6 @@ def dist(self, G1, G2):

"""

G1 = ensure_undirected(G1)
G2 = ensure_undirected(G2)

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

N1 = G1.number_of_nodes()
N2 = G2.number_of_nodes()

Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/degree_divergence.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
import numpy as np
import networkx as nx
from .base import BaseDistance
from ..utilities import entropy, ensure_unweighted
from ..utilities import entropy, unweighted


class DegreeDivergence(BaseDistance):
"""Compare two degree distributions."""

@unweighted
def dist(self, G1, G2):
"""Jenson-Shannon divergence between degree distributions.

Expand All @@ -40,9 +41,6 @@ def dist(self, G1, G2):

"""

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

def degree_vector_histogram(graph):
"""Return the degrees in both formats.

Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/deltacon.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
import numpy as np
import networkx as nx
from .base import BaseDistance
from ..utilities import ensure_undirected
from ..utilities import undirected


class DeltaCon(BaseDistance):
"""Compare matrices related to Fast Belief Propagation."""

@undirected
def dist(self, G1, G2, exact=True, g=None):
"""DeltaCon is based on the Matsusita between matrices created from fast
belief propagation (FBP) on graphs G1 and G2.
Expand Down Expand Up @@ -70,9 +71,6 @@ def dist(self, G1, G2, exact=True, g=None):
if not exact and g is None:
g = N

G1 = ensure_undirected(G1)
G2 = ensure_undirected(G2)

A1 = nx.to_numpy_array(G1)
L1 = nx.laplacian_matrix(G1).toarray()
D1 = L1 + A1
Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/distributional_nbd.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import networkx as nx
import scipy.sparse as sp
from scipy.spatial.distance import euclidean, chebyshev
from ..utilities.graph import ensure_unweighted
from ..utilities.graph import unweighted

from .base import BaseDistance

Expand All @@ -31,6 +31,7 @@ class DistributionalNBD(BaseDistance):

VECTOR_DISTANCES = {'euclidean': euclidean, 'chebyshev': chebyshev}

@unweighted
def dist(
self,
G1,
Expand Down Expand Up @@ -78,9 +79,6 @@ def dist(
The distance between `G1` and `G2`

"""
G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

B1 = reduced_hashimoto(G1, shave=shave, sparse=sparse, **kwargs)
B2 = reduced_hashimoto(G2, shave=shave, sparse=sparse, **kwargs)

Expand Down
9 changes: 3 additions & 6 deletions netrd/distance/dk_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
from scipy.sparse import coo_matrix
from collections import defaultdict
from .base import BaseDistance
from ..utilities import entropy, ensure_undirected, ensure_unweighted
from ..utilities import entropy, undirected, unweighted


class dkSeries(BaseDistance):
"""Compare graphs based on their :math:`dk`-series."""

@unweighted
@undirected
def dist(self, G1, G2, d=2):
r"""Compute the distance between two graphs by using the Jensen-Shannon
divergence between the :math:`dk`-series of the graphs.
Expand Down Expand Up @@ -59,11 +61,6 @@ def dist(self, G1, G2, d=2):

"""

G1 = ensure_undirected(G1)
G2 = ensure_undirected(G2)

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)
N = max(len(G1), len(G2))

if d == 1:
Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/dmeasure.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@
from scipy.stats import entropy
from .base import BaseDistance
from ..utilities.entropy import js_divergence
from ..utilities import ensure_undirected
from ..utilities import undirected


class DMeasure(BaseDistance):
"""Compare two graphs by their network node dispersion."""

@undirected
def dist(self, G1, G2, w1=0.45, w2=0.45, w3=0.10, niter=50):
r"""The D-Measure is a comparison of structural dissimilarities between graphs.

Expand Down Expand Up @@ -104,9 +105,6 @@ def dist(self, G1, G2, w1=0.45, w2=0.45, w3=0.10, niter=50):
if sum([w1, w2, w3]) != 1:
raise ValueError("Weights must sum to one.")

G1 = ensure_undirected(G1)
G2 = ensure_undirected(G2)

first_term = 0
second_term = 0
third_term = 0
Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/frobenius.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
import numpy as np
import networkx as nx
from .base import BaseDistance
from ..utilities.graph import ensure_unweighted
from ..utilities.graph import unweighted


class Frobenius(BaseDistance):
"""The Frobenius distance between their adjacency matrices."""

@unweighted
def dist(self, G1, G2):
r"""Frobenius distance between two graphs.

Expand Down Expand Up @@ -45,9 +46,6 @@ def dist(self, G1, G2):

"""

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

adj1 = nx.to_numpy_array(G1)
adj2 = nx.to_numpy_array(G2)
dist = np.linalg.norm((adj1 - adj2))
Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/hamming.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,13 @@
import numpy as np
import networkx as nx
from .base import BaseDistance
from ..utilities.graph import ensure_unweighted
from ..utilities import unweighted


class Hamming(BaseDistance):
"""Entry-wise disagreement between adjacency matrices."""

@unweighted
def dist(self, G1, G2):
r"""The proportion of disagreeing nodes between the flattened adjacency
matrices.
Expand Down Expand Up @@ -57,9 +58,6 @@ def dist(self, G1, G2):

"""

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

if G1.number_of_nodes() == G2.number_of_nodes():
N = G1.number_of_nodes()
else:
Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/hamming_ipsen_mikhailov.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
from .base import BaseDistance
from scipy.optimize import fsolve
from .ipsen_mikhailov import _im_distance
from ..utilities.graph import ensure_unweighted
from ..utilities.graph import unweighted


class HammingIpsenMikhailov(BaseDistance):
"""Combination of Hamming and Ipsen-Mikhailov distances."""

@unweighted
def dist(self, G1, G2, combination_factor=1):
"""Graph distance combining local and global distances.

Expand Down Expand Up @@ -80,9 +81,6 @@ def dist(self, G1, G2, combination_factor=1):
"""
N = len(G1)

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

# get the adjacency matrices
adj1 = nx.to_numpy_array(G1)
adj2 = nx.to_numpy_array(G2)
Expand Down
5 changes: 2 additions & 3 deletions netrd/distance/ipsen_mikhailov.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@
from scipy.sparse.csgraph import laplacian
from scipy.linalg import eigh
from scipy.integrate import quad
from ..utilities.graph import ensure_unweighted
from ..utilities.graph import unweighted


class IpsenMikhailov(BaseDistance):
"""Compares the spectrum of the Laplacian matrices."""

@unweighted
def dist(self, G1, G2, hwhm=0.08):
"""Compare the spectrum ot the associated Laplacian matrices.

Expand Down Expand Up @@ -58,8 +59,6 @@ def dist(self, G1, G2, hwhm=0.08):

"""
N = len(G1)
G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

# get the adjacency matrices
adj1 = nx.to_numpy_array(G1)
Expand Down
8 changes: 2 additions & 6 deletions netrd/distance/jaccard_distance.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@
"""

from .base import BaseDistance
import networkx as nx
import numpy as np
from ..utilities import ensure_unweighted
from ..utilities import unweighted


class JaccardDistance(BaseDistance):
"""Jaccard distance between edge sets."""

@unweighted
def dist(self, G1, G2):
r"""Compute the Jaccard index between two graphs.

Expand Down Expand Up @@ -50,9 +49,6 @@ def dist(self, G1, G2):

"""

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

e1 = set(G1.edges)
e2 = set(G2.edges)
cup = set.union(e1, e2)
Expand Down
5 changes: 2 additions & 3 deletions netrd/distance/laplacian_spectral_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import numpy as np
import networkx as nx
from .base import BaseDistance
from ..utilities.graph import ensure_unweighted
from ..utilities.graph import unweighted
from scipy.special import erf
from scipy.integrate import quad
from scipy.linalg import eigvalsh
Expand All @@ -27,6 +27,7 @@
class LaplacianSpectral(BaseDistance):
"""Flexible distance able to compare the spectrum of the Laplacian in many ways."""

@unweighted
def dist(
self,
G1,
Expand Down Expand Up @@ -113,8 +114,6 @@ def dist(
.. [2] https://ieeexplore.ieee.org/abstract/document/7344816.

"""
G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)
adj1 = nx.to_numpy_array(G1)
adj2 = nx.to_numpy_array(G2)
self.results['adjacency_matrices'] = adj1, adj2
Expand Down
6 changes: 2 additions & 4 deletions netrd/distance/nbd.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from .base import BaseDistance
from collections import defaultdict, Counter
from ortools.linear_solver import pywraplp
from ..utilities.graph import ensure_unweighted
from ..utilities import unweighted


class NonBacktrackingSpectral(BaseDistance):
Expand All @@ -23,6 +23,7 @@ class NonBacktrackingSpectral(BaseDistance):

"""

@unweighted
def dist(self, G1, G2, topk='automatic', batch=100, tol=1e-5):
"""Non-Backtracking Distance between two graphs.

Expand Down Expand Up @@ -53,9 +54,6 @@ def dist(self, G1, G2, topk='automatic', batch=100, tol=1e-5):

"""

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

vals1 = nbvals(G1, topk, batch, tol)
vals2 = nbvals(G2, topk, batch, tol)

Expand Down
10 changes: 3 additions & 7 deletions netrd/distance/netlsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
import scipy.linalg as spl

from .base import BaseDistance
from ..utilities import ensure_undirected, ensure_unweighted
from ..utilities import undirected, unweighted


class NetLSD(BaseDistance):
"""Compares spectral node signature distributions."""

@undirected
@unweighted
def dist(self, G1, G2, normalization=None, timescales=None):
"""NetLSD: Hearing the Shape of a Graph.

Expand Down Expand Up @@ -62,12 +64,6 @@ def dist(self, G1, G2, normalization=None, timescales=None):
normalization, str
), 'Normalization parameter must be of string type'

G1 = ensure_undirected(G1)
G2 = ensure_undirected(G2)

G1 = ensure_unweighted(G1)
G2 = ensure_unweighted(G2)

lap1 = nx.normalized_laplacian_matrix(G1)
lap2 = nx.normalized_laplacian_matrix(G2)

Expand Down
Loading