Skip to content

Algorithm steps

The four algorithm steps as standalone functions. Each takes a TimeSeriesGraph (or produces one for Step 1) and mutates it in place.

discover_lagged_adjacencies

discover_lagged_adjacencies(
    data: ndarray,
    tau_max: int,
    *,
    ci_test: str | CITest = "fisherz",
    alpha: float = 0.05,
    pc_alpha: float = 0.2,
    max_conds_dim: int | None = None,
    var_names: list[str] | None = None,
    verbose: bool = False,
) -> TimeSeriesGraph

Identify lagged parents for every variable using PCMCI.

Parameters:

Name Type Description Default
data ndarray

Time series, shape (n_samples, n_vars).

required
tau_max int

Maximum lag to consider.

required
ci_test str | CITest

CI test name ("fisherz" or "kci") or an instance.

'fisherz'
alpha float

Significance level for the final MCI step.

0.05
pc_alpha float

Looser significance level for the PC step. Following PCMCI conventions this is usually larger than alpha.

0.2
max_conds_dim int | None

Cap on the size of conditioning sets in the PC step. None (default) means no cap.

None
var_names list[str] | None

Optional variable names for the returned graph.

None
verbose bool

Print per-variable progress.

False

Returns:

Type Description
TimeSeriesGraph

Graph with lagged_edges populated and an empty contemporaneous skeleton (filled in by Step 2).

build_partial_graph

build_partial_graph(graph: TimeSeriesGraph) -> TimeSeriesGraph

Add the fully-connected contemporaneous skeleton to graph.

Modifies graph in place and returns it. The lagged edges already present are preserved untouched.

Parameters:

Name Type Description Default
graph TimeSeriesGraph

The output of Step 1 (lagged adjacency identification).

required

Returns:

Type Description
TimeSeriesGraph

The same graph with all contemporaneous pairs (i, j) for i < j connected by an undirected edge.

refine_skeleton

refine_skeleton(
    graph: TimeSeriesGraph,
    data: ndarray,
    *,
    surrogate: ndarray | None = None,
    ci_test: str | CITest = "fisherz",
    alpha: float = 0.05,
    max_extra_conds: int = 2,
    verbose: bool = False,
) -> TimeSeriesGraph

Prune contemporaneous edges and confirm changing modules.

Two passes:

  1. Contemporaneous skeleton refinement. For each undirected pair (i, j) already in the graph, run CI tests with conditioning sets drawn from the lagged parents of i and j, plus up to max_extra_conds of their contemporaneous neighbors. Drop the edge if any test gives a p-value above alpha. Witness sets are stored on the graph for use by Step 4 (v-structure detection).

  2. Changing-modules confirmation. For each variable i initially marked as changing in Step 2, test X_i ⊥ C | lagged_parents(i). If the test passes (independence not rejected), i is unmarked.

Parameters:

Name Type Description Default
graph TimeSeriesGraph

Graph from Step 2 (lagged edges + fully-connected contemporaneous skeleton + all variables marked changing).

required
data ndarray

Time series, shape (n_samples, n_vars).

required
surrogate ndarray | None

Surrogate variable C of shape (n_samples,) or (n_samples, 1). If None, the time index [0, 1, ..., T-1] is used (appropriate for nonstationary single-domain data).

None
ci_test str | CITest

CI test name or instance.

'fisherz'
alpha float

Significance level.

0.05
max_extra_conds int

Maximum number of contemporaneous neighbors to include in the conditioning set in addition to the lagged parents. Bigger values give stronger tests but at quadratic cost.

2
verbose bool

Print per-edge progress.

False

Returns:

Type Description
TimeSeriesGraph

The same graph with edges pruned and changing modules confirmed. A witness attribute is attached as graph._witness_sets.

orient_edges

orient_edges(
    graph: TimeSeriesGraph,
    *,
    data: NDArray[float64] | None = None,
    surrogate: NDArray[float64] | None = None,
    use_independent_change: bool = True,
    independent_change_width: WidthSpec = AUTO,
) -> TimeSeriesGraph

Orient contemporaneous edges in the graph in place.

Parameters:

Name Type Description Default
graph TimeSeriesGraph

Graph from Step 3 (lagged + contemporaneous skeleton + confirmed changing modules + _witness_sets attribute).

required
data NDArray[float64] | None

Time series, shape (n_samples, n_vars). Required when use_independent_change=True and there are at least two connected changing modules with undirected edges.

None
surrogate NDArray[float64] | None

Distribution-shift surrogate, shape (n_samples,) or (n_samples, 1). Same requirement as data. Truncated to match the lagged design matrix length internally.

None
use_independent_change bool

Whether to run the independent-change-principle sink-finding sub-pass. Setting this to False returns the Markov equivalence class without trying to break ties on undirected edges between changing modules.

True
independent_change_width WidthSpec

Bandwidth for the kernels inside :func:independent_change_score. "auto" (default) picks per-call via the median heuristic on the standardized parents; "gp" learns the bandwidth via a Gaussian-process fit with an ARD-RBF kernel (slower, more adaptive); a positive float forces a manual value. The MATLAB reference uses 0.1.

AUTO

Returns:

Type Description
TimeSeriesGraph

The same graph with as many contemporaneous edges oriented as the algorithm can determine.