Skip to main content

🌀 Interfere

PyPI Version License: MIT Documentation

A Python package for modeling and predicting the response of complex dynamic systems to interventions.

Overview

Interfere is a research-oriented Python package that addresses a fundamental question in complex systems: When can we predict how complex systems will respond to interventions? This package provides tools for:

  • Modeling dynamic nonlinear multivariate stochastic systems.
  • Simulating and analyzing how such systems respond to interventions.
  • Generating complex dynamic counterfactuals.
  • Studying causal relationships in complex systems.

Interfere Benchmark Dataset (Download)

Sixty dynamic systems and intervention responses.

The image above depicts the uninterrupted trajectories of sixty dynamic models in blue and their response to a particular intervention in red. This data is available for download as the Interfere Benchmark 1.1.1. It can be used to benchmark a forecasting method's ability to predict the response of a dynamic system to interventions.

Documentation

Full documentation is built with MkDocs and published at https://djpasseyjr.github.io/interfere/.

Installation

From pip

pip install interfere

From Local Clone

git clone https://github.com/djpasseyjr/interfere.git
cd interfere
pip install .

Quick Start

The Interfere package is designed around three main tasks: counterfactual simulation, predictive method optimization, and prediction. Here's a complete example using the SINDy (Sparse Identification of Nonlinear Dynamics) method:

1. Counterfactual Simulation

First, let's create and simulate a dynamic model:

import numpy as np
import interfere
import optuna

# Set up simulation parameters
initial_cond = np.random.rand(3)
t_train = np.arange(0, 10, 0.05)
dynamics = interfere.dynamics.Belozyorov3DQuad(sigma=0.5)

# Generate trajectory
sim_states = dynamics.simulate(t_train, initial_cond)

Original System Trajectory

2. Applying an Intervention

Next, we'll apply an intervention to one component of the system:

# Time points for the intervention simulation
test_t = np.arange(t_train[-1], 15, 0.05)

# Intervention initialization
intervention = interfere.SignalIntervention(iv_idxs=1, signals=np.sin)

# Simulate intervention
interv_states = dynamics.simulate(
    test_t,
    prior_states=sim_states,
    intervention=intervention,
)

System Trajectory with Intervention

3. Model Optimization and Prediction

Using the generated data, we can run hyperparameter optimization with a forecasting method. All forecasting methods come with reasonable hyperparameter ranges built in.

# Select the SINDy method for hyperparameter optimization.
method_type = interfere.SINDy

# Create an objective function that aims to minimize cross validation error
# over different hyper parameter configurations for SINDy
cv_obj = interfere.CrossValObjective(
    method_type=method_type,
    data=sim_states,
    times=t_train,
    train_window_percent=0.3,
    num_folds=5,
    exog_idxs=intervention.iv_idxs,
)

# Run the study using optuna.
study = optuna.create_study()
study.optimize(cv_obj, n_trials=25)

# Collect the best hyperparameters into a dictionary.
best_param_dict = study.best_params

4. Intervention Response Prediction

Using the best parameters found, we can fit the forecasting method to pre-intervention data and then make a prediction about how the system will respond to the intervention.

# Initialize SINDy with the best perfoming parameters.
method = interfere.SINDy(**study.best_params)

# Use an intervention helper function to split the pre-intervention data
# into endogenous and exogenous columns.
Y_endog, Y_exog = intervention.split_exog(sim_states)

# Fit SINDy to the pre-intervention data.
method.fit(t_train, Y_endog, Y_exog)

# Use the inherited interfere.ForecastMethod.simulate() method
# To simulate intervention response using SINDy
pred_traj = method.simulate(
    test_t, prior_states=sim_states, intervention=intervention
)

Predicted vs Actual Intervention Response

The SINDy method identifies the underlying dynamics of the system using sparse regression techniques, making it particularly effective for discovering interpretable mathematical models of complex systems.

Dependencies

  1. Basic: pip install interfere
  2. Full forecasting methods: pip install "interfere[methods]"
  3. Developer / experimental features: pip install "interfere[dev]"

Example Use

The package can be used to simulate and analyze how systems respond to interventions. For example, it can model the effect of stochasticity on intervention response forecasting:

Stochastic vs Deterministic Systems

Documentation

For a more detailed explanation of the purpose of the package refer to paper.pdf.

Contributing

Contributions are welcome! To contribute code, make your own local fork of the repository.

