gspx 0.1.0

Sparse graph signal processing and spectral graph wavelets in Rust
Documentation

gspx

gspx is a Rust crate for sparse graph signal processing: exact spectral filtering, dynamic topology updates, Chebyshev approximations, and spectral graph modal analysis (SGMA).

It was designed around large sparse networks such as power systems, but the API works with any graph Laplacian.

License: GPL-3.0-only
MSRV: Rust 1.85

Install

[dependencies]
gspx = "0.1"

Start Here

gspx does not depend on packaged sample data. Most users start from one of these three inputs:

  1. An in-memory Laplacian you already have.
  2. A local .mat Laplacian file.
  3. A local .ply mesh file.

If your Laplacian is already in memory, the exact filtering path looks like this:

use gspx::{StaticConvolver, impulse};
use sprs::TriMat;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut triplets = TriMat::<f64>::new((3, 3));
    triplets.add_triplet(0, 0, 1.0);
    triplets.add_triplet(0, 1, -1.0);
    triplets.add_triplet(1, 0, -1.0);
    triplets.add_triplet(1, 1, 2.0);
    triplets.add_triplet(1, 2, -1.0);
    triplets.add_triplet(2, 1, -1.0);
    triplets.add_triplet(2, 2, 1.0);

    let laplacian = triplets.to_csc();
    let signal = impulse(&laplacian, 0, 1)?;
    let scales = [0.25, 1.0, 4.0];

    let mut convolver = StaticConvolver::new(laplacian)?;
    let filtered = convolver.bandpass(signal.view(), &scales, 2)?;

    println!("computed {} scales", filtered.len());
    Ok(())
}

If you want to read local files directly, use the file loaders:

use gspx::{load_laplacian, load_ply_laplacian, load_ply_xyz};
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let delay_texas = load_laplacian(Path::new("resources/library/DELAY/TEXAS.mat"))?;
    let bunny_mesh = load_ply_laplacian(Path::new("resources/library/MESH/BUNNY.ply"))?;
    let bunny_xyz = load_ply_xyz(Path::new("resources/library/MESH/BUNNY.ply"))?;

    println!("Texas vertices: {}", delay_texas.rows());
    println!("Bunny vertices: {}", bunny_mesh.rows());
    println!("Bunny coordinate shape: {:?}", bunny_xyz.raw_dim());
    Ok(())
}

Example Data

The larger Laplacians and meshes used by the examples live in this repository under resources/library, but they are not packaged into the published crate.

Use ExampleData::from_dir(...) when you want the named example datasets from that local directory structure:

use gspx::{Dataset, ExampleData, GraphKind};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let data = ExampleData::from_dir("resources/library")?;
    let texas = data.graph(Dataset::Texas, GraphKind::Delay)?;
    let coords = data.coords(Dataset::Texas)?;

    println!("Texas vertices: {}", texas.rows());
    println!("Texas coordinate shape: {:?}", coords.raw_dim());
    Ok(())
}

Example Dataset Catalog

Dataset Graph kinds Coordinates Source
East Delay no local resources/library
EastWest Delay, Impedance, Length yes local resources/library
Hawaii Delay, Impedance, Length yes local resources/library
Neiso Delay, Length no local resources/library
Texas Delay, Impedance, Length yes local resources/library
Usa Delay, Impedance, Length yes local resources/library
Wecc Delay, Impedance, Length no local resources/library
Bunny Mesh yes local resources/library
Horse Mesh yes local resources/library
Lbrain Mesh yes local resources/library
Rbrain Mesh yes local resources/library

Main Workflows

Exact Filters

StaticConvolver and DynamicConvolver expose the analytical filter family:

  • lowpass(...)
  • bandpass(...)
  • highpass(...)

Use StaticConvolver when the graph is fixed. Use DynamicConvolver when you need online branch updates with add_branch(i, j, weight) and want to reuse precomputed pole state.

Custom Kernels

VfModel fits rational kernels from sampled spectral responses, then StaticConvolver or DynamicConvolver applies the resulting VfKernel.

For polynomial approximations, use ChebyModel and ChebyConvolver.

SGMA

Sgma handles the spatial-temporal analysis path:

  • spectrum(...) and spectrum_complex(...)
  • find_peaks(...)
  • find_modes(...)
  • analyze_many(...)

Signal Shape Conventions

Filtering APIs accept either:

  • 1D signals: (n_vertices,)
  • 2D signal matrices: (n_vertices, n_signals)

For SGMA, the signal matrix is (n_vertices, n_times) and the time vector length must match n_times.

Helpers:

  • impulse(&laplacian, vertex_index, n_channels)
  • impulse_1d(&laplacian, vertex_index)
  • estimate_spectral_bound(&laplacian)

Examples

Cargo examples live in examples/.

Group Examples
Basics basic_static_filters, basic_dynamic_topology, basic_chebyshev, basic_vf_fit, basic_sgma, basic_resource, basic_local_files
Plotting plot_path_filters, plot_sgma_heatmap, plot_sgma_modes, plot_geo_filters, plot_mesh_bunny_filters, plot_mesh_bunny_scales
Reporting benchmark_report

Common starting points:

cargo run --example basic_static_filters
cargo run --example basic_dynamic_topology
cargo run --example basic_chebyshev
cargo run --example basic_vf_fit
cargo run --example basic_sgma
cargo run --example basic_resource
cargo run --example basic_local_files
  • basic_resource shows loading a named dataset from a local resources/library directory.
  • basic_local_files shows direct MAT and PLY loading from local file paths.

Benchmark workflow:

cargo bench --bench perf_core
cargo run --example benchmark_report

Platform Notes

  • gspx targets Linux and Windows for the 0.1 release.
  • Sparse shifted solves use SuiteSparse-backed LDL factorization through sprs-ldl.
  • The packaged crate includes source, tests, examples, and docs only; example data stays in the repo.

Citation

If you use gspx for research, cite the associated HICSS paper.

@inproceedings{lowery-sgwt-2026,
  title={Using Spectral Graph Wavelets to Analyze Large Power System Oscillation Modes},
  author={Lowery, Luke and Baek, Jongoh and Birchfield, Adam},
  year={2026}
}

The same citation metadata is also available in CITATION.cff.

Links

gspx was first prototyped in the Python sgwt project; that repository is still the main background reference for the datasets and research context.