Skip to content

Commit

Permalink
Yay generics!
Browse files Browse the repository at this point in the history
  • Loading branch information
flyingmutant committed Dec 30, 2022
1 parent c71c411 commit 0394ac8
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 24 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
name: CI
strategy:
matrix:
go: ['1.15', '1.16']
go: ['1.18', '1.19']
os: ['ubuntu-latest', 'windows-latest', 'macOS-latest']
runs-on: ${{ matrix.os }}
steps:
Expand Down
30 changes: 15 additions & 15 deletions edpelt.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,15 @@ import (
//
// The implementation is based on the following papers:
//
// [Haynes2017] Kaylea Haynes, Paul Fearnhead, and Idris A. Eckley.
// "A computationally efficient nonparametric approach for changepoint detection."
// Statistics and Computing 27, no. 5 (2017): 1293-1305.
// https://doi.org/10.1007/s11222-016-9687-5
// [Haynes2017] Kaylea Haynes, Paul Fearnhead, and Idris A. Eckley.
// "A computationally efficient nonparametric approach for changepoint detection."
// Statistics and Computing 27, no. 5 (2017): 1293-1305.
// https://doi.org/10.1007/s11222-016-9687-5
//
// [Killick2012] Rebecca Killick, Paul Fearnhead, and Idris A. Eckley.
// "Optimal detection of changepoints with a linear computational cost."
// Journal of the American Statistical Association 107, no. 500 (2012): 1590-1598.
// https://arxiv.org/pdf/1101.1438.pdf
// [Killick2012] Rebecca Killick, Paul Fearnhead, and Idris A. Eckley.
// "Optimal detection of changepoints with a linear computational cost."
// Journal of the American Statistical Association 107, no. 500 (2012): 1590-1598.
// https://arxiv.org/pdf/1101.1438.pdf
func NonParametric(data []float64, minSegment int) []int {
if minSegment < 1 {
panic("minSegment must be positive")
Expand Down Expand Up @@ -66,18 +66,18 @@ func NonParametric(data []float64, minSegment int) []int {

// Partial sums for empirical CDF (formula (2.1) from Section 2.1 "Model" in [Haynes2017])
//
// partialSums'[i, tau] = (count(data[j] < t) * 2 + count(data[j] == t) * 1) for j=0..tau-1
// where t is the i-th quantile value (see Section 3.1 "Discrete approximation" in [Haynes2017] for details)
// partialSums'[i, tau] = (count(data[j] < t) * 2 + count(data[j] == t) * 1) for j=0..tau-1
// where t is the i-th quantile value (see Section 3.1 "Discrete approximation" in [Haynes2017] for details)
//
// In order to get better performance, we present
// a two-dimensional array partialSums'[k, n + 1] as a single-dimensional array partialSums[k * (n + 1)].
// We assume that partialSums'[i, tau] = partialSums[i * (n + 1) + tau].
//
// - We use doubled sum values in order to use []int instead of []float64 (it provides noticeable
// performance boost). Thus, multipliers for count(data[j] < t) and count(data[j] == t) are
// 2 and 1 instead of 1 and 0.5 from the [Haynes2017].
// - Note that these quantiles are not uniformly distributed: tails of the data distribution contain more
// quantile values than the center of the distribution
// - We use doubled sum values in order to use []int instead of []float64 (it provides noticeable
// performance boost). Thus, multipliers for count(data[j] < t) and count(data[j] == t) are
// 2 and 1 instead of 1 and 0.5 from the [Haynes2017].
// - Note that these quantiles are not uniformly distributed: tails of the data distribution contain more
// quantile values than the center of the distribution
func edPartialSums(data []float64, k int) []int32 {
n := len(data)
partialSums := make([]int32, k*(n+1))
Expand Down
4 changes: 2 additions & 2 deletions edpelt_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,8 @@ func BenchmarkNonParametric(b *testing.B) {
func TestNonParametric_ValidDistinctSortedIndexes(t *testing.T) {
rapid.Check(t, func(t *rapid.T) {
var (
data = rapid.SliceOf(rapid.Float64()).Draw(t, "data").([]float64)
minSegment = rapid.IntMin(1).Draw(t, "minSegment").(int)
data = rapid.SliceOf(rapid.Float64()).Draw(t, "data")
minSegment = rapid.IntMin(1).Draw(t, "minSegment")
)

changes := changepoint.NonParametric(data, minSegment)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module pgregory.net/changepoint

go 1.14
go 1.18

require pgregory.net/rapid v0.4.5
require pgregory.net/rapid v0.5.3
6 changes: 2 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
pgregory.net/rapid v0.4.0 h1:/boyXNQlDs1pmk7g1b9u2KrYqXnqjj0ARUDsZj5kapg=
pgregory.net/rapid v0.4.0/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
pgregory.net/rapid v0.4.5 h1:Dej3+7kpi3p5/9dMouKspRs+K8EALKePW4/UYXKq8/4=
pgregory.net/rapid v0.4.5/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU=
pgregory.net/rapid v0.5.3 h1:163N50IHFqr1phZens4FQOdPgfJscR7a562mjQqeo4M=
pgregory.net/rapid v0.5.3/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=

0 comments on commit 0394ac8

Please sign in to comment.