library(ggplot2)  # For plotting histogram and KDE
# Log of the target density f(x) = 0.5 * exp(-|x|)
log_f <- function(x) {
  log(0.5) - abs(x)
}

# Random Walk Metropolis function
random_walk_metropolis <- function(N, s, x0 = 0) {
  samples <- numeric(N + 1)  # Create vector to store samples
  samples[1] <- x0  # Initial value
  for (i in 2:(N + 1)) {  # Loop from 1 to N
    x_current <- samples[i - 1]  # Current sample
    x_star <- rnorm(1, mean = x_current, sd = s)  # Propose new value from Normal
    log_r <- log_f(x_star) - log_f(x_current)  # Log acceptance ratio
    u <- runif(1, min = 0, max = 1)  # Uniform random number
    if (log(u) < log_r) {  # Accept if condition true
      samples[i] <- x_star
    } else {  # Reject, stay at current
      samples[i] <- x_current
    }
  }
  return(samples[2:(N + 1)])  # Return x1 to xN
}
# Run Simulation
N <- 10000  # Number of samples
s <- 1      # Proposal standard deviation
set.seed(42) # For reproducibility (same results every time)
samples <- random_walk_metropolis(N, s)
mean_mc <- mean(samples)  # Monte Carlo mean estimate
sd_mc <- sd(samples)  # Monte Carlo SD estimate
cat(sprintf("Sample Mean: %.4f\n", mean_mc))  # Should be close to 0
## Sample Mean: -0.0006
cat(sprintf("Sample Standard Deviation: %.4f\n", sd_mc))  # Should be close to 1.4142
## Sample Standard Deviation: 1.3479
# FINAL CLEAN PLOT CHUNK - ZERO ERRORS, ZERO WARNINGS

# Prepare data
df_samples <- data.frame(x = samples)
x_vals <- seq(-10, 10, length.out = 1000)
df_true <- data.frame(x = x_vals, y = 0.5 * exp(-abs(x_vals)))

# Plot
ggplot(df_samples, aes(x = x)) +
  geom_histogram(aes(y = after_stat(density)), 
                 bins = 50, fill = "skyblue", color = "black", alpha = 0.7) +
  geom_density(color = "red", linewidth = 1) +
  geom_line(data = df_true, aes(x = x, y = y), 
            color = "black", linewidth = 1) +
  labs(title = "Histogram, KDE, and True Density (N=10000, s=1)",
       x = "x", y = "Density") +
  coord_cartesian(xlim = c(-10, 10)) +
  theme_minimal()

ggsave("part1a_plot_R.png")
## Saving 7 x 5 in image
# === PART 1(b): R-hat convergence diagnostic function ===
compute_rhat <- function(N, s, J, initial_values) {
  chains <- lapply(initial_values, function(iv) random_walk_metropolis(N, s, iv))
  
  Mj <- sapply(chains, mean)
  Vj <- sapply(chains, function(chain) mean((chain - mean(chain))^2))  # as per assignment (N denominator)
  
  W <- mean(Vj)
  M <- mean(Mj)
  B <- mean((Mj - M)^2)
  
  R <- (B + W) / W          # EXACT formula from the assignment
  return(R)
}
# === PART 1(b) RESULTS AND PLOT ===

N <- 2000
J <- 4
initial_values <- c(-10, -5, 5, 10)
set.seed(42)

# 1. R for s = 0.001 (as required)
r_fixed <- compute_rhat(N, 0.001, J, initial_values)
cat("R-hat for s=0.001 (N=2000, J=4):", round(r_fixed, 4), "\n")
## R-hat for s=0.001 (N=2000, J=4): 203808.7
# 2. Grid of s values and R-hat plot
s_grid <- exp(seq(log(0.001), log(1), length.out = 20))
r_values <- sapply(s_grid, function(s) compute_rhat(N, s, J, initial_values))

df_r <- data.frame(s = s_grid, R = r_values)

ggplot(df_r, aes(x = s, y = R)) +
  geom_point(color = "blue", size = 2) +
  geom_line(color = "blue") +
  scale_x_log10() +
  geom_hline(yintercept = 1.05, color = "red", linetype = "dashed", linewidth = 1) +
  labs(title = "R-hat vs s (N=2000, J=4)",
       x = "s (log scale)",
       y = "R-hat") +
  theme_minimal()

ggsave("part1b_plot_R.png")
## Saving 7 x 5 in image