ComputeBayesPosterior <- function(mean_obs, se_obs, prior_mean, prior_sd, alpha) {
 # Computes parameters for Bayesian posterior distribution resulting from a Normal-Normal model.
 # Note that the squared estimated standard error is used as the "known" variance.
 # Args:
 # * mean_obs: parameter estimate from data, where estimator is assumed to be Normal
 # * se_obs: estimated standard error of estimator
 # * prior_mean: mean of Normal prior distribution for parameter
 # * prior_sd: standard deviation of Normal prior distribution for parameter
 # * alpha: number in (0, 1) such that credible interval covers 100(1 - alpha)% of posterior
 # Output: list containing
 # * post_mean: the mean of the posterior Normal distribution
 # * post_sd: the standard deviation of the posterior Normal distribution
 # * cred_int: the 100(1 - alpha)% Bayesian posterior credible interval

 post_sd <- sqrt(1 / (1/se_obs^2 + 1/prior_sd^2))
 post_mean <- post_sd^2 * (prior_mean/prior_sd^2 + mean_obs/se_obs^2)

 z_alpha <- qnorm(1 - alpha / 2)
 cred_int <- c(post_mean - z_alpha * post_sd, post_mean + z_alpha * post_sd)

 return(list(post_mean = post_mean, post_sd = post_sd, cred_int = cred_int))
}

ComputeBAE <- function(mean_obs, se_obs, prior_sd, sign, alpha) {
 # Given observed data and a prior sd, computes the prior mean required in order to
 # achieve a 100(1 - alpha)% credible interval with an endpoint of 0.
 # Args:
 # * mean_obs: parameter estimate from data, where estimator is assumed to be Normal
 # * se_obs: standard error of estimator
 # * prior_sd: standard deviation of Normal prior distribution for parameter
 # * sign: +/-1, indicating whether to seach for a lower or upper credible interval bound of 0
 # * alpha: number in (0, 1) such that credible interval covers 100(1 - alpha)% of posterior
 # Output: prior mean that would result in credible interval with one endpoint at 0

 z_alpha <- qnorm(1 - alpha / 2)

 if (sign == 1) {
   # positive parameter => what is the smallest prior mean will result in lower credible interval bound of 0?
   # thus, prior means in (root, Inf) will result in credible interval that excludes zero in favour of positive parameter
   prior_mean_needed <- uniroot(function(x) {
    post <- ComputeBayesPosterior(mean_obs, se_obs, x, prior_sd)
    post$post_mean - z_alpha * post$post_sd
   }, interval = c(-1e6, 1e6))$root
 } else if (sign == -1) {
   # negative parameter => what is the least negative prior mean will result in an upper credible interval bound of 0?
   # thus, prior means in (-Inf, root) will result in credible interval that excludes zero in favour of negative parameter
   prior_mean_needed <- uniroot(function(x) {
   post <- ComputeBayesPosterior(mean_obs, se_obs, x, prior_sd)
   post$post_mean + z_alpha * post$post_sd
   }, interval = c(-1e6, 1e6))$root
 }
 return(prior_mean_needed)
}
