Nothing
library(testthat)
Sys.setenv('OMP_THREAD_LIMIT'=2)
library(rlibkriging)
## *************************************************************************
## test-WarpKriging.R — testthat tests for WarpKriging R binding
##
## Mirrors the 16 C++ tests from test_WarpKriging.cpp.
## *************************************************************************
#library(testthat)
#library(rlibkriging)
f1d <- function(x) {
1 - 0.5 * (sin(12 * x) / (1 + x) + 2 * cos(7 * x) * x^5 + 0.7)
}
# ===========================================================================
# Test 1: Kumaraswamy warping (1D continuous)
# ===========================================================================
test_that("Kumaraswamy warping works on 1D function", {
X <- as.matrix(seq(0.01, 0.99, length.out = 8))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "kumaraswamy", kernel = "gauss",
parameters = list(max_iter_adam = "200"))
expect_s3_class(k, "WarpKriging")
cat(summary(k))
p <- predict(k, X, stdev = TRUE)
expect_equal(length(p$mean), 8)
expect_true(all(is.finite(p$mean)))
x_pred <- as.matrix(seq(0.01, 0.99, length.out = 50))
p2 <- predict(k, x_pred, stdev = TRUE)
rmse <- sqrt(mean((p2$mean - f1d(x_pred))^2))
cat(" Kumaraswamy RMSE:", rmse, "\n")
})
# ===========================================================================
# Test 2: Categorical-only (embedding)
# ===========================================================================
test_that("Categorical embedding works", {
mu <- c(1.0, 5.0, 3.0)
set.seed(42)
n <- 15
levels <- rep(0:2, length.out = n)
X <- as.matrix(levels)
y <- mu[levels + 1] + rnorm(n, sd = 0.1)
k <- WarpKriging(y, X, warping = "categorical(3,2)", kernel = "gauss",
parameters = list(max_iter_adam = "200"))
cat(summary(k))
X_test <- as.matrix(0:2)
p <- predict(k, X_test, stdev = TRUE)
for (l in 1:3)
cat(sprintf(" level %d: pred=%.3f, true=%.1f\n",
l - 1, p$mean[l], mu[l]))
expect_true(all(is.finite(p$mean)))
expect_equal(length(p$mean), 3)
})
# ===========================================================================
# Test 3: Mixed continuous + categorical
# ===========================================================================
test_that("Mixed continuous + categorical works", {
offset <- c(1.0, 2.0, 0.5)
set.seed(99)
n <- 30
X <- cbind(runif(n), rep(0:2, length.out = n))
y <- sin(2 * pi * X[, 1]) * offset[X[, 2] + 1]
k <- WarpKriging(y, X,
warping = c("kumaraswamy", "categorical(3,2)"),
kernel = "matern5_2",
parameters = list(max_iter_adam = "300"))
cat(summary(k))
xc <- seq(0.01, 0.99, length.out = 20)
for (cat_idx in 0:2) {
X_test <- cbind(xc, rep(cat_idx, 20))
p <- predict(k, X_test, stdev = TRUE)
ytrue <- sin(2 * pi * xc) * offset[cat_idx + 1]
rmse <- sqrt(mean((p$mean - ytrue)^2))
cat(sprintf(" cat=%d RMSE=%.4f\n", cat_idx, rmse))
expect_true(is.finite(rmse))
}
})
# ===========================================================================
# Test 4: Ordinal variable
# ===========================================================================
test_that("Ordinal warping works", {
L <- 5
set.seed(7)
n <- 20
levels <- rep(0:(L - 1), length.out = n)
X <- as.matrix(levels)
y <- levels^2 + rnorm(n, sd = 0.1)
k <- WarpKriging(y, X, warping = "ordinal(5)", kernel = "gauss",
parameters = list(max_iter_adam = "200"))
cat(summary(k))
X_test <- as.matrix(0:(L - 1))
p <- predict(k, X_test, stdev = TRUE)
for (l in 0:(L - 1))
cat(sprintf(" level %d: pred=%.3f, true=%d\n", l, p$mean[l + 1], l * l))
expect_true(all(is.finite(p$mean)))
expect_equal(length(p$mean), L)
})
# ===========================================================================
# Test 5: NeuralMono warping
# ===========================================================================
test_that("NeuralMono warping works", {
X <- as.matrix(seq(0.01, 0.99, length.out = 10))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "neural_mono(8)", kernel = "gauss",
parameters = list(max_iter_adam = "200"))
cat(summary(k))
p <- predict(k, X, stdev = TRUE)
cat(" Max train error:", max(abs(p$mean - y)), "\n")
expect_true(all(is.finite(p$mean)))
})
# ===========================================================================
# Test 6: MLP warping (1D)
# ===========================================================================
test_that("MLP warping works on 1D function", {
X <- as.matrix(seq(0.01, 0.99, length.out = 10))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "mlp(16:8,3,selu)", kernel = "gauss",
parameters = list(max_iter_adam = "300"))
cat(summary(k))
x_pred <- as.matrix(seq(0.01, 0.99, length.out = 50))
p <- predict(k, x_pred, stdev = TRUE)
rmse <- sqrt(mean((p$mean - f1d(x_pred))^2))
cat(" MLP RMSE:", rmse, "\n")
expect_true(is.finite(rmse))
})
# ===========================================================================
# Test 7: MLP + categorical mixed
# ===========================================================================
test_that("MLP + categorical mixed warping works", {
offset <- c(1.0, 2.0, 0.5)
set.seed(99)
n <- 30
X <- cbind(runif(n), rep(0:2, length.out = n))
y <- sin(2 * pi * X[, 1]) * offset[X[, 2] + 1]
k <- WarpKriging(y, X,
warping = c("mlp(16:8,2,tanh)", "categorical(3,2)"),
kernel = "matern5_2",
parameters = list(max_iter_adam = "300"))
cat(summary(k))
xc <- seq(0.01, 0.99, length.out = 20)
for (cat_idx in 0:2) {
p <- predict(k, cbind(xc, rep(cat_idx, 20)), stdev = TRUE)
ytrue <- sin(2 * pi * xc) * offset[cat_idx + 1]
cat(sprintf(" [MLP+cat] cat=%d RMSE=%.4f\n", cat_idx,
sqrt(mean((p$mean - ytrue)^2))))
expect_true(all(is.finite(p$mean)))
}
})
# ===========================================================================
# Test 8: Conditional simulations (mixed)
# ===========================================================================
test_that("simulate works with mixed variables", {
set.seed(42)
n <- 20
X <- cbind(runif(n), rep(0:1, length.out = n))
y <- sin(2 * pi * X[, 1]) * c(1, 3)[X[, 2] + 1]
k <- WarpKriging(y, X,
warping = c("affine", "categorical(2,2)"),
kernel = "gauss",
parameters = list(max_iter_adam = "200"))
X_sim <- cbind(seq(0.1, 0.9, length.out = 10), rep(0, 10))
sims <- simulate(k, nsim = 30, seed = 123, x = X_sim)
expect_equal(nrow(sims), 10)
expect_equal(ncol(sims), 30)
expect_true(all(is.finite(sims)))
p <- predict(k, X_sim, stdev = TRUE)
rel_diff <- sqrt(sum((rowMeans(sims) - p$mean)^2)) / sqrt(sum(p$mean^2))
cat(" Sim mean vs kriging mean rel diff:", rel_diff, "\n")
})
# ===========================================================================
# Test 9: Update (incremental)
# ===========================================================================
test_that("update works", {
X0 <- matrix(c(0.1, 0.0, 0.5, 1.0, 0.9, 0.0), ncol = 2, byrow = TRUE)
y0 <- c(1.0, 3.0, 0.5)
k <- WarpKriging(y0, X0,
warping = c("none", "categorical(2,1)"),
kernel = "gauss",
parameters = list(max_iter_adam = "100"))
X_new <- matrix(c(0.3, 1.0, 0.7, 0.0), ncol = 2, byrow = TRUE)
update(k, c(2.0, 1.5), X_new)
p <- predict(k, X0, stdev = TRUE)
expect_true(all(is.finite(p$mean)))
})
# ===========================================================================
# Test 10: Branin 2D with per-variable MLP
# ===========================================================================
test_that("Branin 2D with MLP warping works", {
branin <- function(x1, x2) {
a <- 1; b <- 5.1 / (4 * pi^2); cc <- 5 / pi
r <- 6; s <- 10; t <- 1 / (8 * pi)
a * (x2 - b * x1^2 + cc * x1 - r)^2 + s * (1 - t) * cos(x1) + s
}
set.seed(77)
n <- 25
X <- matrix(runif(n * 2), ncol = 2)
y <- mapply(function(i) branin(X[i, 1] * 15 - 5, X[i, 2] * 15), 1:n)
k <- WarpKriging(y, X,
warping = c("mlp(16:8,2,selu)", "mlp(16:8,2,selu)"),
kernel = "matern5_2", normalize = TRUE,
parameters = list(max_iter_adam = "300"))
cat(summary(k))
set.seed(88)
X_test <- matrix(runif(15 * 2), ncol = 2)
p <- predict(k, X_test, stdev = TRUE)
expect_equal(length(p$mean), 15)
expect_true(all(is.finite(p$stdev)))
sims <- simulate(k, nsim = 20, seed = 42, x = X_test)
expect_equal(dim(sims), c(15, 20))
})
# ===========================================================================
# Test 11: None vs Kumaraswamy vs MLP comparison
# ===========================================================================
test_that("Warping improves over None baseline", {
X <- as.matrix(seq(0.01, 0.99, length.out = 12))
y <- f1d(X)
xp <- as.matrix(seq(0.01, 0.99, length.out = 50))
ytrue <- f1d(xp)
k_none <- WarpKriging(y, X, "none", "gauss",
parameters = list(max_iter_adam = "200"))
k_kuma <- WarpKriging(y, X, "kumaraswamy", "gauss",
parameters = list(max_iter_adam = "200"))
k_mlp <- WarpKriging(y, X, "mlp(16:8,2,selu)", "gauss",
parameters = list(max_iter_adam = "300"))
rmse <- function(model) sqrt(mean((predict(model, xp)$mean - ytrue)^2))
cat(sprintf(" RMSE None: %.6f\n RMSE Kuma: %.6f\n RMSE MLP: %.6f\n",
rmse(k_none), rmse(k_kuma), rmse(k_mlp)))
cat(sprintf(" LL None: %.4f\n LL Kuma: %.4f\n LL MLP: %.4f\n",
logLikelihood(k_none), logLikelihood(k_kuma), logLikelihood(k_mlp)))
expect_true(is.finite(rmse(k_none)))
expect_true(is.finite(rmse(k_kuma)))
expect_true(is.finite(rmse(k_mlp)))
})
# ===========================================================================
# Test 12: logLikelihoodFun
# ===========================================================================
test_that("logLikelihoodFun works with analytical gradient", {
X <- as.matrix(seq(0.01, 0.99, length.out = 8))
y <- f1d(X)
k <- WarpKriging(y, X, "affine", "gauss", optim = "none")
# Evaluate at a fixed benign theta (not the optimum) so FD is well-conditioned.
th <- rep(0.3, length(theta(k)))
ll <- logLikelihoodFun(k, th, return_grad = TRUE)
expect_true(is.finite(ll$logLikelihood))
expect_true(all(is.finite(ll$gradient)))
cat(" LL at theta=0.3:", ll$logLikelihood, "\n")
cat(" Gradient norm:", sqrt(sum(ll$gradient^2)), "\n")
# FD check
h <- 1e-5
grad_num <- numeric(length(th))
for (i in seq_along(th)) {
tp <- tm <- th
tp[i] <- tp[i] + h; tm[i] <- tm[i] - h
grad_num[i] <- (logLikelihoodFun(k, tp, FALSE)$logLikelihood -
logLikelihoodFun(k, tm, FALSE)$logLikelihood) / (2 * h)
}
rel <- sqrt(sum((ll$gradient - grad_num)^2)) /
(sqrt(sum(grad_num^2)) + 1e-12)
cat(" Gradient FD check error:", rel, "\n")
expect_lt(rel, 1e-4)
})
# ===========================================================================
# Test 13: Accessors and summary
# ===========================================================================
test_that("Summary and accessors work", {
X <- as.matrix(seq(0.01, 0.99, length.out = 6))
y <- f1d(X)
k <- WarpKriging(y, X, "boxcox", "matern3_2",
parameters = list(max_iter_adam = "100"))
s <- summary(k)
expect_true(is.character(s))
expect_true(nchar(s) > 0)
th <- theta(k)
expect_true(length(th) > 0)
expect_true(all(th > 0))
s2 <- sigma2(k)
expect_true(s2 > 0)
expect_equal(kernel(k), "matern3_2")
ll <- logLikelihood(k)
expect_true(is.finite(ll))
ws <- warping(k)
expect_equal(ws, "boxcox")
cat(" kernel:", kernel(k), "\n")
cat(" theta:", th, "\n")
cat(" sigma2:", s2, "\n")
cat(" warping:", ws, "\n")
expect_true(is_fitted(k))
})
# ===========================================================================
# Test 15: Predict with derivatives
# ===========================================================================
test_that("predict with deriv returns finite derivatives", {
X <- as.matrix(seq(0.01, 0.99, length.out = 8))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "affine", kernel = "gauss",
parameters = list(max_iter_adam = "100"))
X_new <- as.matrix(seq(0.1, 0.9, length.out = 5))
p <- predict(k, X_new, return_stdev = TRUE, return_deriv = TRUE)
expect_true(!is.null(p$mean_deriv))
expect_true(!is.null(p$stdev_deriv))
expect_equal(dim(p$mean_deriv), c(5, 1))
expect_equal(dim(p$stdev_deriv), c(5, 1))
expect_true(all(is.finite(p$mean_deriv)))
expect_true(all(is.finite(p$stdev_deriv)))
})
# ===========================================================================
# Test 16: Getters (feature_dim)
# ===========================================================================
test_that("feature_dim getter works", {
X <- as.matrix(seq(0.01, 0.99, length.out = 8))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "affine", kernel = "gauss",
parameters = list(max_iter_adam = "100"))
expect_true(feature_dim(k) > 0)
expect_true(all(theta(k) > 0))
expect_true(sigma2(k) > 0)
})
# ===========================================================================
# Test 17: Predict with covariance
# ===========================================================================
test_that("predict with cov returns finite covariance matrix", {
X <- as.matrix(seq(0.01, 0.99, length.out = 8))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "affine", kernel = "gauss",
parameters = list(max_iter_adam = "100"))
X_new <- as.matrix(seq(0.1, 0.9, length.out = 5))
p <- predict(k, X_new, return_stdev = TRUE, return_cov = TRUE)
expect_true(!is.null(p$cov))
expect_equal(dim(p$cov), c(5, 5))
expect_true(all(is.finite(p$cov)))
# Covariance matrix should be symmetric positive semi-definite
expect_true(max(abs(p$cov - t(p$cov))) < 1e-10)
})
# ===========================================================================
# Test 14: warp_*() helper functions return correct strings
# ===========================================================================
test_that("warp helpers produce correct strings", {
expect_equal(warp_none(), "none")
expect_equal(warp_affine(), "affine")
expect_equal(warp_boxcox(), "boxcox")
expect_equal(warp_kumaraswamy(), "kumaraswamy")
expect_equal(warp_neural_mono(16), "neural_mono(16)")
expect_equal(warp_mlp(c(16, 8), 3, "selu"), "mlp(16:8,3,selu)")
expect_equal(warp_categorical(5, 2), "categorical(5,2)")
expect_equal(warp_ordinal(4), "ordinal(4)")
})
# ===========================================================================
# Test 18: Copy
# ===========================================================================
test_that("copy creates an independent WarpKriging model", {
X <- as.matrix(seq(0.01, 0.99, length.out = 8))
y <- f1d(X)
k <- WarpKriging(y, X, warping = "affine", kernel = "gauss",
parameters = list(max_iter_adam = "100"))
k2 <- copy(k)
expect_s3_class(k2, "WarpKriging")
p2 <- predict(k2, X, stdev = TRUE)
expect_true(all(is.finite(p2$mean)))
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.