Source code for pywhy_graphs.classes.timeseries.graph
import networkx as nx
from pywhy_graphs.classes.timeseries.base import BaseTimeSeriesGraph, TsGraphEdgeMixin
[docs]
class TimeSeriesGraph(BaseTimeSeriesGraph, TsGraphEdgeMixin, nx.Graph):
"""A class to imbue undirected graph with time-series structure.
This should not be used directly. See ``BaseTimeSeriesGraph`` for documentation on the
functionality of time-series graphs.
"""
# whether or not the graph should be assumed to be stationary
stationary: bool = False
# whether to check for valid time-directionality in edges
check_time_direction: bool = False
def __init__(self, incoming_graph_data=None, max_lag: int = 1, **attr):
if max_lag <= 0:
raise ValueError(f"Max lag for time series graph should be at least 1, not {max_lag}.")
attr.update(dict(max_lag=max_lag))
self.graph = dict()
self.graph["max_lag"] = max_lag
super(TimeSeriesGraph, self).__init__(incoming_graph_data=None, **attr)
# TODO: this is needed because nx.from_edgelist() checks for type of 'create_using',
# which does not work with Protocol classes
if incoming_graph_data is not None:
# we assume a list of tuples of tuples as edges
if isinstance(incoming_graph_data, list):
self.add_edges_from(incoming_graph_data)
elif isinstance(incoming_graph_data, nx.Graph):
for edge in incoming_graph_data.edges:
self.add_edge(*sorted(edge, key=lambda x: x[1]))
else:
raise RuntimeError(
f"Not implemented yet for incoming graph data that is of "
f"type {type(incoming_graph_data)}."
)
[docs]
class StationaryTimeSeriesGraph(TimeSeriesGraph):
"""Stationary time-series graph without directionality on edges.
This class should not be used directly.
Included for completeness to enable modeling and working with ``nx.Graph`` like
objects with time-series structure. By the time-ordering assumption, all lagged
edges must point forward in time. This serves as an API layer to allow for
non-directed edges in time (i.e. circular edges among nodes in a ts-PAG).
Parameters
----------
incoming_graph_data : iterable, optional
The graph data to set, by default None.
max_lag : int, optional
Maximum lag, by default 1.
See Also
--------
StationaryTimeSeriesDiGraph
"""
# whether or not the graph should be assumed to be stationary
stationary: bool = True
def __init__(self, incoming_graph_data=None, max_lag: int = 1, stationary: bool = True, **attr):
self.stationary = stationary
super(StationaryTimeSeriesGraph, self).__init__(
incoming_graph_data=incoming_graph_data, max_lag=max_lag, **attr
)