Skip to content

cemsbv/pelt

Repository files navigation

Crates.io pypi MPL-2.0 docs.rs ci

Changepoint detection with Pruned Exact Linear Time.

Usage

Python

from pelt import predict

predict(signal, penalty=20, segment_cost_function="l1", jump=10, minimum_segment_length=2)

Rust

use std::num::NonZero;
use pelt::{Pelt, SegmentCostFunction};

// Setup the structure for calculating changepoints
let pelt = Pelt::new()
  .with_jump(NonZero::new(5).expect("Invalid number"))
  .with_minimum_segment_length(NonZero::new(2).expect("Invalid number"))
  .with_segment_cost_function(SegmentCostFunction::L1);

// Do the calculation on a data set
let penalty = 10.0;
let result = pelt.predict(&signal[..], penalty)?;

Run locally

# Install maturin inside a Python environment
python3 -m venv .env
source .env/bin/activate
pip install maturin numpy

# Create a Python package from the Rust code
maturin develop

# Open an interpreter
python

>>> from pelt import predict
>>> import numpy as np
>>> signal = np.array([np.sin(np.arange(0, 1000, 10))]).transpose()
>>> predict(signal, penalty=20)

Benchmarks

Warning

Like all benchmarks, take these with a grain of salt.

Python

Comparison with ruptures:

Cost Function Data Points Data Dimension Mean pelt Mean ruptures Times Faster
L2 100 1D 2.042 μs 3.110 ms 1523.1x
L2 100 2D 2.420 μs 3.148 ms 1300.9x
L2 1000 1D 106.783 μs 190.108 ms 1780.3x
L2 1000 2D 55.815 μs 104.357 ms 1869.7x
L2 10000 1D 20.407 ms 12.859 s 630.2x
L2 10000 2D 2.317 ms 1.797 s 775.6x
L1 100 1D 11.245 μs 5.041 ms 448.3x
L1 100 2D 21.587 μs 5.350 ms 247.8x
L1 1000 1D 321.619 μs 187.656 ms 583.5x
L1 1000 2D 2.186 ms 628.126 ms 287.3x
L1 10000 1D 13.215 ms 15.615 s 1181.6x
L1 10000 2D 84.453 ms 30.508 s 361.2x
Command
maturin develop
python benches/bench_compare.py

Profile

Command
cargo build --example simple --profile profiling \
 && samply record target/profiling/examples/simple tests/signals-large.csv

Credits