
getwd()
rm(list = ls())
source('./src/data_pattern_generator.R')

library(FNN)
library(dplyr)
library("INLA")
library("Matrix")
library("sp")
library("parallel")
library("lattice")

library(spatstat)
library(RandomFields)
library(fields)
library(inlabru)

#----------------------- Get lgcp data ---------------------------
data <- read.csv("./data/xtrain.csv")
xy_coords <- data[, c("x", "y")]

# 确定观测域的边界（稍微扩大以避免点落在边界上）
buffer <- 0.5  # 边界缓冲值，可根据数据尺度调整
x_min <- min(xy_coords$x) - buffer
x_max <- max(xy_coords$x) + buffer
y_min <- min(xy_coords$y) - buffer
y_max <- max(xy_coords$y) + buffer

win <- owin(c(x_min,x_max), c(y_min,y_max))
# spatstat.options(npixel = 21*21)
# # spatstat.options(npixel = 21*21)
# y0 = x0 = seq(win$xrange[1], win$xrange[2], length = spatstat.options()$npixel)
# nu = 1
# d = 2
# 
# kappa_HVGA = 0.2
# 
# gridcov = outer(x0, y0, function(x,y) cos(x-2.5)-sin(y-3.5))
# pl.dom_hole = cbind(c(2, 8, 8, 2), c(2, 2, 8.5, 8.5))
# beta_0 = 2.5
# beta_1 = 0.8
# tau_0 = 2
# nu = 1
# kappa_0 = 0.3
# (sigma2 = gamma(nu) / ((tau_0^2)*gamma(nu+d/2)*((4*pi)^(d/2))*(kappa_0^(2*nu))))
# 
# DP_with_hole1 = Data_pattern_generator(beta_0, beta_1, tau_0, nu, kappa_0, random_seed = 1, domain_type = "with hole", max_edge = 0.5)
# DP_without_hole1 = Data_pattern_generator(beta_0, beta_1, tau_0, nu, kappa_0, random_seed = 1, domain_type = "without hole", max_edge = 0.5)

# Domain boundary
pl.dom = cbind(c(x_min,x_max,x_max,x_min), c(y_min,y_min,y_max,y_max))
bnd1 = Polygon(pl.dom, hole = FALSE)
xy.c_observed = as.matrix(xy_coords)
max_edge = min(x_max, y_max)/20

#--------------------------------------------------------
N = nrow(xy.c_observed)
plot(xy.c_observed)

# n_test = as.integer(0.2*N)
# margin = 0.5
# 
# min_dist = 0.4
# 
# sampling_x_min = win$xrange[1] + margin
# sampling_x_max = win$xrange[2] - margin
# sampling_y_min = win$yrange[1] + margin
# sampling_y_max = win$yrange[2] - margin
# 
# if (sampling_x_min >= sampling_x_max || sampling_y_min >= sampling_y_max) {
#   stop("Margin is too large, resulting in an invalid sampling area.")
# }
# 
# sampling_win <- owin(c(sampling_x_min, sampling_x_max), c(sampling_y_min, sampling_y_max))
# cat("Attempting to generate", n_test, "points with minimum distance", min_dist, "...\n")
# ppp_test <- rSSI(r = min_dist, n = n_test, win = sampling_win, giveup = 1000, verbose = FALSE)
# 
# n_generated <- npoints(ppp_test)
# if (n_generated < n_test) {
#   warning(paste("Could only generate", n_generated, "points out of the requested",
#                 n_test, "due to the minimum distance constraint (min_dist =", min_dist, ").",
#                 "Consider reducing n_test or min_dist if more points are needed."))
# } else {
#   cat("Successfully generated", n_generated, "points.\n")
# }


# loc_test <- coords(ppp_test)
loc_test = read.csv("./data/xtest.csv")
loc_test = as.matrix(loc_test)
print(head(loc_test))
cat("Actual number of points generated:", nrow(loc_test), "\n")

plot(win, main = paste("Generated Test Locations (rSSI, min_dist =", min_dist, ")"))
plot(sampling_win, border = "blue", add = TRUE)
points(loc_test, pch = 16, col = "red")
legend("topright", legend = c("Original Domain", "Sampling Area", "Generated Points"),
       lty = c(1, 1, NA), pch = c(NA, NA, 16), col = c("black", "blue", "red"))

if (n_generated > 1) {
  min_observed_dist <- min(nndist(ppp_test))
  cat("Minimum distance observed between generated points:", round(min_observed_dist, 4), "\n")
  if(min_observed_dist < min_dist - 1e-9) {
    warning("Observed minimum distance is slightly less than specified min_dist!")
  }
}
n_test = length(loc_test[,1])
#------------------------------ mesh --------------------------------------
pl.dom = cbind(c(x_min,x_max,x_max,x_min), c(y_min,y_min,y_max,y_max))
bnd1 = Polygon(pl.dom, hole = FALSE)
max_edge = min(x_max, y_max)/10
mesh_full = inla.mesh.2d(loc_test, pl.dom, boundary = bnd1, max.edge = max_edge)
plot(mesh_full)
points(xy.c_observed)

N = nrow(xy.c_observed)
n = mesh_full$n


mesh_vertices <- mesh_full$loc[ ,1:2]
nn_result <- get.knnx(data = mesh_vertices,
                      query = loc_test,
                      k = 1)
mesh_ind_loc_test <- nn_result$nn.index[, 1]

# plot
par(mar = c(0, 0, 2, 0))
plot(mesh_full, asp = 1, main = '')
points(xy.c_observed, pch = 20, col = 'red')
# points(mesh_full$loc[,1:2], pch = 20, col = 'black')
# points(loc_test, pch = 20, col = 'green')
# points(mesh_full$loc[mesh_ind_loc_test,1:2], col = 'blue')
# title('Mesh Over Bei Data')
# rm(mesh_vertices, mesh_loc, nn_result)

#------------------------------- Dual mesh -------------------------------
alpha_weight = DualMesh_parameter(mesh_full)[[1]]
Dualmesh_loc = DualMesh_parameter(mesh_full)[[2]]

loc_n_N = rbind(mesh_vertices, xy.c_observed)

#------------------------------- covariate ----------------------------------
n_test = nrow(loc_test)
X = cbind(rep(1, N))
X_tilde = cbind(rep(1, n))
X_test = cbind(rep(1, n_test))


# A_tilde and A
zero_block1 = matrix(0, nrow = n, ncol = N)
zero_block2 = matrix(0, nrow = N, ncol = n)
A_tilde = as(cbind(diag(n), zero_block1), "dgCMatrix")
A = as(cbind(zero_block2, diag(N)), "dgCMatrix")

rm(zero_block1, zero_block2)
rm(x0,y0,tau_0,sampling_win,sampling_x_max,sampling_x_min,sampling_y_max,sampling_y_min,min_observed_dist,min_dist,margin,ppp_test,mesh_hole,esh_vertices)
rm(n_generated)
rm(n_hole,N_hole)

getwd()
save(list = ls(all.names = TRUE), file = "./data/lgcp_data_full.RData", envir = .GlobalEnv)
