att.binding

Binding detection via persistence image subtraction.

class att.binding.BindingDetector(max_dim=1, method='persistence_image', image_resolution=50, image_sigma=0.1, baseline='max', embedding_quality_gate=True)[source]

Bases: object

Detect topological binding between coupled dynamical systems.

Computes persistence images for joint and marginal embeddings, then measures excess topology in the joint that is absent from both marginals.

Parameters:
  • max_dim (int) – Maximum homology dimension (0=components, 1=loops).

  • method (str) – “persistence_image” (PI subtraction) or “diagram_matching” (optimal matching via Hungarian algorithm).

  • image_resolution (int) – Resolution of persistence images.

  • image_sigma (float) – Gaussian kernel bandwidth for persistence images.

  • baseline (str) – “max” (conservative, pointwise max of marginals) or “sum” (sensitive, pointwise sum of marginals).

  • embedding_quality_gate (bool) – If True, validate all three embeddings and warn if any is degenerate.

fit(X, Y, joint_embedder=None, marginal_embedder_x=None, marginal_embedder_y=None, subsample=None, seed=None, n_ensemble=1)[source]

Fit the detector on two coupled time series.

Parameters:
  • X (1D time series arrays)

  • Y (1D time series arrays)

  • joint_embedder (pre-configured JointEmbedder, or None for auto)

  • marginal_embedder_x (pre-configured TakensEmbedders)

  • marginal_embedder_y (pre-configured TakensEmbedders)

  • subsample (subsample point clouds before persistence computation)

  • seed (seed for subsampling (same seed used for all three clouds))

  • n_ensemble (int) – Number of independent fits with different subsample seeds. If > 1, binding_score() returns the mean, and ensemble_scores stores individual scores. Default 1 (no ensembling).

Return type:

self

binding_score()[source]

Binding score (higher = more emergent topology).

For persistence_image method: L1 norm of positive residual. For diagram_matching method: optimal matching cost between joint and concatenated marginal persistence diagrams.

If fit() was called with n_ensemble > 1, returns the ensemble mean.

Returns:

float

Return type:

binding score

property ensemble_scores: ndarray | None

Individual scores from ensemble fitting, or None if n_ensemble=1.

confidence_interval(confidence=0.95)[source]

Bootstrap percentile confidence interval from ensemble scores.

Parameters:

confidence (float) – Confidence level (default 0.95 for 95% CI).

Return type:

(lower, upper) tuple, or None if no ensemble was run.

binding_features()[source]

Per-dimension breakdown of excess topology.

For persistence_image: {dim: {n_excess, total_persistence, max_persistence}} For diagram_matching: {dim: {score, n_joint, n_baseline, n_unmatched}}

Returns:

dict

Return type:

per-dimension feature dictionary

binding_image()[source]

Residual persistence images (joint - baseline).

Only available for the persistence_image method.

Return type:

list of (resolution, resolution) arrays, one per homology dimension

Raises:

RuntimeError – If called with the diagram_matching method.

embedding_quality()[source]

Embedding quality metrics for all three clouds.

Returns:

dict with keys

Return type:

marginal_x, marginal_y, joint, any_degenerate

test_significance(n_surrogates=100, method='phase_randomize', seed=None, subsample=None)[source]

Test significance of binding score against surrogate null distribution.

Generates surrogates of Y, recomputes binding score for each, and computes a p-value. Reuses the cached marginal X persistence result across all surrogates for efficiency.

Parameters:
  • n_surrogates (number of surrogate iterations)

  • method ("phase_randomize", "time_shuffle", or "twin_surrogate")

  • seed (seed for surrogate generation)

  • subsample (subsample for persistence (passed through))

Returns:

  • dict with p_value, observed_score, surrogate_scores, significant,

  • embedding_quality

Return type:

dict

plot_comparison()[source]

3-panel comparison: marginal X | joint (excess) | marginal Y.

plot_binding_image()[source]

Heatmap of residual persistence images.

class att.binding.BindingDetector(max_dim=1, method='persistence_image', image_resolution=50, image_sigma=0.1, baseline='max', embedding_quality_gate=True)[source]

