test_that("known corrected-AS217 dip values are reproduced", { expect_equal(as.numeric(fast_dip_stat(1)), 0.5, tolerance = 0) expect_equal( as.numeric(fast_dip_stat(1, min.is.0 = TRUE)), 0, tolerance = 0 ) expect_equal( as.numeric(fast_dip_stat(rep(2, 4))), 1 / 8, tolerance = 0 ) expect_equal( as.numeric(fast_dip_stat(c(1, 1, 2, 2))), 1 / 4, tolerance = 1e-15 ) expect_equal( as.numeric(fast_dip_stat(cumsum(0:3))), 1 / 8, tolerance = 0 ) expect_equal( as.numeric(fast_dip_stat(c(0, 2, 3, 5, 6))), 2 / 15, tolerance = 2e-15 ) }) test_that("sorted and unsorted fast dip paths agree", { set.seed(20260809) x <- c(rnorm(5000), NA_real_, NaN) xs <- sort(x[is.finite(x)]) a <- fast_dip_stat(x) b <- fast_dip_stat(xs, sorted = TRUE) c <- fast_dip_stat(xs, sorted = TRUE, check.sorted = FALSE) expect_equal(a, b, tolerance = 0) expect_equal(a, c, tolerance = 0) expect_equal(attr(a, "n"), 5000) expect_equal(attr(a, "modal.interval"), attr(b, "modal.interval")) }) test_that("fast dip validation errors are explicit", { expect_error(fast_dip_stat(c(2, 1), sorted = TRUE), "sorted") expect_error(fast_dip_stat(character()), "numeric") expect_error(fast_dip_stat(numeric()), "no complete") expect_error(fast_dip_stat(c(NA_real_, NaN)), "no complete") expect_error(fast_dip_stat(1:3, sorted = NA), "TRUE or FALSE") expect_error(fast_dip_stat(1:3, check.sorted = 1), "TRUE or FALSE") }) test_that("fast dip statistics agree with diptest", { skip_if_not_installed("diptest") set.seed(31) for (rep in seq_len(100)) { n <- sample.int(500, 1) x <- if (rep %% 4 == 0) round(rnorm(n), 1) else rnorm(n) expect_equal( as.numeric(fast_dip_stat(x)), as.numeric(diptest::dip(x)), tolerance = 2e-15, info = paste("rep =", rep, "n =", n) ) } })