Skip to main content

GyRAPH

A Python framework for signal processing on directed graphs.

Tests Coverage Documentation License: MIT Python 3.9+


Overview

GyRAPH provides graph shift operators for asymmetric graphs, a complex-valued Graph Fourier Transform built on their (possibly non-orthogonal) eigenbases, a family of filters that operate in the resulting spectral domain, and statistical tooling — surrogates and stationarity tests — for hypothesis testing on directed graph signals.

The library is built on NumPy, SciPy and NetworkX, and is designed to slot into existing analysis pipelines rather than replace them.

📖 Documentation: gyraph.readthedocs.io — tutorials, full API reference, and the papers behind the methods.

Key features

Area What you get
Graph shift operators Adjacency, directed Laplacian, advection–diffusion, and time–vertex (joint temporal/spatial) operators — each with normalization options and an automatic Jordan-block perturbation fallback for non-diagonalizable matrices.
Directed Graph Fourier Transform Forward and inverse GFT over complex eigenbases, conjugate-frequency pairing, and frequency ordering by eigenvalue magnitude.
Filters Spectral, polynomial (and dual-polynomial), Chebyshev, Faber, Hilbert, Tikhonov, and Wiener filters — including approximation schemes that avoid an explicit eigendecomposition.
Surrogates & stationarity Phase-randomized and structure-preserving surrogate generation, PSD estimation, and stationarity tests for null-hypothesis testing on graph signals.
Graph construction Synthetic generators (cycles, directed tori, asymmetric Erdős–Rényi, vortex and laminar-flow fields) and mesh/surface graphs (sphere, cube, bunny, dragon, hyperbolic paraboloid).
Metrics & visualization Dirichlet energy, total variation, Sobolev and directed-variation smoothness measures; publication-styled plotting for graphs, signals, spectra, meshes and dynamics.

Installation

pip install GyRAPH

From source, for development:

git clone https://github.com/miki998/GyRAPH.git && cd GyRAPH && pip install -e .

Requires Python 3.9+. Core dependencies (NumPy, SciPy, NetworkX, scikit-learn, pandas, matplotlib/seaborn/scienceplots, sympy, tqdm) are installed automatically; the mesh and learning-oriented modules additionally pull in PyTorch, torch-geometric, OpenCV and scikit-image.

Quickstart

Building a graph and its Fourier basis

import numpy as np
from gyraph.graphs import Graph, create_directed_torus

# A directed torus: 8 rows x 6 columns, asymmetric by construction
G, pos = create_directed_torus(Nr=8, Nc=6, directed=True)
graph = Graph(G=G, pos=pos)

# Attach a shift operator — this computes the Graph Fourier basis
graph.set_operator("adjacency")            # or "laplacian", "advection_diffusion", ...
op = graph.operator

print(graph)                                # active operator, node and edge counts
print(graph.is_directed(), graph.assymetry_level())
print(op.normality())                       # 0 if the operator is normal, larger otherwise
print(op.V[:5], op.frequencies[:5])         # eigenvalues and graph frequencies

set_operator accepts "adjacency", "laplacian", "advection_diffusion", "time_vertex_laplacian" and "time_vertex_adjacency", and forwards keyword arguments to the operator — e.g. graph.set_operator("laplacian", normalize="symmetric").

Transforming and filtering a signal

from gyraph.filters import SpectralFilter, PolynomialFilter

x = np.random.randn(graph.N)

# Graph Fourier Transform and its inverse
coef = op.GFT(x)
assert np.allclose(op.inverseGFT(coef), x)

# Low-pass in the spectral domain: keep the 10 lowest graph frequencies
kernel = np.zeros(graph.N)
kernel[:10] = 1.0

sfilt = SpectralFilter(graph)
x_low = sfilt.apply(x, kernel)

# Same response, approximated by a degree-K polynomial of the shift operator
# (no eigendecomposition needed at apply time)
pfilt = PolynomialFilter(graph, order=12)
x_low_approx = pfilt.apply(x, kernel)

For directed operators the spectrum is complex. SpectralFilter.transform_in_real enforces conjugate symmetry on a kernel so the filtered signal stays real-valued, and phase_shift generalizes the Hilbert transform to arbitrary phase rotations in the GFT domain.

Surrogates and stationarity testing

from gyraph.surrogates import Surrogate

surr = Surrogate(graph)

# 200 surrogates preserving the directed spectral structure of x
surrogates = surr.directed_random_surrogate(x, nrands=200, seed=99)

# Test whether a set of realizations is stationary w.r.t. the graph
is_stat = surr.is_stationary(surrogates, eps_diag=0.5, eps_mean=0.5, verbose=True)

Measuring signal smoothness

from gyraph.utils import dirichlet, TV, directed_variation