Then install the full developer deps using pip install ".[dev]". (The full dependencies are pretty big. Use a virtual environment, so you can delete it when you are done.)

After you write code, auto-format it with black at the top level of the repo:

$ black interfere

Then you can run the linter and fix any linter errors (also at the top level):

$ flake8 interfere

Build docs

Docs use MkDocs (mkdocs.yml). From the repo root:

$ mkdocs serve   # preview at http://127.0.0.1:8000
$ mkdocs build   # output in site/

Add Tests

If you are adding a dynamic model or forecasting method, the test suite has a series of prebuilt tests.

Dynamic Model Tests

Add a factory function in tests/sample_models.py, then import it and append your model instance to the MODELS list in tests/test_dynamics.py:

# In sample_models.py
def my_model() -> interfere.dynamics.MyDynamics:
    return interfere.dynamics.MyDynamics(...)

# In test_dynamics.py: add to imports, then
MODELS = [
    ...
    my_model()
]

Run tests for a specific model by index:

pytest tests -k "model7"

(The above will only run tests for the 8th model in the MODELS list.)

Forecasting Method Tests

Add your method class to the METHODS list in tests/test_methods.py:

# In test_methods.py
METHODS = [
    ...
    interfere.methods.YourMethod,
]

Run tests for a specific method by name:

pytest tests -k "YourMethod"

Optional dependencies (GitHub forks)

Some features need maintainer forks that are not on PyPI (they cannot be declared in PyPI package metadata). Install them for local development and before running the full test suite.

SURD (surd) — SURD_SINDy

  • Module: interfere/_methods/restricted_sindy.py (exported via interfere.methods)
  • Uses surd.surd_parallel to restrict SINDy terms by information decomposition
  • Also needs Tigramite: pip install interfere[methods]
pip install git+https://github.com/djpasseyjr/surd.git

pyclustering fork — oscillatory neural dynamics

  • Module: interfere/dynamics/pyclustering_models.py (not imported by default)
  • Models: HodgkinHuxleyPyclustering, LEGIONPyclustering, StuartLandauKuramoto
pip install pyclustering@git+https://github.com/djpasseyjr/pyclustering

Running Full Tests

The full test suite takes over an hour. When contributing, just make sure you add tests for new code. The full suite will run as part of the automated checks with your pull request.

If you like, you can install the full set of dependencies and run tests locally like this:

git clone https://github.com/djpasseyjr/interfere.git
cd interfere
pip install pyclustering@git+https://github.com/djpasseyjr/pyclustering
pip install git+https://github.com/djpasseyjr/surd.git
pip install ".[dev]"
python -m pytest -v tests

(The full dependencies are pretty big. Use a virtual environment.)

Building the docs

Install dev dependencies (which include mkdocs), then build and serve the site locally:

pip install ".[dev]"
mkdocs serve

Open http://127.0.0.1:8000 to view the docs. To build static files only: mkdocs build.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contact

  • Author: DJ Passey (djpassey@unc.edu)
  • Institution: University of North Carolina at Chapel Hill

Metadata

Release files for interfere 1.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for interfere 1.0.2
File Size Uploaded Provenance Actions
interfere-1.0.2.tar.gz 7.7 MB Without provenance Details for interfere-1.0.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for interfere 1.0.2
File Interpreter ABI Platform Actions
interfere-1.0.2-py3-none-any.whl Python 3 none any Details for interfere-1.0.2-py3-none-any.whl

Total release size: 15.4 MB

Release files / interfere-1.0.2.tar.gz

Download URL interfere-1.0.2.tar.gz
Size 7.7 MB
Tags Source
SHA-256 checksum
How to use checksums
1aeac3612accab8ce355559fc8a1a39cdedf56a4f7979384843dab8620f87b2d
BLAKE2b-256 checksum
How to use checksums
fb53ce47f6b0cba155588d104f526616509b7c8360babeaefac6ea3efc1957c2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / interfere-1.0.2-py3-none-any.whl

Download URL interfere-1.0.2-py3-none-any.whl
Size 7.7 MB
Tags Python 3
SHA-256 checksum
How to use checksums
6e4082005f70fc421bdc10f44256b7ac86a9153a3dacfbb0335a1c2ca8aebb63
BLAKE2b-256 checksum
How to use checksums
b30003d06aae450ba00f7cb942c76bf951bde6546733288eb7197b1792c2f2d3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Security for interfere 1.0.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.2 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page