
home.wd <- getwd()

source('./src/dual_mesh_loc.R')

Data_pattern_generator = function(beta_0, beta_1, tau_0, nu, kappa_0, random_seed = 1, domain_type = c("without hole", "with hole"), max_edge = 0.5){
  set.seed(random_seed)
  
  kappa = (sqrt(2*nu))/kappa_0
  sigma2 = gamma(nu) / ((tau_0^2)*gamma(nu+d/2)*((4*pi)^(d/2))*(kappa_0^(2*nu)))
  
  # RF with covariate
  lg.s.c = rLGCP('matern', im(beta_0 + beta_1*gridcov, xcol=x0, yrow=y0),
                 var=sigma2, scale=kappa, nu=1, win=win)
  
  # Domain boundary
  pl.dom = cbind(c(0,domain_max,domain_max,0), c(0,0,domain_max,domain_max))
  # pl.dom_hole = cbind(c(2, 8, 8, 2), c(2, 2, 8.5, 8.5))
  # pl.dom = cbind(c(-0.5,domain_max+0.5,domain_max+0.5,-0.5), c(-0.5,-0.5,domain_max+0.5,domain_max+0.5))
  # pl.dom_hole = cbind(c(2, 8, 8, 2), c(2, 2, 8.5, 8.5))
  
  bnd1 = Polygon(pl.dom, hole = FALSE)
  bnd_hole = Polygon(pl.dom_hole, hole = TRUE)
  bnd2 = Polygon(pl.dom_hole, hole = FALSE)
  sp = SpatialPolygons(list(Polygons(list(bnd1, bnd_hole), "0"), 
                            Polygons(list(bnd2), "1")))
  sp_hole = SpatialPolygons(list(Polygons(list(bnd_hole), "hole")))
  # plot(sp)
  bound = inla.sp2segment(sp)
  
  if(domain_type == "without hole"){
    # xy.c = cbind(lg.s.c$x, lg.s.c$y)[, 2:1]
    xy.c = cbind(lg.s.c$x, lg.s.c$y)
    mesh = inla.mesh.2d(xy.c, pl.dom, boundary = bnd1, max.edge = max_edge, cutoff = max_edge/5)
    result_list = list(lg.s.c, xy.c, mesh)
    names(result_list) = c("lg_s_c", "xy_c_observed", "mesh")
    return(result_list)
  }
  
  if(domain_type == "with hole"){
    # xy.c = cbind(lg.s.c$x, lg.s.c$y)[, 2:1]
    xy.c = cbind(lg.s.c$x, lg.s.c$y)
    xy.c_points = SpatialPoints(xy.c)
    xy.c_inside = over(xy.c_points, sp_hole)
    xy.c_outside = xy.c_points[is.na(xy.c_inside), ]
    xy.c_hole = xy.c_points[!is.na(xy.c_inside), ]
    xy.c_unobserved = cbind(xy.c_hole@coords[ ,1], xy.c_hole@coords[ ,2])
    xy.c_observed = cbind(xy.c_outside@coords[ ,1], xy.c_outside@coords[ ,2])
    
    # # 从洞外再随机删除 random_per 的观测点
    # random_per = 0.1
    # rows_to_choose = sample(1:nrow(xy.c_observed), size = round(random_per*nrow(xy.c_observed)))
    # xy.c_unobserved = rbind(xy.c_unobserved, xy.c_observed[rows_to_choose, ])
    # xy.c_observed = xy.c_observed[-rows_to_choose, , drop = FALSE]
    
    mesh = inla.mesh.2d(xy.c_observed, pl.dom, boundary = bnd1, max.edge = max_edge, cutoff = max_edge/5)
    
    result_list = list(lg.s.c, xy.c_observed, xy.c_unobserved, mesh)
    names(result_list) = c("lg_s_c", "xy_c_observed", "xy_c_unobserved", "mesh")
    return(result_list)
  }
}

# log-intensity covariance matrix

# Matern_kernel_ele = function(x, y, sigma, kappa, nu = 1){
#    d = sqrt(sum((x-y)^2))
#    
#    if(d == 0){
#     return(sigma^2)
#      }
#    else{
#      return(sigma^2 * (sqrt(2*nu)*d/kappa) * besselK(sqrt(2*nu)*d/kappa, nu) / ((2^(nu-1)*gamma(nu))))
#      }
#  }
# # 
# logintensity_cov = function(data_pattern_loc, sigma, kappa, nu = 1){
#   N = nrow(data_pattern_loc)
#   cov_mat = matrix(0, N, N)
#   
#   for (i in 1:N) {
#     for (j in 1:N) {
#       cov_mat[i,j] = Matern_kernel_ele(data_pattern_loc[i, ], data_pattern_loc[j, ], sigma, kappa, nu = 1)
#     }
#   }
#   return(cov_mat)
# }
# 
# kappa = (sqrt(2*nu))/kappa_0
# sigma2 = gamma(nu) / ((tau_0^2)*gamma(nu+d/2)*((4*pi)^(d/2))*(kappa_0^(2*nu)))
# logintensity_cov_true = logintensity_cov(xy.c, sigma = sqrt(sigma2), kappa = kappa, nu = 1)
# logintensity_corr_true = logintensity_cov_true/sigma2
# 
# custom_gray_colors <- colorRampPalette(c("white", "black"))
# heatmap(logintensity_cov_true, Rowv = NA, Colv = NA, col = custom_gray_colors(256))
# dev.off()
