Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
rust:
name: Rust ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: Swatinem/rust-cache@v2
- name: cargo fmt
run: cargo fmt --all -- --check
- name: cargo clippy
run: cargo clippy -p cssd-core --all-targets -- -D warnings
- name: cargo test
run: cargo test -p cssd-core --release

python:
name: Python ${{ matrix.python-version }} ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.9", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
- name: create and activate venv
shell: bash
run: |
python -m venv .venv
if [ -d .venv/Scripts ]; then
echo "$GITHUB_WORKSPACE/.venv/Scripts" >> "$GITHUB_PATH"
else
echo "$GITHUB_WORKSPACE/.venv/bin" >> "$GITHUB_PATH"
fi
echo "VIRTUAL_ENV=$GITHUB_WORKSPACE/.venv" >> "$GITHUB_ENV"
- name: install build deps
run: pip install maturin pytest numpy scipy matplotlib
- name: maturin develop
run: maturin develop --release
- name: pytest
run: pytest tests_py -v
- name: smoke demos
run: |
python demos_py/ex_synthetic.py --smoke
python demos_py/ex_heavi_sine.py --smoke
python demos_py/ex_vector_valued.py --smoke
python demos_py/ex_geyser_cv.py --smoke
python demos_py/ex_cputime.py --smoke
95 changes: 95 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Release

on:
push:
tags:
- "v*"
workflow_dispatch:

permissions:
contents: read
id-token: write # for trusted publishing to PyPI

jobs:
linux:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: [x86_64, aarch64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist --zig
manylinux: auto
- uses: actions/upload-artifact@v4
with:
name: wheels-linux-${{ matrix.target }}
path: dist

macos:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
target: [x86_64, aarch64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist
- uses: actions/upload-artifact@v4
with:
name: wheels-macos-${{ matrix.target }}
path: dist

windows:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
target: [x64]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- uses: PyO3/maturin-action@v1
with:
target: ${{ matrix.target }}
args: --release --out dist
- uses: actions/upload-artifact@v4
with:
name: wheels-windows-${{ matrix.target }}
path: dist

sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- uses: actions/upload-artifact@v4
with:
name: wheels-sdist
path: dist

publish:
name: Publish to PyPI
runs-on: ubuntu-latest
needs: [linux, macos, windows, sdist]
if: startsWith(github.ref, 'refs/tags/v')
steps:
- uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- uses: pypa/gh-action-pypi-publish@release/v1
30 changes: 27 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@

demos/__pycache__/ruptures_cssd.cpython-39.pyc
.DS_Store
.DS_Store

# Python build artifacts
__pycache__/
*.pyc
*.pyo
*.so
*.dylib
*.pyd
*.egg-info/
build/
dist/
wheels/
.pytest_cache/

# maturin / PyO3 build outputs (keep `python/cssd/*.py`, exclude binaries)
python/cssd/_cssd_core*

# Rust build outputs
/target/
Cargo.lock.bak

# Internal / historical docs not shipped to PyPI
PORTING_NOTES.md
PAPER_COMPLIANCE.md

# Devcontainer
.devcontainer/
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Changelog

All notable changes to `cssd` are documented here. This project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html) and the
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) layout.

## [Unreleased]

## [1.0.1] - 2026-05-07

First PyPI release. Continues the version line of the MATLAB reference
implementation (last MATLAB tag: `v1.0.0`); the Rust core and Python
bindings introduced here ship under the next patch version so MATLAB
and Python consumers see a single coherent release history.

### Added
- Rust core (`cssd-core`) implementing cubic smoothing splines with
discontinuities (CSSD) per Storath & Weinmann, *Smoothing splines for
discontinuous signals*, JCGS 2024.
- Python package (`cssd`) with PyO3 bindings via `cssd-py`. Exposes
`cssd(x, y, p, gamma, …)` and `cssd_cvscore(...)` with FPVI / PELT
pruning and optional local preconditioning.
- 211 Python unit tests, 6 Rust integration tests, MATLAB-parity tests
driven by 594 pre-baked `.mat` fixtures, paper-compliance tests
validating equations from the JCGS 2024 paper.
- CITATION.cff with Storath & Weinmann ORCIDs and the JCGS 2024
reference.

### Security
- Built against `pyo3 >= 0.24.1` (closes GHSA-pph8-gcv7-4qj5,
`PyString::from_object` buffer-overread).
40 changes: 40 additions & 0 deletions CITATION.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
cff-version: 1.2.0
message: "If you use this software, please cite both the software and the associated paper below."
title: "CSSD: Cubic smoothing splines for discontinuous signals"
version: 1.0.1
date-released: 2026-05-07
abstract: "Reference implementation (MATLAB and Rust/Python port) of cubic smoothing splines for signals with a priori unknown discontinuities. Solves a piecewise smoothing-spline model in which both the spline coefficients and the discontinuity set are estimated jointly via dynamic programming."
type: software
url: "https://github.com/mstorath/CSSD"
repository-code: "https://github.com/mstorath/CSSD"
license: MIT
authors:
- family-names: Storath
given-names: Martin
email: martin.storath@thws.de
orcid: "https://orcid.org/0000-0003-1427-0776"
affiliation: "Lab for Mathematical Methods in Computer Vision and Machine Learning, Technische Hochschule Würzburg-Schweinfurt"
- family-names: Weinmann
given-names: Andreas
email: andreas.weinmann@thws.de
orcid: "https://orcid.org/0000-0002-4969-7609"
affiliation: "Department of Mathematics and Natural Sciences, Hochschule Darmstadt"
preferred-citation:
type: article
title: "Smoothing splines for discontinuous signals"
authors:
- family-names: Storath
given-names: Martin
orcid: "https://orcid.org/0000-0003-1427-0776"
- family-names: Weinmann
given-names: Andreas
orcid: "https://orcid.org/0000-0002-4969-7609"
journal: "Journal of Computational and Graphical Statistics"
volume: 33
issue: 2
start: 651
end: 665
year: 2024
publisher:
name: "Taylor & Francis"
doi: "10.1080/10618600.2023.2262000"
Loading
Loading