From 5a8d8914b91c80a4c085be15d91292930f0ef9a8 Mon Sep 17 00:00:00 2001 From: Ingo Scholtes Date: Sun, 5 Oct 2025 14:18:01 +0000 Subject: [PATCH] removed asserts, logging, rename of method --- docs/tutorial/paths_higher_order.ipynb | 40 ++++++------- src/pathpyG/algorithms/centrality.py | 4 -- src/pathpyG/algorithms/generative_models.py | 35 +++++++---- src/pathpyG/core/graph.py | 31 ++++------ src/pathpyG/core/multi_order_model.py | 64 ++++++++++++--------- src/pathpyG/io/pandas.py | 11 +++- tests/algorithms/test_generative_models.py | 5 +- tests/core/test_graph.py | 4 +- tests/core/test_multi_order_model.py | 20 +++---- tests/nn/test_dbgnn.py | 4 +- tests/processes/conftest.py | 2 +- 11 files changed, 118 insertions(+), 102 deletions(-) diff --git a/docs/tutorial/paths_higher_order.ipynb b/docs/tutorial/paths_higher_order.ipynb index 1c6f8bfb3..55a8e6353 100644 --- a/docs/tutorial/paths_higher_order.ipynb +++ b/docs/tutorial/paths_higher_order.ipynb @@ -524,7 +524,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -817,7 +817,7 @@ } ], "source": [ - "m = pp.MultiOrderModel.from_PathData(paths, max_order=1)\n", + "m = pp.MultiOrderModel.from_path_data(paths, max_order=1)\n", "g = m.layers[1]\n", "print(g.data.edge_index)\n", "print(g.data.edge_weight)\n", @@ -869,7 +869,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1162,7 +1162,7 @@ } ], "source": [ - "m = pp.MultiOrderModel.from_PathData(paths_2, max_order=1)\n", + "m = pp.MultiOrderModel.from_path_data(paths_2, max_order=1)\n", "g = m.layers[1]\n", "print(g.data.edge_index)\n", "print(g.data.edge_weight)\n", @@ -1186,7 +1186,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1470,7 +1470,7 @@ } ], "source": [ - "m = pp.MultiOrderModel.from_PathData(paths, max_order=2)\n", + "m = pp.MultiOrderModel.from_path_data(paths, max_order=2)\n", "g = m.layers[2]\n", "pp.plot(g, node_label=g.nodes, edge_size=5);" ] @@ -1519,7 +1519,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -1803,7 +1803,7 @@ } ], "source": [ - "m = pp.MultiOrderModel.from_PathData(paths_2, max_order=2)\n", + "m = pp.MultiOrderModel.from_path_data(paths_2, max_order=2)\n", "g = m.layers[2]\n", "pp.plot(g, node_label=g.nodes);" ] @@ -2251,7 +2251,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2271,7 +2271,7 @@ } ], "source": [ - "m1 = pp.MultiOrderModel.from_PathData(paths, max_order=2)\n", + "m1 = pp.MultiOrderModel.from_path_data(paths, max_order=2)\n", "print(m1.estimate_order(paths, significance_threshold=0.01))" ] }, @@ -2284,7 +2284,7 @@ }, { "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2296,7 +2296,7 @@ } ], "source": [ - "m2 = pp.MultiOrderModel.from_PathData(paths_2, max_order=2)\n", + "m2 = pp.MultiOrderModel.from_path_data(paths_2, max_order=2)\n", "print(m2.estimate_order(paths_2, significance_threshold=0.01))" ] }, @@ -2309,7 +2309,7 @@ }, { "cell_type": "code", - "execution_count": 21, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2334,7 +2334,7 @@ "paths_3.append_walk(('b', 'c', 'e'), weight=6.0)\n", "paths_3.append_walk(('b', 'c', 'd'), weight=2.0)\n", "\n", - "m3 = pp.MultiOrderModel.from_PathData(paths_3, max_order=2)\n", + "m3 = pp.MultiOrderModel.from_path_data(paths_3, max_order=2)\n", "print(m3.layers[1].data.edge_weight)\n", "print(m3.estimate_order(paths_3, significance_threshold=0.01))" ] @@ -2372,7 +2372,7 @@ }, { "cell_type": "code", - "execution_count": 23, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2393,7 +2393,7 @@ "paths_3.append_walk(('b', 'c', 'e'), weight=7.0)\n", "paths_3.append_walk(('b', 'c', 'd'), weight=1.0)\n", "\n", - "m3 = pp.MultiOrderModel.from_PathData(paths_3, max_order=2)\n", + "m3 = pp.MultiOrderModel.from_path_data(paths_3, max_order=2)\n", "print(m3.layers[1].data.edge_weight)\n", "print(m3.estimate_order(paths_3, significance_threshold=0.01))" ] @@ -2457,7 +2457,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2741,7 +2741,7 @@ } ], "source": [ - "m = pp.MultiOrderModel.from_PathData(paths_tube, max_order=1)\n", + "m = pp.MultiOrderModel.from_path_data(paths_tube, max_order=1)\n", "g = m.layers[1]\n", "pp.plot(g, node_label=g.mapping.node_ids.tolist());" ] @@ -2755,7 +2755,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -2771,7 +2771,7 @@ ], "source": [ "paths_tube.to(device)\n", - "m = pp.MultiOrderModel.from_PathData(paths_tube, max_order=20)\n", + "m = pp.MultiOrderModel.from_path_data(paths_tube, max_order=20)\n", "print(m.layers[20])" ] }, diff --git a/src/pathpyG/algorithms/centrality.py b/src/pathpyG/algorithms/centrality.py index f05a8a6bd..f5f2c4604 100644 --- a/src/pathpyG/algorithms/centrality.py +++ b/src/pathpyG/algorithms/centrality.py @@ -152,10 +152,6 @@ def path_visitation_probabilities(paths: PathData) -> dict: Args: paths: PathData object that contains path data """ - # if not isinstance(paths, PathData): - # assert False, "`paths` must be an instance of Paths" - # Log.add('Calculating visitation probabilities...', Severity.INFO) - # entries capture the probability that a given node is visited on an arbitrary path # Note: this is identical to the subpath count of zero-length paths # (i.e. the relative frequencies of nodes across all pathways) diff --git a/src/pathpyG/algorithms/generative_models.py b/src/pathpyG/algorithms/generative_models.py index 33243ea94..86a877db9 100644 --- a/src/pathpyG/algorithms/generative_models.py +++ b/src/pathpyG/algorithms/generative_models.py @@ -22,9 +22,13 @@ import torch from torch_geometric.utils import degree +import logging + from pathpyG.core.graph import Graph from pathpyG.core.index_map import IndexMap +logger = logging.getLogger("root") + def max_edges(n: int, directed: bool = False, multi_edges: bool = False, self_loops: bool = False) -> int | float: """Returns the maximum number of edges that a directed or undirected network with n nodes can @@ -82,7 +86,9 @@ def erdos_renyi_gnm(n: int, m: int, mapping: IndexMap | None = None, Returns: Graph: graph object """ - assert m <= max_edges(n, directed=directed, self_loops=self_loops, multi_edges=multi_edges) + if m > max_edges(n, directed=directed, self_loops=self_loops, multi_edges=multi_edges): + logger.error("Given number of edges is larger than theoretical maximum") + raise ValueError("Given number of edges is larger than theoretical maximum") edges = set() edges_added: int = 0 @@ -186,20 +192,26 @@ def erdos_renyi_gnp_randomize(graph: Graph, self_loops: bool = False) -> Graph: def erdos_renyi_gnp_likelihood(p: float, graph: Graph) -> float: - """Calculate the likelihood of parameter p for a G(n,p) model and a given graph""" - assert graph.is_directed() is False + """Calculate the likelihood of parameter p for a G(n,p) model and a given undirected graph""" + if graph.is_directed(): + logger.error("erdos_renyi_gnp_likelihood does not support directed graphs") + raise NotImplementedError("erdos_renyi_gnp_likelihood does not support directed graphs") return p**graph.n * (1 - p) ** (scipy.special.binom(graph.n, 2) - graph.m) def erdos_renyi_gnp_log_likelihood(p: float, graph: Graph) -> float: - """Calculate the log-likelihood of parameter p for a G(n,p) model and a given graph""" - assert graph.is_directed() is False + """Calculate the log-likelihood of parameter p for a G(n,p) model and a given undirected graph""" + if graph.is_directed(): + logger.error("erdos_renyi_gnp_log_likelihood does not support directed graphs") + raise NotImplementedError("erdos_renyi_gnp_log_likelihood does not support directed graphs") return graph.m * _np.log10(p) + (scipy.special.binom(graph.n, 2) - (graph.m)) * _np.log10(1 - p) def erdos_renyi_gnp_mle(graph: Graph) -> float: """Calculate the maximum likelihood estimate of parameter p for a G(n,p) model and a given undirected graph""" - assert graph.is_directed() is False + if graph.is_directed(): + logger.error("erdos_renyi_gnp_mle does not support directed graphs") + raise NotImplementedError("erdos_renyi_gnp_mle does not support directed graphs") return graph.m / scipy.special.binom(graph.n, 2) @@ -246,11 +258,12 @@ def watts_strogatz( if not allow_duplicate_edges: if n * (n - 1) < edges.shape[1]: + logger.error("number of edges is greater than the number of possible edges in the graph. Set `allow_duplicate_edges=True` to allow this.") raise ValueError( - "The number of edges is greater than the number of possible edges in the graph. Set `allow_duplicate_edges=True` to allow this." + "number of edges is greater than the number of possible edges in the graph. Set `allow_duplicate_edges=True` to allow this." ) elif n * (n - 1) * 0.5 < edges.shape[1] and p > 0.3: - warnings.warn( + logger.info( "Avoding duplicate in graphs with high connectivity and high rewiring probability may be slow. Consider setting `allow_duplicate_edges=True`." ) @@ -426,7 +439,8 @@ def molloy_reed(degree_sequence: _np.array | Dict[int, float], # assume that we are given a graphical degree sequence if not is_graphic_erdos_gallai(degree_sequence): - raise AttributeError('degree sequence is not graphic') + logger.error("given degree sequence is not graphic") + raise ValueError('gicen degree sequence is not graphic') # create empty network with n nodes n = len(degree_sequence) @@ -466,9 +480,10 @@ def molloy_reed(degree_sequence: _np.array | Dict[int, float], def molloy_reed_randomize(g: Graph) -> Optional[Graph]: - """Generates a random realization of a given network based on the observed degree sequence. + """Generates a randomized realization of a given undirected network based on the observed degree sequence. """ if g.is_directed(): + logger.error("molloy_reed_randomize is only implemented for undirected graphs") raise NotImplementedError('molloy_reed_randomize is only implemented for undirected graphs') # degrees are listed in order of node indices degrees = degree(g.data.edge_index[1], num_nodes=g.n, dtype=torch.int).tolist() diff --git a/src/pathpyG/core/graph.py b/src/pathpyG/core/graph.py index 28d0e9a46..c76f6fdd1 100644 --- a/src/pathpyG/core/graph.py +++ b/src/pathpyG/core/graph.py @@ -19,8 +19,11 @@ from torch_geometric.data import Data from torch_geometric.utils import scatter, to_undirected +import logging from pathpyG.core.index_map import IndexMap +logger = logging.getLogger("root") + class Graph: """ @@ -60,8 +63,9 @@ def __init__(self, data: Data, mapping: Optional[IndexMap] = None): self.mapping = mapping # set num_nodes property - if "num_nodes" not in data and "edge_index" in data: + if "num_nodes" not in data and "edge_index" in data: data.num_nodes = data.edge_index.max().item() + 1 + logger.debug("Inferred number of nodes from edge_index, n = %s", data.num_nodes) # turn edge index tensor into EdgeIndex object if not isinstance(data.edge_index, EdgeIndex): @@ -71,7 +75,8 @@ def __init__(self, data: Data, mapping: Optional[IndexMap] = None): data.edge_index.get_sparse_size(dim=0) != data.num_nodes or data.edge_index.get_sparse_size(dim=1) != data.num_nodes ): - raise Exception("sparse size of EdgeIndex should match number of nodes!") + logger.error("Sparse size of edge_index does not match number of nodes, n = %s", data.num_nodes) + raise ValueError("sparse size of EdgeIndex must match number of nodes!") self.data = data @@ -128,6 +133,7 @@ def from_edge_index(edge_index: torch.Tensor, mapping: Optional[IndexMap] = None d = Data(edge_index=edge_index) else: if mapping is not None and mapping.num_ids() != num_nodes: + logger.error("Number of node IDs in mapping must match num_nodes") raise ValueError("Number of node IDs in mapping must match num_nodes") d = Data(edge_index=edge_index, num_nodes=num_nodes) return Graph(d, mapping=mapping) @@ -456,7 +462,8 @@ def out_degrees(self) -> Dict[str, float]: """ return self.degrees(mode="out") - def degrees(self, mode: str = "in", edge_attr: Any = None, return_tensor: bool = False) -> Dict[str, float]: + def degrees(self, mode: str = "in", edge_attr: Any = None, return_tensor: bool = False) -> Union[Dict[str, float], + torch.tensor]: """ Return (weighted) degrees of nodes. @@ -487,24 +494,6 @@ def degrees(self, mode: str = "in", edge_attr: Any = None, return_tensor: bool = else: return {str(self.mapping.to_id(i)): d[i].item() for i in range(self.n)} - # def weighted_outdegrees(self) -> torch.Tensor: - # """ - # Compute the weighted outdegrees of each node in the graph. - - # Args: - # graph (Graph): pathpy graph object. - - # Returns: - # tensor: Weighted outdegrees of nodes. - # """ - # edge_weight = getattr(self.data, "edge_weight", None) - # if edge_weight is None: - # edge_weight = torch.ones(self.data.num_edges, device=self.data.edge_index.device) - # weighted_outdegree = scatter( - # edge_weight, self.data.edge_index[0], dim=0, dim_size=self.data.num_nodes, reduce="sum" - # ) - # return weighted_outdegree - def transition_probabilities(self, edge_attr: Any = None) -> torch.Tensor: """ Compute transition probabilities based on (weighted) outdegrees. diff --git a/src/pathpyG/core/multi_order_model.py b/src/pathpyG/core/multi_order_model.py index d0c70ec07..9affbcb10 100644 --- a/src/pathpyG/core/multi_order_model.py +++ b/src/pathpyG/core/multi_order_model.py @@ -1,10 +1,17 @@ from __future__ import annotations +from typing import ( + TYPE_CHECKING, + Optional, +) from scipy.stats import chi2 import torch from torch_geometric.data import Data from torch_geometric.utils import degree, cumsum + +import logging + from pathpyG.core.graph import Graph from pathpyG.core.path_data import PathData from pathpyG.core.temporal_graph import TemporalGraph @@ -18,6 +25,8 @@ aggregate_edge_index, ) +logger = logging.getLogger("root") + class MultiOrderModel: """MultiOrderModel based on torch_geometric.Data.""" @@ -89,7 +98,7 @@ def from_temporal_graph( max_order: int = 1, weight: str = "edge_weight", cached: bool = True, - event_graph: torch.Tensor = None, + event_graph: Optional[torch.Tensor] = None, ) -> MultiOrderModel: """Creates multiple higher-order De Bruijn graph models for paths in a temporal graph. @@ -150,11 +159,10 @@ def from_temporal_graph( ) if cached or k == max_order: m.layers[k] = gk - return m @staticmethod - def from_PathData( + def from_path_data( path_data: PathData, max_order: int = 1, mode: str = "propagation", cached: bool = True ) -> MultiOrderModel: """ @@ -203,7 +211,7 @@ def from_PathData( return m - def get_mon_dof(self, max_order: int = None, assumption: str = "paths") -> int: + def get_mon_dof(self, max_order: Optional[int] = None, assumption: str = "paths") -> int: """ The degrees of freedom for the kth layer of a multi-order model. This depends on the number of different paths of exactly length `k` in the graph. Therefore, we can obtain these values by summing the entries of the `k`-th power of the binary adjacency matrix of the graph. @@ -225,16 +233,17 @@ def get_mon_dof(self, max_order: int = None, assumption: str = "paths") -> int: int: The degrees of freedom for the multi-order model. Raises: - AssertionError: If max_order is larger than the maximum order of + ValueError: If max_order is larger than the maximum order of the multi-order network. ValueError: If the assumption is not 'paths' or 'ngrams'. """ if max_order is None: max_order = max(self.layers) - assert max_order <= max( - self.layers - ), "Error: max_order cannot be larger than maximum order of multi-order network" + if max_order > max(self.layers): + logger.error("max_order cannot be larger than maximum order of multi-order network") + raise ValueError("max_order cannot be larger than maximum order of multi-order network") + dof = self.layers[1].data.num_nodes - 1 # Degrees of freedom for zeroth order @@ -268,8 +277,9 @@ def get_mon_dof(self, max_order: int = None, assumption: str = "paths") -> int: for order in range(1, max_order + 1): dof += (self.layers[1].data.num_nodes**order) * (self.layers[1].data.num_nodes - 1) else: + logger.error("Unknown assumption %s. Only 'path' and 'ngram' are accepted.", assumption) raise ValueError( - f"Unknown assumption {assumption} in input. The only accepted values are 'path' and 'ngram'" + f"Unknown assumption {assumption}. Only 'path' and 'ngram' are accepted." ) return int(dof) @@ -400,12 +410,12 @@ def likelihood_ratio_test( tuple: A tuple containing a boolean indicating whether the null hypothesis is rejected and the p-value of the test. """ - assert ( - max_order_null < max_order - ), "Error: order of null hypothesis must be smaller than order of alternative hypothesis" - assert max_order <= max( - self.layers - ), f"Error: order of hypotheses ({max_order_null} and {max_order}) must be smaller than the maximum order of the MultiOrderModel {max(self.layers)}" + if max_order_null >= max_order: + logger.error("order of null hypothesis must be smaller than order of alternative hypothesis") + raise ValueError("order of null hypothesis must be smaller than order of alternative hypothesis") + if max_order > max(self.layers): + logger.error("order of hypotheses must be smaller than max. order of MultiOrderModel") + raise ValueError(f"order of hypotheses ({max_order_null} and {max_order}) must be smaller than max. order of MultiOrderModel {max(self.layers)}") # let L0 be the likelihood for the null model and L1 be the likelihood for the alternative model # we first compute a test statistic x = -2 * log (L0/L1) = -2 * (log L0 - log L1) @@ -423,7 +433,7 @@ def likelihood_ratio_test( p = 1 - chi2.cdf(x, dof_diff) return (p < significance_threshold), p - def estimate_order(self, dag_data: PathData, max_order: int = None, significance_threshold: float = 0.01) -> int: + def estimate_order(self, dag_data: PathData, max_order: Optional[int] = None, significance_threshold: float = 0.01) -> int: """ Selects the optimal maximum order of a multi-order network model for the observed paths, based on a likelihood ratio test with p-value threshold of p @@ -440,19 +450,20 @@ def estimate_order(self, dag_data: PathData, max_order: int = None, significance int: The estimated optimal maximum order for the multi-order network model. Raises: - AssertionError: If the provided max_order is larger than the maximum order of the multi-order model + ValueError: If the provided max_order is larger than the maximum order of the multi-order model or if the input DAGData does not have the same set of nodes as the multi-order network """ if max_order is None: - max_order = max(self.layers) # THIS - assert max_order <= max( - self.layers - ), "Error: maxOrder cannot be larger than maximum order of multi-order network" - assert max_order > 1, "Error: max_order must be larger than one" - - assert set(dag_data.mapping.node_ids).intersection(set(self.layers[1].mapping.node_ids)) == set( - dag_data.mapping.node_ids - ), "Input DAGData doesn t have the same set of nodes as those of the multi-order network" + max_order = max(self.layers) + if max_order > max(self.layers): + logger.error("max_order cannot be larger than maximum order of multi-order network") + raise ValueError("max_order cannot be larger than maximum order of multi-order network") + if max_order <= 1: + logger.error("max_order must be larger than one") + raise ValueError("max_order must be larger than one") + if set(dag_data.mapping.node_ids).intersection(set(self.layers[1].mapping.node_ids)) != set(dag_data.mapping.node_ids): + logger.error("Input paths do not have same set of nodes as multi-order network") + raise ValueError("Input paths do not have same set of nodes as multi-order network") max_accepted_order = 1 dag_graph = dag_data.data @@ -480,6 +491,7 @@ def to_dbgnn_data(self, max_order: int = 2, mapping: str = "last") -> Data: Data: The De Bruijn graph data. """ if max_order not in self.layers: + logger.error("Higher-order graph of specified order not found.") raise ValueError(f"Higher-order graph of order {max_order} not found.") g = self.layers[1] diff --git a/src/pathpyG/io/pandas.py b/src/pathpyG/io/pandas.py index 3748b45eb..d32ab058b 100644 --- a/src/pathpyG/io/pandas.py +++ b/src/pathpyG/io/pandas.py @@ -252,7 +252,9 @@ def add_edge_attributes(df: pd.DataFrame, g: Graph, time_attr: str | None = None g: The graph to which the edge attributes should be added. time_attr: If not None, the name of the column containing time stamps for temporal edges. """ - assert "v" in df and "w" in df, "Data frame must have columns `v` and `w` for source and target nodes" + if "v" not in df or "w" not in df: + logger.error("Data frame must have columns `v` and `w` for source and target nodes") + raise ValueError("Data frame must have columns `v` and `w` for source and target nodes") # check for non-existent nodes node_ids = set(df["v"]).union(set(df["w"])) @@ -276,7 +278,9 @@ def add_edge_attributes(df: pd.DataFrame, g: Graph, time_attr: str | None = None edge_attrs = [attr for attr in df.columns if attr not in ["v", "w"]] if time_attr is not None: - assert time_attr in df, f"Data frame must have column `{time_attr}` for time stamps" + if time_attr not in df: + logger.error("Data frame must have column %s for time stamps", time_attr) + raise ValueError(f"Data frame must have column {time_attr} for time stamps") time = df[time_attr].values edge_attrs.remove(time_attr) @@ -286,6 +290,7 @@ def add_edge_attributes(df: pd.DataFrame, g: Graph, time_attr: str | None = None for src_i, tgt_i, time_i in zip(src, tgt, time): edge = g.tedge_to_index.get((src_i.item(), tgt_i.item(), time_i.item()), None) # type: ignore if edge is None: + logger.error("found non-existing edge in temporal graph") raise ValueError( f"Edge ({src_i.item()}, {tgt_i.item()}) does not exist at time {time_i.item()} in the graph." ) @@ -296,6 +301,7 @@ def add_edge_attributes(df: pd.DataFrame, g: Graph, time_attr: str | None = None for src_i, tgt_i in zip(src, tgt): edge = g.edge_to_index.get((src_i.item(), tgt_i.item()), None) if edge is None: + logger.error("found non-existing edge in temporal graph") raise ValueError(f"Edge ({src_i.item()}, {tgt_i.item()}) does not exist in the graph.") edge_idx.append(edge) @@ -364,6 +370,7 @@ def df_to_temporal_graph( if no_header: # interpret first two columns as source and target + logger.info("Interpreting first three columns as v, w, t") col_names = ["v", "w", "t"] # interpret remaining columns as edge attributes for i in range(3, len(df.columns.values.tolist())): diff --git a/tests/algorithms/test_generative_models.py b/tests/algorithms/test_generative_models.py index 45e036489..5b20d2062 100644 --- a/tests/algorithms/test_generative_models.py +++ b/tests/algorithms/test_generative_models.py @@ -232,13 +232,10 @@ def test_watts_strogatz_rewiring(): assert ratio < 0.6 -def test_watts_strogatz_get_warning(): +def test_watts_strogatz_get_error(): with pytest.raises(ValueError): print(watts_strogatz(5, 10, 0.5, allow_duplicate_edges=False)) - with pytest.warns(Warning): - print(watts_strogatz(10, 5, 0.31, allow_duplicate_edges=False)) - def test_stochastic_block_model(): M = np.matrix('0.95 0.15; 0.15 0.85') diff --git a/tests/core/test_graph.py b/tests/core/test_graph.py index 9b05c74b4..b22348ad9 100644 --- a/tests/core/test_graph.py +++ b/tests/core/test_graph.py @@ -358,8 +358,8 @@ def test_add_with_edge_attrs(): def test_higher_order_graph(simple_walks, simple_walks_2): - ho_g1 = MultiOrderModel.from_PathData(simple_walks, max_order=2).layers[2] - ho_g2 = MultiOrderModel.from_PathData(simple_walks_2, max_order=2).layers[2] + ho_g1 = MultiOrderModel.from_path_data(simple_walks, max_order=2).layers[2] + ho_g2 = MultiOrderModel.from_path_data(simple_walks_2, max_order=2).layers[2] g = ho_g1 + ho_g2 assert g.n == 4 diff --git a/tests/core/test_multi_order_model.py b/tests/core/test_multi_order_model.py index 9d28b194c..ce0e1be6e 100644 --- a/tests/core/test_multi_order_model.py +++ b/tests/core/test_multi_order_model.py @@ -47,7 +47,7 @@ def test_dof(): line_data = PathData(IndexMap(list("abcd"))) line_data.append_walk(("a", "b", "c", "d")) max_order = 4 - m = MultiOrderModel.from_PathData(line_data, max_order=max_order) + m = MultiOrderModel.from_path_data(line_data, max_order=max_order) for order in range(max_order + 1): assert m.get_mon_dof(assumption="paths", max_order=order) == 3 @@ -57,7 +57,7 @@ def test_dof(): toy_paths_ho.append_walk(("a", "c", "d")) toy_paths_ho.append_walk(("b", "c", "e")) max_order = 2 - m = MultiOrderModel.from_PathData(toy_paths_ho, max_order=max_order, mode="propagation") + m = MultiOrderModel.from_path_data(toy_paths_ho, max_order=max_order, mode="propagation") assert m.get_mon_dof(assumption="paths", max_order=0) == 4 assert m.get_mon_dof(assumption="paths", max_order=1) == 5 assert m.get_mon_dof(assumption="paths", max_order=2) == 7 @@ -84,7 +84,7 @@ def test_likelihood_ratio_test(): toy_paths_ho.append_walk(("b", "c", "e")) dag_graph = toy_paths_ho.data max_order = 2 - m = MultiOrderModel.from_PathData(toy_paths_ho, max_order=max_order) + m = MultiOrderModel.from_path_data(toy_paths_ho, max_order=max_order) bool_code_01, p_01_code = m.likelihood_ratio_test( dag_graph, max_order_null=0, max_order=1, assumption="paths", significance_threshold=significance_threshold @@ -105,7 +105,7 @@ def test_log_likelihood(): toy_paths_ho.append_walk(("a", "c", "d")) toy_paths_ho.append_walk(("b", "c", "e")) max_order = 2 - m = MultiOrderModel.from_PathData(toy_paths_ho, max_order=max_order, mode="propagation") + m = MultiOrderModel.from_path_data(toy_paths_ho, max_order=max_order, mode="propagation") dag_graph = toy_paths_ho.data assert np.isclose(m.get_mon_log_likelihood(dag_graph, max_order=0), np.log(1 / 6) * 4 + np.log(2 / 6) * 2) assert np.isclose(m.get_mon_log_likelihood(dag_graph, max_order=1), np.log(1 / 6) * 2 + 0 + 2 * np.log(1 / 2)) @@ -118,7 +118,7 @@ def test_log_likelihood(): toy_paths.append_walk(("a", "c", "e")) toy_paths.append_walk(("b", "c", "d")) max_order = 2 - m = MultiOrderModel.from_PathData(toy_paths, max_order=max_order, mode="propagation") + m = MultiOrderModel.from_path_data(toy_paths, max_order=max_order, mode="propagation") dag_graph = toy_paths.data assert np.isclose( m.get_mon_log_likelihood(dag_graph, max_order=0), # fails already at computing log_lh here @@ -134,7 +134,7 @@ def test_log_likelihood(): toy_paths.append_walk(("a", "b")) toy_paths.append_walk(("a", "b", "c")) max_order = 2 - m = MultiOrderModel.from_PathData(toy_paths, max_order=max_order, mode="propagation") + m = MultiOrderModel.from_path_data(toy_paths, max_order=max_order, mode="propagation") dag_graph = toy_paths.data assert np.isclose( m.get_mon_log_likelihood(dag_graph, max_order=0), # fails already at computing log_lh here @@ -153,18 +153,18 @@ def test_estimate_order(): toy_paths_ho = PathData(IndexMap(list("abcde"))) toy_paths_ho.append_walk(("a", "c", "d"), weight=3) toy_paths_ho.append_walk(("b", "c", "e"), weight=3) - m = MultiOrderModel.from_PathData(toy_paths_ho, max_order=2) + m = MultiOrderModel.from_path_data(toy_paths_ho, max_order=2) assert m.estimate_order(toy_paths_ho, max_order=max_order, significance_threshold=significance_threshold) == 1 toy_paths_ho = PathData(IndexMap(list("abcde"))) toy_paths_ho.append_walk(("a", "c", "d"), weight=4) toy_paths_ho.append_walk(("b", "c", "e"), weight=4) - m = MultiOrderModel.from_PathData(toy_paths_ho, max_order=max_order) + m = MultiOrderModel.from_path_data(toy_paths_ho, max_order=max_order) assert m.estimate_order(toy_paths_ho, max_order=2, significance_threshold=significance_threshold) == 2 def test_multi_order_model_from_paths(simple_walks_2): - m = MultiOrderModel.from_PathData(simple_walks_2, max_order=2) + m = MultiOrderModel.from_path_data(simple_walks_2, max_order=2) g1 = m.layers[1] g2 = m.layers[2] assert torch.equal(g1.data.edge_index, EdgeIndex([[0, 1, 2, 2], [2, 2, 3, 4]])) @@ -216,7 +216,7 @@ def test_paths_indexing(): pathdata = PathData(mapping) pathdata.append_walks(node_seqs=paths_list, weights=frequencies) max_order = 3 - mon = MultiOrderModel.from_PathData(pathdata, max_order=max_order) + mon = MultiOrderModel.from_path_data(pathdata, max_order=max_order) detected_order = mon.estimate_order( pathdata, max_order=max_order diff --git a/tests/nn/test_dbgnn.py b/tests/nn/test_dbgnn.py index efacc5d37..d5625c5bb 100644 --- a/tests/nn/test_dbgnn.py +++ b/tests/nn/test_dbgnn.py @@ -10,7 +10,7 @@ def test_bipartite_edge_index(simple_walks): - m = MultiOrderModel.from_PathData(simple_walks, max_order=2) + m = MultiOrderModel.from_path_data(simple_walks, max_order=2) g = m.layers[1] print(g.data.edge_index) print(g.mapping) @@ -32,7 +32,7 @@ def test_bipartite_edge_index(simple_walks): def test_dbgnn(simple_walks): - m = MultiOrderModel.from_PathData(simple_walks, max_order=2) + m = MultiOrderModel.from_path_data(simple_walks, max_order=2) data = m.to_dbgnn_data() g1 = m.layers[1] g2 = m.layers[2] diff --git a/tests/processes/conftest.py b/tests/processes/conftest.py index 63a2abe04..deccd6e1e 100644 --- a/tests/processes/conftest.py +++ b/tests/processes/conftest.py @@ -48,5 +48,5 @@ def simple_second_order_graph() -> Tuple[Graph, Graph]: paths.append_walk(["c", "d", "a"], weight=0.2) paths.append_walk(["d", "a", "b"], weight=1) - m = MultiOrderModel.from_PathData(paths, max_order=2) + m = MultiOrderModel.from_path_data(paths, max_order=2) return (g, m.layers[2])