test_that("covariateStructure places longitude last within a spherical group", { lat <- c(-pi / 4, pi / 4, 0) lon <- c(-pi, pi, 0) df <- data.frame(longitude = lon, colatitude = lat) san <- covariateStructure_internal(df, c("S", "S")) extents <- apply(san$data, 2, function(col) diff(range(col))) expect_lte(extents[1], pi) expect_gt(extents[2], pi) expect_equal(san$data[, 1], lat) expect_equal(san$data[, 2], lon) expect_equal(names(san$data), c("colatitude", "longitude")) }) test_that("covariateStructure keeps names when spherical order is already correct", { lat <- c(-pi / 4, pi / 4, 0) lon <- c(-pi, pi, 0) df <- data.frame(colatitude = lat, longitude = lon) san <- covariateStructure_internal(df, c("S", "S")) expect_equal(names(san$data), c("colatitude", "longitude")) expect_equal(san$data$colatitude, lat) expect_equal(san$data$longitude, lon) }) test_that("fit preprocessing leaves spherical columns in original radians", { lat <- c(-0.3, 0.4, 0.1) lon <- c(-2.5, 2.8, 0.5) x <- cbind(lat, lon) metric <- c(1L, 1L) xScalingResult <- scaleData_internal(x) xScaled <- xScalingResult$scaledData xScaled[, metric != 0] <- x[, metric != 0] expect_equal(xScaled[, 1], lat) expect_equal(xScaled[, 2], lon) expect_false(isTRUE(all.equal(xScalingResult$scaledData[, 1], lat))) }) test_that("predict preprocessing matches fit for spherical columns", { lat <- c(-0.3, 0.4) lon <- c(-2.5, 2.8) newdata <- cbind(lat, lon) metric <- c(1L, 1L) centres <- c(mean(lat), mean(lon)) ranges <- c(diff(range(lat)), diff(range(lon))) xNewScaled <- applyScaling_internal(newdata, centres, ranges) xNewScaled[, metric != 0] <- newdata[, metric != 0] expect_equal(xNewScaled[, 1], lat) expect_equal(xNewScaled[, 2], lon) }) test_that("cellIndices remaps permuted active dimensions to global columns", { # Two active dimensions covering all covariates but given in reversed order. # The centre matrix columns follow `dim` order (col 1 -> covariate 2, # col 2 -> covariate 1). cellIndices must place them at the correct global # columns before computing distances, matching a brute-force nearest centre. x <- matrix(c( 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0 ), ncol = 2, byrow = TRUE) tess <- matrix(c( 0.0, 1.0, # covariate 2 coordinates (dim[1] == 2) 0.0, 1.0 # covariate 1 coordinates (dim[2] == 1) ), ncol = 2) dim <- c(2L, 1L) idx <- cellIndices(x, tess, dim, metric = 0L, members = 2L) brute <- apply(x, 1, function(row) { dists <- apply(tess, 1, function(cen) { sum((row[dim] - cen)^2) }) which.min(dists) }) expect_equal(idx, brute) }) test_that("in-sample and predicted values agree on the training data", { skip_on_cran() consistency <- function(x, metric) { withr::local_seed(11) n <- nrow(x) y <- sin(2 * x[, 1]) + cos(x[, 2]) + rnorm(n, sd = 0.2) fit <- AddiVortes(y, x, m = 15, totalMCMCIter = 200, mcmcBurnIn = 60, metric = metric, showProgress = FALSE ) preds <- predict(fit, as.matrix(x), showProgress = FALSE, parallel = FALSE) reRmse <- sqrt(mean((y - preds)^2)) abs(fit$inSampleRmse - reRmse) } n <- 120 lat <- runif(n, -pi / 4, pi / 4) lon <- runif(n, -pi, pi) # Euclidean control and spherical configurations, including column orders that # force covariateStructure_internal to reorder covariates. expect_lt(consistency(cbind(a = lat, b = lon), "E"), 1e-8) expect_lt(consistency(cbind(lat = lat, lon = lon), "S"), 1e-8) expect_lt(consistency(cbind(lon = lon, lat = lat), "S"), 1e-8) expect_lt(consistency(cbind(e = lat, lat = lat, lon = lon), c("E", "S", "S")), 1e-8) expect_lt(consistency(cbind(lat = lat, lon = lon, e = lon), c("S", "S", "E")), 1e-8) }) test_that("spherical fit and predict preserve coordinate values", { skip_on_cran() withr::local_seed(42) n <- 10 lat <- runif(n, -pi / 4, pi / 4) lon <- runif(n, -pi, pi) x <- data.frame(lat = lat, lon = lon) y <- rnorm(n) fit <- AddiVortes( y, x, m = 2, totalMCMCIter = 4, mcmcBurnIn = 0, metric = "S", showProgress = FALSE ) xnew <- data.frame(lat = lat[1:2], lon = lon[1:2]) pred <- predict(fit, as.matrix(xnew)) expect_length(pred, 2) expect_true(all(is.finite(pred))) }) test_that("spherical in-sample matches out-of-sample", { n <- 10 lat <- runif(n, -pi / 4, pi / 4) lon <- runif(n, -pi, pi) x <- data.frame(lat = lat, lon = lon) y <- rnorm(n) fit <- AddiVortes( y, x, m = 2, totalMCMCIter = 4, mcmcBurnIn = 0, metric = "S", showProgress = FALSE ) pred <- predict(fit, as.matrix(x)) in_sample <- fit$inSampleRmse out_sample <- sqrt(mean((y - pred)^2)) expect_equal(in_sample, out_sample, tolerance = 1e-8) })