Bases: object

Detect topological binding between coupled dynamical systems.

Computes persistence images for joint and marginal embeddings, then measures excess topology in the joint that is absent from both marginals.

Parameters:
  • max_dim (int) – Maximum homology dimension (0=components, 1=loops).

  • method (str) – “persistence_image” (PI subtraction) or “diagram_matching” (optimal matching via Hungarian algorithm).

  • image_resolution (int) – Resolution of persistence images.

  • image_sigma (float) – Gaussian kernel bandwidth for persistence images.

  • baseline (str) – “max” (conservative, pointwise max of marginals) or “sum” (sensitive, pointwise sum of marginals).

  • embedding_quality_gate (bool) – If True, validate all three embeddings and warn if any is degenerate.

__init__(max_dim=1, method='persistence_image', image_resolution=50, image_sigma=0.1, baseline='max', embedding_quality_gate=True)[source]
Parameters:
  • max_dim (int)

  • method (str)

  • image_resolution (int)

  • image_sigma (float)

  • baseline (str)

  • embedding_quality_gate (bool)

fit(X, Y, joint_embedder=None, marginal_embedder_x=None, marginal_embedder_y=None, subsample=None, seed=None, n_ensemble=1)[source]

Fit the detector on two coupled time series.

Parameters:
  • X (1D time series arrays)

  • Y (1D time series arrays)

  • joint_embedder (pre-configured JointEmbedder, or None for auto)

  • marginal_embedder_x (pre-configured TakensEmbedders)

  • marginal_embedder_y (pre-configured TakensEmbedders)

  • subsample (subsample point clouds before persistence computation)

  • seed (seed for subsampling (same seed used for all three clouds))

  • n_ensemble (int) – Number of independent fits with different subsample seeds. If > 1, binding_score() returns the mean, and ensemble_scores stores individual scores. Default 1 (no ensembling).

Return type:

self

binding_score()[source]

Binding score (higher = more emergent topology).

For persistence_image method: L1 norm of positive residual. For diagram_matching method: optimal matching cost between joint and concatenated marginal persistence diagrams.

If fit() was called with n_ensemble > 1, returns the ensemble mean.

Returns:

float

Return type:

binding score

property ensemble_scores: ndarray | None

Individual scores from ensemble fitting, or None if n_ensemble=1.

confidence_interval(confidence=0.95)[source]

Bootstrap percentile confidence interval from ensemble scores.

Parameters:

confidence (float) – Confidence level (default 0.95 for 95% CI).

Return type:

(lower, upper) tuple, or None if no ensemble was run.

binding_features()[source]

Per-dimension breakdown of excess topology.

For persistence_image: {dim: {n_excess, total_persistence, max_persistence}} For diagram_matching: {dim: {score, n_joint, n_baseline, n_unmatched}}

Returns:

dict

Return type:

per-dimension feature dictionary

binding_image()[source]

Residual persistence images (joint - baseline).

Only available for the persistence_image method.

Return type:

list of (resolution, resolution) arrays, one per homology dimension

Raises:

RuntimeError – If called with the diagram_matching method.

embedding_quality()[source]

Embedding quality metrics for all three clouds.

Returns:

dict with keys

Return type:

marginal_x, marginal_y, joint, any_degenerate

test_significance(n_surrogates=100, method='phase_randomize', seed=None, subsample=None)[source]

Test significance of binding score against surrogate null distribution.

Generates surrogates of Y, recomputes binding score for each, and computes a p-value. Reuses the cached marginal X persistence result across all surrogates for efficiency.

Parameters:
  • n_surrogates (number of surrogate iterations)

  • method ("phase_randomize", "time_shuffle", or "twin_surrogate")

  • seed (seed for surrogate generation)

  • subsample (subsample for persistence (passed through))

Returns:

  • dict with p_value, observed_score, surrogate_scores, significant,

  • embedding_quality

Return type:

dict

plot_comparison()[source]

3-panel comparison: marginal X | joint (excess) | marginal Y.

plot_binding_image()[source]

Heatmap of residual persistence images.