tests/testthat/test-doubles.R

options("cppdoubles.tolerance" = sqrt(.Machine$double.eps))

testthat::test_that("Integers", {
  set.seed(1000)
  x <- sample((-10^2):(10^2), size = 10^3, replace = TRUE)
  y <- sample((-10^2):(10^2), size = 10^3, replace = TRUE)
  testthat::expect_equal(double_equal(x, y),
                         x == y)
  testthat::expect_equal(double_gte(x, y),
                         x >= y)
  testthat::expect_equal(double_lte(x, y),
                         x <= y)
  testthat::expect_equal(double_gt(x, y),
                         x > y)
  testthat::expect_equal(double_lt(x, y),
                         x < y)

  testthat::expect_equal(x %~==% y,
                         x == y)
  testthat::expect_equal(x %~>=% y,
                         x >= y)
  testthat::expect_equal(x %~<=% y,
                         x <= y)
  testthat::expect_equal(x %~>% y,
                         x > y)
  testthat::expect_equal(x %~<% y,
                         x < y)
})

testthat::test_that("Differences", {
  testthat::expect_equal(rel_diff(10^-8, 2 * 10^-8),
                         rel_diff(2 * 10^-8, 10^-8))

  testthat::expect_equal(abs_diff(10^-8, 2 * 10^-8),
                         abs_diff(2 * 10^-8, 10^-8))
})

testthat::test_that("Double floating point precision", {
  set.seed(1849127)

  x <- abs(rnorm(5 * (10^6)))
  y <- sqrt(x)^2
  z <- sample(x)

  testthat::expect_equal(all(double_gt(x, y) == FALSE),
                         TRUE)
  testthat::expect_equal(all(double_gte(x, y) == TRUE),
                         TRUE)
  testthat::expect_equal(all(double_lte(x, y) == TRUE),
                         TRUE)
  testthat::expect_equal(all(double_lt(x, y) == FALSE),
                         TRUE)
  testthat::expect_equal(all(double_equal(x, y) == TRUE),
                         TRUE)

  testthat::expect_equal(all.equal(x >= z, double_gte(x, z)), TRUE)
  testthat::expect_equal(all.equal(x > z, double_gt(x, z)), TRUE)
  testthat::expect_equal(all.equal(x <= z, double_lte(x, z)), TRUE)
  testthat::expect_equal(all.equal(x < z, double_lt(x, z)), TRUE)
  testthat::expect_equal(all.equal(x == z, double_equal(x, z)), TRUE)

  x <- seq(-10, 10, 0.2)
  testthat::expect_true(all(double_gte(x + 0.2, x - 0.2 + sqrt(0.2)^2 + 0.2)))
  testthat::expect_true(all(double_gt(x + 0.2, x - 0.2 + sqrt(0.2)^2 + 0.2)) == FALSE)
  testthat::expect_true(all(double_lt(x + 0.2, x - 0.2 + sqrt(0.2)^2 + 0.2)) == FALSE)
  testthat::expect_true(all(double_lte(x + 0.2, x - 0.2 + sqrt(0.2)^2 + 0.2)))

  testthat::expect_true(all(double_equal(diff(x) - 0.2, 0)))
})

