Skip to content

Latest commit

 

History

452 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Fast Change Point Detection

Codecov test coverage CodeFactor CRAN status doi R CMD check r-universe Python version Python package

Documentation: x2r.io

Python and standalone C++ sources are published separately in fastcpd-py and fastcpd-cpp.

Installation: R, Python, and C++

R package:

install.packages("fastcpd")

Python package:

python -m pip install fastcpd

C++ library (requires Armadillo and Abseil 20260526 or newer):

git clone https://github.com/doccstat/fastcpd-cpp.git
cmake -S fastcpd-cpp -B fastcpd-cpp/build -DFASTCPD_BUILD_EXAMPLES=OFF
cmake --build fastcpd-cpp/build --parallel
cmake --install fastcpd-cpp/build --prefix fastcpd-install

Comparison

R

set.seed(1)
n <- 10^7
mean_data <- c(rnorm(n / 2, 0, 1), rnorm(n / 2, 50, 1))
print(run_isolated(fastcpd::detect_mean(mean_data, cp_only = TRUE, variance_estimation = 1)))
#>    user  system elapsed 
#>   0.745   0.194   0.981
print(run_isolated(mosum::mosum(c(mean_data), G = 40)))
#>    user  system elapsed 
#>   1.282   0.696   2.236
print(run_isolated(changepoint::cpt.mean(mean_data, method = "PELT")))
#>    user  system elapsed 
#>   3.381   0.665   4.418
print(run_isolated(fpop::Fpop(mean_data, 2 * log(n))))
#>    user  system elapsed 
#>   4.027   0.299   4.483

Python

import numpy as np
import ruptures as rpt
from fastcpd import detect_mean
from sdt.changepoint import Pelt as SdtPelt
from skchange.detectors import PELT
from skchange.interval_scorers import L2Cost

rng = np.random.default_rng(1)
n = 1_000
x = np.r_[rng.normal(0, 1, n // 2), rng.normal(50, 1, n // 2)]


benchmark("fastcpd", lambda: detect_mean(x, variance_estimation=1, cp_only=True))
benchmark("skchange", lambda: PELT(cost=L2Cost(), penalty=2 * np.log(n), min_segment_length=1).fit_predict(x.reshape(-1, 1)))
benchmark("sdt-python", lambda: SdtPelt(cost="l2", min_size=1, jump=1).find_changepoints(x, penalty=2 * np.log(n)))
benchmark("ruptures", lambda: rpt.Pelt(model="l2", min_size=1, jump=1).fit(x).predict(pen=2 * np.log(n)))

C++

Native fastcpd and fpop on Linux ARM64, with 1,000,000 observations. Source and build instructions.

References

About

Fast Change Point Detection (C++ Mirror)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages