## ----setup, include = FALSE---------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment  = "#>",
  fig.width = 6, fig.height = 4
)
set.seed(20260529)
has_ggplot <- requireNamespace("ggplot2", quietly = TRUE)

## ----cran-gate, include = FALSE-----------------------------------------------
# The model fits below are evaluated when the article is built locally, in CI
# and for the pkgdown site (all of which set NOT_CRAN). CRAN's check farm gives
# the whole check a ten-minute budget, which these fits do not fit inside, so
# there the code is shown without being run.
EVAL_FITS <- identical(Sys.getenv("NOT_CRAN"), "true")
knitr::opts_chunk$set(eval = EVAL_FITS)

## ----load, message = FALSE----------------------------------------------------
# library(tulpa)

## ----first-evidence-----------------------------------------------------------
# n  <- 500
# x  <- rnorm(n)
# y0 <- 0.5 + 1.2 * x + rnorm(n, sd = 0.8)
# df <- data.frame(y = y0, x = x)
# 
# fit <- tulpa(y ~ x, data = df, family = "gaussian",
#              mode = "laplace", phi = 0.8)
# logLik(fit)

## ----evidence-attrs-----------------------------------------------------------
# c(df = attr(logLik(fit), "df"), nobs = attr(logLik(fit), "nobs"))

## ----sim-ladder---------------------------------------------------------------
# n  <- 500
# x  <- rnorm(n)
# z  <- rnorm(n)
# g  <- factor(sample(1:15, n, replace = TRUE))
# u  <- rnorm(15, sd = 0.7)
# y  <- 0.5 + 1.2 * x + 0.8 * z + u[g] + rnorm(n, sd = 0.8)
# dat <- data.frame(y = y, x = x, z = z, g = g)

## ----fit-ladder---------------------------------------------------------------
# m0 <- tulpa(y ~ 1, data = dat, family = "gaussian",
#             mode = "laplace", phi = 0.8)
# m1 <- tulpa(y ~ x, data = dat, family = "gaussian",
#             mode = "laplace", phi = 0.8)
# m2 <- tulpa(y ~ x + (1 | g), data = dat, family = "gaussian",
#             mode = "laplace", sigma_re = 0.7, phi = 0.8)
# m3 <- tulpa(y ~ x + z + (1 | g), data = dat, family = "gaussian",
#             mode = "laplace", sigma_re = 0.7, phi = 0.8)

## ----ladder-evidence----------------------------------------------------------
# ll <- c(intercept = as.numeric(logLik(m0)),
#         slope     = as.numeric(logLik(m1)),
#         slope_re  = as.numeric(logLik(m2)),
#         full      = as.numeric(logLik(m3)))
# data.frame(model = names(ll), logLik = round(ll, 1),
#            gain = c(NA, round(diff(ll), 1)))

## ----ladder-plot, eval = has_ggplot && EVAL_FITS, fig.alt = "Bar chart of cumulative log evidence by ladder rung"----
# library(ggplot2)
# pd <- data.frame(model = factor(names(ll), levels = names(ll)),
#                  rel = ll - ll[1])
# ggplot(pd, aes(model, rel)) +
#   geom_col(width = 0.6, fill = "#3a6ea5") +
#   labs(x = NULL, y = "log evidence vs. null") +
#   theme_minimal() +
#   theme(panel.background = element_rect(fill = "transparent", colour = NA),
#         plot.background  = element_rect(fill = "transparent", colour = NA))

## ----noise-term---------------------------------------------------------------
# dat$w <- rnorm(n)
# m4 <- tulpa(y ~ x + z + w + (1 | g), data = dat, family = "gaussian",
#             mode = "laplace", sigma_re = 0.7, phi = 0.8)
# c(full = round(as.numeric(logLik(m3)), 2),
#   plus_noise = round(as.numeric(logLik(m4)), 2),
#   gain = round(as.numeric(logLik(m4)) - as.numeric(logLik(m3)), 2))

## ----compare------------------------------------------------------------------
# compare_models(intercept = m0, slope = m1,
#                slope_re = m2, full = m3, criterion = "loglik")

## ----binom-ladder-------------------------------------------------------------
# set.seed(101)
# xb  <- rnorm(n); zb <- rnorm(n)
# yb  <- rbinom(n, 1, plogis(-0.4 + 1.1 * xb + 0.9 * zb))
# dfb <- data.frame(y = yb, x = xb, z = zb)
# 
# b0 <- tulpa(y ~ 1,     data = dfb, family = "binomial", mode = "laplace")
# b1 <- tulpa(y ~ x,     data = dfb, family = "binomial", mode = "laplace")
# b2 <- tulpa(y ~ x + z, data = dfb, family = "binomial", mode = "laplace")
# compare_models(intercept = b0, x = b1, xz = b2, criterion = "loglik")

## ----non-nested---------------------------------------------------------------
# mx <- tulpa(y ~ x, data = dat, family = "gaussian",
#             mode = "laplace", phi = 0.8)
# mz <- tulpa(y ~ z, data = dat, family = "gaussian",
#             mode = "laplace", phi = 0.8)
# compare_models(x_only = mx, z_only = mz, criterion = "loglik")

## ----interpret-gap------------------------------------------------------------
# gain <- as.numeric(logLik(b2)) - as.numeric(logLik(b1))
# c(log_evidence_gain = round(gain, 2),
#   evidence_ratio    = round(exp(gain), 1))

## ----bridge-------------------------------------------------------------------
# y_obs   <- 1.5
# log_post <- function(theta)
#   dnorm(y_obs, theta, 1, log = TRUE) + dnorm(theta, 0, 10, log = TRUE)
# post_sd  <- sqrt(100 / 101)
# draws    <- matrix(rnorm(4000, y_obs * 100 / 101, post_sd), ncol = 1)
# bs <- bridge_sampling(draws, log_post)
# c(bridge = round(bs$log_marginal, 3),
#   exact  = round(dnorm(y_obs, 0, sqrt(101), log = TRUE), 3))

## ----glance-one---------------------------------------------------------------
# glance(m3)

## ----glance-stack-------------------------------------------------------------
# do.call(rbind, Map(function(m, nm) cbind(model = nm, glance(m)),
#                    list(m0, m1, m2, m3),
#                    c("intercept", "slope", "slope_re", "full")))

## ----tidy-winner--------------------------------------------------------------
# tidy(m3)

## ----waic-needs, error = TRUE-------------------------------------------------
try({
# loo::waic(b2)
})

## ----model-average------------------------------------------------------------
# ma <- model_average(slope = m1, slope_re = m2, full = m3,
#                     weights = "waic")
# ma$weights
# head(round(ma$averaged, 3))