graph.set_operator("laplacian")
print(dirichlet(x, graph.operator.M))        # x^T L x
print(TV(x, graph.adj_matrix, norm="L1"))    # ||x - Ax||_1
print(directed_variation(x, graph.adj_matrix))

Package layout

gyraph/
├── graphs/        Graph container, synthetic generators, mesh & physical-flow graphs
├── operators/     Adjacency, Laplacian, advection–diffusion, time–vertex operators;
│                  Jordan-block and zero-eigenvalue handling
├── filters/       Spectral, polynomial, Chebyshev, Faber, Hilbert, Tikhonov, Wiener
├── surrogates/    Surrogate generation and stationarity/PSD estimation
├── stats/         p-values, circular statistics, complex Gaussian sampling
└── utils/         Numerics, smoothness metrics, plotting, logging configuration

Every subpackage is re-exported at the top level, so import gyraph gives access to gyraph.graphs, gyraph.filters, gyraph.operators, gyraph.surrogates and gyraph.utils. Importing gyraph also applies a publication-oriented matplotlib style (science/ieee) — see gyraph/constants.py if you would rather keep your own rcParams.

Examples and data

Runnable scripts and notebooks live in examples/ — start with examples/basic/ for graph construction, filtering and visualization, then move to examples/advanced/.

The data/ directory ships the graph datasets used throughout the examples and tests:

  • manhattan_graph_data/ — mid-Manhattan road network with NYC taxi flow signals
  • usa_graph_data/ — US state adjacency graph with boundary shapefiles
  • temperature_bretagne_graph_data/ — Brittany weather-station network

Development

pip install -e . && pip install pytest pytest-cov flake8 pre-commit && pre-commit install

Run the test suite (154 unit tests, ~84% line coverage):

python -m unittest discover -s tests/ -p 'test_*.py'

With coverage and linting, as CI does:

coverage run -m unittest discover -s tests/ -p 'test_*.py' && coverage report -m && flake8 . --max-line-length=127

Type checking is configured in mypy.ini. Both workflows — unit tests with a coverage badge, and packaging — run on every push to main (see .github/workflows/).

Contributions are welcome; please read CONTRIBUTING.md for the branch/commit conventions, NumPy-style docstring requirements and review process, and CODE_OF_CONDUCT.md before opening an issue or pull request.

Research powered by GyRAPH

GyRAPH is the reference implementation behind the following publications — the derivations, assumptions and validation for the code live there:

  • Graph Diffusion-Advection Operator for Directed Graph Signal Processing — Chan, Cionca, Škultéty, Van De Ville. arXiv:2606.16306gyraph.operators.AdvectionDiffusion
  • Graph Signal Surrogate Generation for Statistical Testing of Covariance Structure on Directed Graphs — Chan, Cionca, Van De Ville. arXiv:2608.01766gyraph.surrogates
  • Hilbert Transform on Graphs: Let There Be Phase — Chan, Cionca, Van De Ville, IEEE Signal Processing Letters. IEEE Xploregyraph.filters.HilbertFilter

Citation

If you use GyRAPH in academic work, please cite it. Machine-readable metadata is in CITATION.cff:

@software{chan_gyraph,
  author  = {Chan, Chun Hei Michael},
  title   = {{GyRAPH}: Directed Graph Signal Processing Framework},
  url     = {https://github.com/miki998/GyRAPH},
  license = {MIT}
}

Acknowledgment

This project has been partly funded by the Swiss National Science Foundation under Sinergia grant 209470 “Precision mapping of electrical brain network dynamics with application to epilepsy”.

License

Released under the MIT License. Copyright © Chun Hei Michael Chan, MIP:Lab, EPFL.

Download files

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

Source Distribution

gyraph-1.0.1.tar.gz (14.4 MB view details)

Uploaded Source

Built Distribution

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

gyraph-1.0.1-py3-none-any.whl (87.9 kB view details)

Uploaded Python 3

File details

Details for the file gyraph-1.0.1.tar.gz.

File metadata

  • Download URL: gyraph-1.0.1.tar.gz
  • Upload date:
  • Size: 14.4 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.18

File hashes

Hashes for gyraph-1.0.1.tar.gz
Algorithm Hash digest
SHA256 ded787016e83afaa35f0e4824edf209722760d2e331a41a2335bb825c88816b5
MD5 bb40fefcd35d6a4a98e29d2d33579fff
BLAKE2b-256 7ccf69aada551a05ddab55f20fcdc9763903f158ce6bb9102072603f1a232742

See more details on using hashes here.

File details

Details for the file gyraph-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: gyraph-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 87.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.8.18

File hashes

Hashes for gyraph-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b4f77c4648f88593d3b4c0dfac4cc7fa9ad231da927d47116e39d300885631b5
MD5 08c18ab60d39839cd8276e960bfb5071
BLAKE2b-256 105a23b33af2d881b6cf0c3af22050afd47963f1211be92c63cbad6836a973e6

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