testthat::test_that("more tests", {
  testthat::expect_true(double_equal(10^-8, 2 * 10^-8))
  testthat::expect_true(double_equal(2 * 10^-8, 10^-8))
  testthat::expect_false(double_equal(10^-8, 2 * 10^-8, tol = sqrt(.Machine$double.eps)/100))
  testthat::expect_false(double_equal(2 * 10^-8, 10^-8, tol = sqrt(.Machine$double.eps)/100))
  testthat::expect_true(double_equal(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(double_equal(110 * 10^200, 1.1 * 100 * 10^200))
  testthat::expect_false(double_lt(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_false(double_gt(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(double_lte(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(double_gte(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(double_equal(0, 0))
  testthat::expect_false(double_equal(0, sqrt(.Machine$double.eps)))
  testthat::expect_true(double_equal(0, sqrt(.Machine$double.eps)^2))
  testthat::expect_identical(
    double_equal(c(NaN, NA_real_, NaN, NaN, Inf, Inf, -Inf, -Inf, 0, 0, -3, -3, 2, 2),
                 c(1, 2, NaN, 0, Inf, -Inf, Inf, -Inf, Inf, -Inf, Inf, -Inf, Inf, -Inf)),
    c(NA, NA, NA, NA, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)
  )
  x <- c(NaN, NA_real_, 0, 0.01, -0.001, sqrt(2)^2, -sqrt(2)^2, Inf, -Inf, 10^7, -10^7)
  combs <- expand.grid(x1 = x, x2 = x)
  testthat::expect_identical(double_equal(combs$x1, combs$x2),
                             c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
                               NA, NA, NA, NA, NA, NA, NA, NA, NA, TRUE, FALSE, FALSE, FALSE,
                               FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA, FALSE, TRUE, FALSE,
                               FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA, FALSE, FALSE,
                               TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA, FALSE,
                               FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA,
                               FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
                               NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE,
                               FALSE, NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
                               FALSE, FALSE, NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
                               FALSE, TRUE, FALSE, NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE,
                               FALSE, FALSE, FALSE, TRUE))
  x <- c(NaN, NA_real_, 0, 0.01, -0.001, Inf, -Inf, 10^7, -10^7)
  combs <- expand.grid(x1 = x, x2 = x)
  testthat::expect_identical(double_gt(combs$x1, combs$x2),
                             combs$x1 > combs$x2)
  testthat::expect_identical(double_gte(combs$x1, combs$x2),
                             combs$x1 >= combs$x2)
  testthat::expect_identical(double_lt(combs$x1, combs$x2),
                             combs$x1 < combs$x2)
  testthat::expect_identical(double_lte(combs$x1, combs$x2),
                             combs$x1 <= combs$x2)

  # Abs diff would work here but rel diff doesn't
  testthat::expect_true(double_equal(10^9, 10^9 + 0.002))
  testthat::expect_false(double_equal(0, -0.00001))
  testthat::expect_false(double_equal(0, 0.00001))
  testthat::expect_false(double_equal(0, 10^20))
  testthat::expect_false(double_equal(0, -10^20))
  testthat::expect_false(double_equal(0, -10^20))
  testthat::expect_true(double_equal(10^-9, 2 * 10^-9)) # Default tolerance isnt low enough
  testthat::expect_false(double_equal(10^-9, 2 * 10^-9, tol = sqrt(.Machine$double.eps)/10^4))
})

testthat::test_that("even more tests", {
  testthat::expect_true(`%~==%`(10^-8, 2 * 10^-8))
  testthat::expect_true(`%~==%`(2 * 10^-8, 10^-8))
  options(cppdoubles.tolerance = sqrt(.Machine$double.eps)/100)
  testthat::expect_false(`%~==%`(10^-8, 2 * 10^-8))
  options(cppdoubles.tolerance = sqrt(.Machine$double.eps)/100)
  testthat::expect_false(`%~==%`(2 * 10^-8, 10^-8))
  options(cppdoubles.tolerance = sqrt(.Machine$double.eps))
  testthat::expect_true(`%~==%`(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(`%~==%`(110 * 10^200, 1.1 * 100 * 10^200))
  testthat::expect_false(`%~<%`(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_false(`%~>%`(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(`%~<=%`(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(`%~>=%`(1.1 * 100 * 10^200, 110 * 10^200))
  testthat::expect_true(`%~==%`(0, 0))
  testthat::expect_false(`%~==%`(0, sqrt(.Machine$double.eps)))
  testthat::expect_true(`%~==%`(0, sqrt(.Machine$double.eps)^2))
  testthat::expect_identical(
    `%~==%`(c(NaN, NA_real_, NaN, NaN, Inf, Inf, -Inf, -Inf, 0, 0, -3, -3, 2, 2),
                 c(1, 2, NaN, 0, Inf, -Inf, Inf, -Inf, Inf, -Inf, Inf, -Inf, Inf, -Inf)),
    c(NA, NA, NA, NA, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE)
  )
  x <- c(NaN, NA_real_, 0, 0.01, -0.001, sqrt(2)^2, -sqrt(2)^2, Inf, -Inf, 10^7, -10^7)
  combs <- expand.grid(x1 = x, x2 = x)
  testthat::expect_identical(`%~==%`(combs$x1, combs$x2),
                             c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
                               NA, NA, NA, NA, NA, NA, NA, NA, NA, TRUE, FALSE, FALSE, FALSE,
                               FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA, FALSE, TRUE, FALSE,
                               FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA, FALSE, FALSE,
                               TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA, FALSE,
                               FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, NA, NA,
                               FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE,
                               NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE,
                               FALSE, NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
                               FALSE, FALSE, NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE,
                               FALSE, TRUE, FALSE, NA, NA, FALSE, FALSE, FALSE, FALSE, FALSE,
                               FALSE, FALSE, FALSE, TRUE))
  x <- c(NaN, NA_real_, 0, 0.01, -0.001, Inf, -Inf, 10^7, -10^7)
  combs <- expand.grid(x1 = x, x2 = x)
  testthat::expect_identical(`%~>%`(combs$x1, combs$x2),
                             combs$x1 > combs$x2)
  testthat::expect_identical(`%~>=%`(combs$x1, combs$x2),
                             combs$x1 >= combs$x2)
  testthat::expect_identical(`%~<%`(combs$x1, combs$x2),
                             combs$x1 < combs$x2)
  testthat::expect_identical(`%~<=%`(combs$x1, combs$x2),
                             combs$x1 <= combs$x2)

  # Abs diff would work here but rel diff doesn't
  testthat::expect_true(`%~==%`(10^9, 10^9 + 0.002))
  testthat::expect_false(`%~==%`(0, -0.00001))
  testthat::expect_false(`%~==%`(0, 0.00001))
  testthat::expect_false(`%~==%`(0, 10^20))
  testthat::expect_false(`%~==%`(0, -10^20))
  testthat::expect_false(`%~==%`(0, -10^20))
  testthat::expect_true(`%~==%`(10^-9, 2 * 10^-9)) # Default tolerance isnt low enough
  options(cppdoubles.tolerance = sqrt(.Machine$double.eps)/10^4)
  testthat::expect_false(`%~==%`(10^-9, 2 * 10^-9))
  options(cppdoubles.tolerance = sqrt(.Machine$double.eps))
})

testthat::test_that("vectorisation", {
  set.seed(42)
  x <- as.double(sample(c(Inf, -Inf, NA, -10:10), size = 111, replace = TRUE))
  y <- as.double(sample(0:5, size = 10^4, replace = TRUE))
  tol <- as.double(sample(c(0, 0.000001), size = 77, replace = TRUE,
                          prob = c(0.2, 0.8)))

  res_eq <- double_equal(x, y, tol)
  res_gte <- double_gte(x, y, tol)
  res_gt <- double_gt(x, y, tol)
  res_lte <- double_lte(x, y, tol)
  res_lt <- double_lt(x, y, tol)

  zero <- numeric(max(length(x), length(y), length(tol)))
  df <- suppressWarnings(data.frame(x + zero, y + zero, tol + zero))

  df$eq <- abs(df$x - df$y) < df$tol
  df$gt <- (df$x - df$y) > df$tol
  df$gte <- (df$x - df$y) > -df$tol
  df$lte <- (df$x - df$y) < df$tol
  df$lt <- (df$x - df$y) < -df$tol

  df$res_eq <- res_eq
  df$res_gte <- res_gte
  df$res_gt <- res_gt
  df$res_lte <- res_lte
  df$res_lt<- res_lt

  testthat::expect_equal(df$eq, df$res_eq)
  testthat::expect_equal(df$gte, df$res_gte)
  testthat::expect_equal(df$gt, df$res_gt)
  testthat::expect_equal(df$lte, df$res_lte)
  testthat::expect_equal(df$lt, df$res_lt)
})

Try the cppdoubles package in your browser

Any scripts or data that you put into this service are public.

cppdoubles documentation built on June 22, 2024, 7:36 p.m.