Skip to main content

Vinnicombe nu-gap metric and a pipeline for comparing time-course data across two conditions

Project description

nugap

Detect condition-specific changes in dynamics using the Vinnicombe ν-gap metric.

PyPI License: MIT Open In Colab

nugap is a lightweight Python implementation of the Vinnicombe ν-gap — a bounded (0–1) distance between linear dynamical systems from robust control theory — together with the model identification and statistics needed to ask a practical question of two-condition time-course data:

Which variables, or which relationships between them, change their dynamical behaviour between conditions?

(for example wild type vs mutant, or untreated vs treated). Comparisons of expression level answer a different question and are blind to changes in timescale, gain or phase. The ν-gap is defined directly on dynamical models, so it is not: two systems close in ν-gap behave the same way under feedback, and a large ν-gap marks a genuine change in dynamics.

Installation

pip install nugap

Requires Python ≥ 3.10. The core and pipelines depend only on NumPy, SciPy and pandas; the plotting helpers additionally use Matplotlib and NetworkX.

Tutorial

A guided, runnable tutorial covers the metric, model fitting, and the two-condition network comparison end to end:

Quick start

The ν-gap between two systems (coefficients in descending powers of s):

from nugap import tf, nu_gap

P1 = tf([1], [1, 1])     # 1/(s+1)
P2 = tf([1], [1, 3])     # 1/(s+3)
nu_gap(P1, P2)           # -> 0.447   (0 = identical, 1 = maximally different)

Comparing a whole interaction network between two conditions, with replicate-based significance:

from nugap import compare_network

# data_A, data_B: dict {variable_name: array of shape (replicates, timepoints)}
# t: the common time vector
edges = compare_network(data_A, data_B, t, order=1, min_r2=0.5)

edges.query("q_global < 0.1")   # relationships rewired between conditions (FDR < 10%)

What it provides

  • nu_gap — the Vinnicombe ν-gap for SISO systems in continuous or discrete time, with an optional frequency-band restriction (band=) and a switchable winding-number test (check_winding=) for oscillatory data.
  • Model identificationfit_first_order, fit_model, fit_arx, fit_prony, with simulation-based fit quality and an optional DC-gain floor (min_dc_gain=); plus the dc_gain helper.
  • compare_conditions — per-variable comparison of dynamics between two conditions, with a fit-quality reliability flag.
  • compare_network — pairwise interaction-network comparison: a low-order model is fitted to every ordered pair of variables in each condition, the ν-gap is taken between conditions, and significance comes from a replicate-derived empirical null with Benjamini–Hochberg FDR control.
  • Plottingnugap.viz (volcano plot, hub network, hub bar plot).

How it works

For each variable or pairwise interaction, nugap fits a low-order linear input–output model under each condition, then measures the ν-gap between the fitted models. Because models are compared on mean-centred trajectories, the metric reflects changes in the relationship — timescale, gain or phase — rather than in absolute level. With biological replicates, the spread of within-condition ν-gaps provides an empirical null and a per-edge noise floor, against which between-condition changes are tested and FDR-controlled.

The models are single-input single-output, so an edge captures a pairwise input–output relationship, not proven causation.

Correctness

The ν-gap implementation is verified by several independent routes — exact closed-form values, an algebraic invariance of the chordal metric, an independent reference implementation, and the Vinnicombe robust-stability theorem — and is cross-checked against MATLAB's gapmetric (Robust Control Toolbox), which it reproduces to within ~10⁻⁶. The scripts are in validation/, with a fast subset run on every commit.

Citing

If you use nugap in your work, please cite the software and the accompanying methods paper:

Hearn, T. J. nugap: condition-specific changes in dynamical relationships via the
Vinnicombe ν-gap. Software archive: Zenodo, DOI: 10.5281/zenodo.XXXXXXX.

<methods paper reference — to be added>

License

Released under the MIT License. Copyright © 2026 Tim Hearn. See LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nugap-0.5.0.tar.gz (26.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nugap-0.5.0-py3-none-any.whl (25.0 kB view details)

Uploaded Python 3

File details

Details for the file nugap-0.5.0.tar.gz.

File metadata

  • Download URL: nugap-0.5.0.tar.gz
  • Upload date:
  • Size: 26.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for nugap-0.5.0.tar.gz
Algorithm Hash digest
SHA256 00bb213a1674d62e598df6db9fa564a1562b125168ac9242b1d902b17862de18
MD5 31603ec934004ce709039f3684500b7f
BLAKE2b-256 b78a5ba70e0f70af9d9aa9116184ad5c7766d38d77c475bef6f09132402ee223

See more details on using hashes here.

File details

Details for the file nugap-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: nugap-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 25.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for nugap-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ded104e06150c53e5c818ab096191d78b21067b4eb34b0878bcc2dfb5f94e5b6
MD5 ec34946066cddfae4334c32d7fa52337
BLAKE2b-256 a94c018fee2200fbc6b890b969cc4178d40a1d280c5631732b07cefb14b7e9e0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page