# Two-dimensional density estimation

This vignette illustrates two-dimensional density estimation and visualization. It complements the estimator-choice vignette by focusing on the 2D workflow.

    library(GLBFP)

## Simulated example

The example uses a small reproducible mixture so the vignette remains quick to build.

    n <- 250
    group <- rbinom(n, size = 1, prob = 0.5)

    x <- cbind(
      rnorm(n, mean = ifelse(group == 1, -1.2, 1.2), sd = 0.7),
      rnorm(n, mean = ifelse(group == 1, 1.0, -1.0), sd = 0.8)
    )

    colnames(x) <- c("x1", "x2")

    b <- compute_bi_optim(x, m = c(1, 1))
    b
    #> [1] 0.3210361 0.3159536

## Pointwise estimation

    x0 <- c(0, 0)

    ash_fit <- ash(x0, x, b = b, m = c(1, 1))
    lbfp_fit <- lbfp(x0, x, b = b)
    glbfp_fit <- glbfp(x0, x, b = b, m = c(1, 1))

    c(
      ASH = ash_fit$estimation,
      LBFP = lbfp_fit$estimation,
      GLBFP = glbfp_fit$estimation
    )
    #>        ASH       LBFP      GLBFP
    #> 0.03943508 0.01941260 0.01941260

## Grid estimation

    grid_fit <- glbfp_estimate(x, b = b, m = c(1, 1), grid_size = 20)
    summary(grid_fit)
    #> Method: GLBFP
    #> Dimension: 2
    #> Grid points: 400
    #> Grid type: rectangular
    #> Grid dimensions: 20 x 20
    #> Bandwidths (b): 0.321036127107069, 0.315953610723842
    #> Shifts (m): 1, 1
    #> Density range: 0 to 0.210331281836707
    #> Density quartiles: 0, 0.00348642703612869, 0.0356905349965338
    #> Density median: 0.003486427
    #> Density mean: 0.02480127
    #> Zero densities: 188
    #> Standard error median: 0.007210991
    #> Median visited cells: 1
    #> Median prefix nodes: 6
    head(as.data.frame(grid_fit))
    #>          x1        x2 density sd IC_lower IC_upper visited prefix_nodes
    #> 1 -2.974658 -2.888704       0  0        0        0       0            6
    #> 2 -2.657723 -2.888704       0  0        0        0       0            6
    #> 3 -2.340789 -2.888704       0  0        0        0       0            6
    #> 4 -2.023855 -2.888704       0  0        0        0       0            6
    #> 5 -1.706920 -2.888704       0  0        0        0       0            6
    #> 6 -1.389986 -2.888704       0  0        0        0       0            6

## Visualization

For two-dimensional regular grids, `contour = TRUE` returns a static `ggplot2` contour plot.

    plot(grid_fit, contour = TRUE)

With `contour = FALSE`, the plot method returns an interactive surface. This is useful for exploration. Static contours are usually easier to reproduce in manuscripts, and they keep this vignette lightweight for CRAN checks.

    surface <- plot(grid_fit, contour = FALSE)
    surface

## Computational note

The number of evaluation points grows quickly with `grid_size` in two dimensions. For manuscript figures, start with a moderate grid and increase it only after confirming that the visual conclusions are stable.