# ============================================================
# KRONX :: emissions.R
# Emission log-density functions for Gaussian and Student-t HMMs.
# ============================================================

# Gaussian log-density N(mu, sigma^2) evaluated at each element of x.
log_dnorm_vec <- function(x, mu, sigma) {
  stats::dnorm(x, mean = mu, sd = sigma, log = TRUE)
}

# Location-scale Student-t log-density.
# If Z ~ t_{nu}, then X = mu + sigma * Z.
# log f(x) = log t_{nu}((x - mu)/sigma) - log(sigma).
log_dt_locscale_vec <- function(x, mu, sigma, nu) {
  stats::dt((x - mu) / sigma, df = nu, log = TRUE) - log(sigma)
}

# Build the T x K matrix of emission log-densities.
# Each column k corresponds to hidden state k.
emission_logdens_matrix <- function(x, params, model = c("gaussian", "student")) {
  model <- match.arg(model)
  Tn    <- length(x)
  K     <- length(params$mu)
  B     <- matrix(NA_real_, nrow = Tn, ncol = K)

  for (k in seq_len(K)) {
    if (model == "gaussian") {
      B[, k] <- log_dnorm_vec(x, params$mu[k], params$sigma[k])
    } else {
      B[, k] <- log_dt_locscale_vec(x, params$mu[k], params$sigma[k], params$nu[k])
    }
  }
  B
}
