Nothing
test_that("generic_ns basic functionality works", {
# Create test matrices
n <- 5
A <- matrix(1, n, n)
B <- matrix(2, n, n)
alpha <- 0.4
# Create a simple generic_ns model
model <- generic_ns(
theta_K = list(alpha = c(alpha)),
matrices = list(A, B),
h = rep(1, n),
position = list(c(2, 1), c(3)) # Diagonal(alpha) * A + B
)
# First position c(2, 1) means:
# - Matrix at index 2 (A) multiplied by
# - Matrix at index 1 (Diagonal with alpha)
# Second position c(3) means matrix at index 3 (B)
# So expected_K = A * Diagonal(alpha) + B
expected_K <- A %*% Matrix::Diagonal(n, alpha) + B
expect_equal(as.matrix(model$K), as.matrix(expected_K))
expect_equal(length(model$matrices), 2) # Only original matrices are stored
expect_equal(model$h, rep(1, n))
})
test_that("generic_ns with parameter transformations works", {
n <- 5
A <- matrix(1, n, n)
B <- matrix(2, n, n)
alpha <- 0.6
# Create model with parameter transformations
model <- generic_ns(
theta_K = list(alpha = c(log(alpha))),
matrices = list(A, B),
h = rep(1, n),
trans = list(alpha = "exp"),
position = list(c(1, 2), c(3)) # Diagonal(exp(log(alpha))) * A + B = Diagonal(alpha) * A + B
)
# With exp transformation, expected_K = A * Diagonal(alpha) + B
expected_K <- A %*% Matrix::Diagonal(n, alpha) + B
expect_equal(as.matrix(model$K), as.matrix(expected_K))
# Check flat parameters
expect_equal(model$theta_K, c(alpha = log(alpha)))
})
test_that("generic_ns with custom basis expansion works", {
n <- 10
A <- matrix(1, n, n)
B <- matrix(2, n, n)
C <- matrix(3, n, n)
# Create basis matrices (simple example for testing)
basis_alpha <- matrix(rnorm(n), n, 1) # One coefficient per location
alpha <- 0.5
# Create model with basis expansion
model <- generic_ns(
theta_K = list(alpha = c(alpha)),
matrices = list(A, B, C),
h = rep(1, n),
B_theta_K = list(alpha = basis_alpha),
trans = list(alpha = "identity"),
position = list(c(1, 2), c(3, 2, 1), c(4)) # Diagonal(basis_alpha * alpha) * A + B
)
# Expected: K = D_alpha * A + B
alpha_vec <- as.vector(basis_alpha %*% alpha)
D_alpha <- Matrix::Diagonal(x = alpha_vec)
expected_K <- D_alpha %*% A + B %*% A %*% D_alpha + C
expect_equal(as.matrix(model$K), as.matrix(expected_K))
expect_false(identical(as.matrix(A %*% D_alpha), as.matrix(D_alpha %*% A)))
})
test_that("generic_ns with B_theta_K defaults to matrices of 1s", {
n <- 5
A <- matrix(1, n, n)
B <- matrix(2, n, n)
alpha <- 0.7
# Create model without explicit B_theta_K
model <- generic_ns(
theta_K = list(alpha = c(alpha)),
matrices = list(A, B),
h = rep(1, n),
position = list(c(1, 2), c(3)) # Diagonal(alpha*ones(n)) * A + B = Diagonal(alpha) * A + B
)
# Default B_theta_K is a matrix of 1s, so expected_K = A * Diagonal(alpha) + B
expected_K <- A %*% Matrix::Diagonal(n, alpha) + B
expect_equal(as.matrix(model$K), as.matrix(expected_K))
})
test_that("generic_ns handles complex matrix combinations", {
n <- 5
A <- matrix(1, n, n)
B <- matrix(2, n, n)
C <- matrix(3, n, n)
D <- matrix(4, n, n)
alpha <- 0.8
beta <- 1.2
# Create a complex model with multiple operations
model <- generic_ns(
theta_K = list(alpha = c(alpha), beta = c(beta)),
matrices = list(A, B, C, D),
h = rep(1, n),
trans = list(alpha = "identity", beta = "identity"),
position = list(c(1, 3), c(2, 4), c(1, 5), c(2, 6))
# This represents: Diagonal(alpha)*A + Diagonal(beta)*B + Diagonal(alpha)*C + Diagonal(beta)*D
)
# Calculate expected result
D_alpha <- Matrix::Diagonal(n, alpha)
D_beta <- Matrix::Diagonal(n, beta)
expected_K <- (D_alpha %*% A) + (D_beta %*% B) + (D_alpha %*% C) + (D_beta %*% D)
expect_equal(as.matrix(model$K), as.matrix(expected_K))
})
test_that("generic_ns with spatially-varying kappa works", {
# Create a simple 1D mesh
n <- 10
mesh <- fmesher::fm_mesh_1d(seq(0, 1, length.out = n))
# Create basis for spatially-varying kappa
B_kappa <- matrix(0, n, 2)
B_kappa[1:(n / 2), 1] <- 1 # First half of the domain
B_kappa[(n / 2 + 1):n, 2] <- 1 # Second half of the domain
# Create standard Matern components
matern_model <- matern(mesh)
C <- matern_model$C
G <- matern_model$G
# Create model with space-varying kappa
ns_model <- generic_ns(
theta_K = list(kappa = c(log(1), log(2))), # log(kappa) values
matrices = list(C, G), # Include both matrices C and G
B_theta_K = list(kappa = B_kappa),
trans = list(kappa = "exp2"), # kappa^2 transformation for C
h = matern_model$h,
position = list(c(1, 2), c(3)), # D_kappa * C + G
mesh = mesh
)
# Create the expected K matrix manually
kappa_vec <- exp(2 * (B_kappa %*% c(log(1), log(2))))
D_kappa <- Matrix::Diagonal(x = kappa_vec)
expected_K <- D_kappa %*% C + G
expect_equal(as.matrix(ns_model$K), as.matrix(expected_K))
})
test_that("generic_ns handles edge cases correctly", {
n <- 5
A <- matrix(1, n, n)
B <- matrix(2, n, n)
# Single matrix, no parameters
model1 <- generic_ns(
theta_K = list(),
matrices = list(A),
position = list(c(1)),
h = rep(1, n)
)
expect_equal(as.matrix(model1$K), A)
# Multiple parameters with same transformation
model3 <- generic_ns(
theta_K = list(alpha = c(1), beta = c(2)),
matrices = list(A, B),
h = rep(1, n),
trans = list(alpha = "exp", beta = "exp"),
position = list(c(1, 2), c(3, 2, 1), c(4))
)
D_alpha <- Matrix::Diagonal(n, exp(1))
D_beta <- Matrix::Diagonal(n, exp(2))
expected_K <- D_alpha %*% D_beta + A %*% D_beta %*% D_alpha + B
expect_equal(as.matrix(model3$K), as.matrix(expected_K))
})
test_that("generic_ns with complex matrix combinations works", {
n <- 5
A <- matrix(rnorm(n^2), n, n)
B <- matrix(rnorm(n^2), n, n)
C <- matrix(rnorm(n^2), n, n)
D <- matrix(rnorm(n^2), n, n)
# Create a complex model with nested matrix operations
model <- generic_ns(
theta_K = list(alpha = c(1), beta = c(2)),
matrices = list(A, B, C, D),
h = rep(1, n),
trans = list(alpha = "identity", beta = "exp"),
position = list(c(1, 2), c(3, 4), c(1, 5), c(2, 6))
# This represents: D_alpha * D_beta + A * B + D_alpha * C + D_beta * D
)
D_alpha <- Matrix::Diagonal(n, 1)
D_beta <- Matrix::Diagonal(n, exp(2))
expected_K <- D_alpha %*% D_beta + A %*% B + D_alpha %*% C + D_beta %*% D
expect_equal(as.matrix(model$K), as.matrix(expected_K))
})
test_that("generic_ns model == AR1 model", {
# Test AR1 representation
seed <- 10
n_obs <- 5
Y <- rnorm(n_obs)
ar1 <- ar1(1:n_obs, rho = 0.5)
g <- name2fun("tanh", inv = TRUE)
ar1$param_name
ar1$param_trans
generic_ar1 <- generic_ns(
theta_K = list(x = c(g(0.5))), # trans(X) = rho
trans = list(x = "tanh"),
matrices = list(ar1$C, ar1$G),
position = list(c(1, 2), c(3)),
h = ar1$h,
mesh = 1:n_obs
)
generic_ar1
generic_ar1$param_name
generic_ar1$param_trans
expect_equal(ar1$K, ar1$C * 0.5 + ar1$G)
expect_equal(generic_ar1$K, ar1$K)
expect_equal(generic_ar1$matrices, list(ar1$C, ar1$G))
control <- control_opt(
seed = seed,
iterations = 100,
n_parallel_chain = 4,
n_batch = 1
)
fit_ar1 <- ngme(
Y ~ 0 + f(
1:n_obs,
name = "my_ar",
model = ar1(rho = 0.5)
),
data = data.frame(Y = Y),
control_opt = control
)
fit_ar1
est_rho_ar1 <- ar1_th2a(ngme_result(fit_ar1, "my_ar")$rho)
print(est_rho_ar1)
print(generic_ar1$K)
generic_ar1$param_map
generic_ar1$position
fit_generic <- ngme(
Y ~ 0 + f(
1:n_obs,
name = "generic",
model = generic_ns(
theta_K = list(rho = g(0.5)),
trans = list(rho = "tanh"),
matrices = list(ar1$C, ar1$G),
h = ar1$h,
position = list(c(1, 2), c(3))
)
),
data = data.frame(Y = Y),
control_opt = control
)
fit_generic
est_rho_generic <- ar1_th2a(ngme_result(fit_generic, "generic")$rho)
print(est_rho_generic)
expect_equal(est_rho_generic[[1]][1], est_rho_ar1[[1]][1])
})
test_that("generic model == Matern model (alpha == 2 or 4)", {
x <- seq(0, 1, length.out = 10)
y <- seq(0, 1, length.out = 10)
mesh <- fmesher::fm_mesh_2d(cbind(x, y))
mesh$n
B_kappa <- matrix(rnorm(mesh$n * 2), mesh$n, 2)
theta_kappa <- c(0.5, 0.3)
matern <- matern(
mesh,
alpha = 4,
theta_kappa = theta_kappa,
B_kappa = B_kappa
)
kappas <- as.numeric(exp(B_kappa %*% theta_kappa))
D_kappa <- Matrix::Diagonal(x = kappas)
C <- matern$C
G <- matern$G
Cinv <- C
diag(Cinv) <- 1 / Matrix::diag(C)
# Complicated K matrix
# D_\kappa C D_\kappa C^{-1} D_\kappa C D_\kappa + D_\kappa C D_\kappa C^{-1} G + G C^{-1} D_\kappa C D_\kappa + G C^{-1} G
full_K <- D_kappa %*% C %*% D_kappa %*% Cinv %*% D_kappa %*% C %*% D_kappa +
D_kappa %*% C %*% D_kappa %*% Cinv %*% G +
G %*% Cinv %*% D_kappa %*% C %*% D_kappa +
G %*% Cinv %*% G
expect_equal(matern$K, full_K)
# matrices list : D_kappa, C, G, Cinv
generic_model_matern <- generic_ns(
theta_K = list(theta = theta_kappa),
trans = list(theta = c("exp")),
B_theta_K = list(theta = B_kappa),
matrices = list(C, G, Cinv),
position = list(
c(1, 2, 1, 4, 1, 2, 1),
c(1, 2, 1, 4, 3),
c(3, 4, 1, 2, 1),
c(3, 4, 3)
),
h = matern$h
)
expect_equal(generic_model_matern$symmetric, matern$symmetric)
expect_equal(generic_model_matern$zero_trace, matern$zero_trace)
expect_equal(generic_model_matern$h, matern$h)
expect_equal(generic_model_matern$K, matern$K, tolerance = 1e-4)
# Fitting the matern model
control <- control_opt(
seed = 10,
iterations = 50,
n_parallel_chain = 4,
n_batch = 1,
)
Y <- rnorm(10)
fit_matern_2 <- ngme(
Y ~ 0 + f(
cbind(x, y),
model = matern(
mesh = mesh,
theta_kappa = theta_kappa,
B_kappa = B_kappa,
alpha = 2
)
),
data = data.frame(Y = Y),
control_opt = control
)
fit_matern_2
est_theta_matern_2 <- ngme_result(fit_matern_2, "field1")$kappa
est_theta_matern_2[[1]]
fit_generic_2 <- ngme(
Y ~ 0 + f(
cbind(x, y),
name = "generic",
model = generic_ns(
mesh = mesh,
theta_K = list(theta = theta_kappa),
trans = list(theta = c("exp")),
B_theta_K = list(theta = B_kappa),
matrices = list(C, G),
position = list(
c(1, 2, 1),
c(3)
),
h = matern$h
)
),
data = data.frame(Y = Y),
control_opt = control
)
fit_generic_2
est_theta_generic_2 <- ngme_result(fit_generic_2, "generic")$theta
expect_equal(est_theta_generic_2[[1]], est_theta_matern_2[[1]], tolerance = 1e-4)
fit_matern_4 <- ngme(
Y ~ 0 + f(
cbind(x, y),
model = matern(
mesh = mesh,
theta_kappa = theta_kappa,
B_kappa = B_kappa,
alpha = 4
)
),
data = data.frame(Y = Y),
control_opt = control
)
fit_matern_4
est_theta_matern_4 <- ngme_result(fit_matern_4, "field1")$operator$theta_K
est_theta_matern_4[[1]]
fit_generic_alpha_4 <- ngme(
Y ~ 0 + f(
cbind(x, y),
name = "generic",
model = generic_ns(
mesh = mesh,
theta_K = list(theta = theta_kappa),
trans = list(theta = c("exp")),
B_theta_K = list(theta = B_kappa),
matrices = list(C, G, Cinv),
position = list(
c(1, 2, 1, 4, 1, 2, 1),
c(1, 2, 1, 4, 3),
c(3, 4, 1, 2, 1),
c(3, 4, 3)
),
h = matern$h
)
),
data = data.frame(Y = Y),
control_opt = control
)
fit_generic_alpha_4
est_theta_generic_alpha_4 <- ngme_result(fit_generic_alpha_4, "generic")$operator$theta_K
expect_equal(est_theta_generic_alpha_4[[1]], est_theta_matern_4[[1]], tolerance = 1e-4)
})
test_that("ou (generic) equals rho*C + G on uniform mesh", {
mesh <- 1:8
rho <- 0.3
theta <- -log(rho)
op <- ou(mesh = mesh, theta = theta)
C <- Matrix::sparseMatrix(j = 1:(length(mesh) - 1), i = 2:length(mesh), x = -1, dims = c(length(mesh), length(mesh)))
G <- Matrix::Diagonal(length(mesh))
G[1, 1] <- sqrt(1 - rho^2)
expected <- rho * C + G
expect_equal(as.matrix(op$K), as.matrix(expected))
})
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.