R/Beta.R

Defines functions Beta

Documented in Beta

#' (Weighted) MLE of Beta Distribution
#' 
#' Beta distribution is characterized by the following probability density function,
#' \deqn{f(x;\alpha,\beta) = \frac{1}{B(\alpha,\beta)} x^{\alpha - 1} (1-x)^{\beta-1}}
#' where the domain is \eqn{x \in [0,1]} with two shape parameters \eqn{\alpha} and \eqn{\beta}. \eqn{B(\alpha,\beta)} is beta function.
#' 
#' @param x a length-\eqn{n} vector of values in \eqn{[0,1]}.
#' @param weight a length-\eqn{n} weight vector. If set as \code{NULL}, it gives an equal weight, leading to standard MLE.
#' 
#' @return a named list containing (weighted) MLE of \describe{
#' \item{alpha}{shape parameter \eqn{\alpha}.}
#' \item{beta}{shape parameter \eqn{\beta}.}
#' }
#' 
#' @examples
#' ## Beta(1,1) = Unif(0,1) : Can we find it ?
#' #  generate data
#' x = stats::runif(100)
#' 
#' #  fit unweighted
#' Beta(x)
#' 
#' \dontrun{
#' # put random weights to see effect of weights
#' niter = 1000
#' ndata = 200
#' 
#' # generate data as above and fit unweighted MLE
#' x    = stats::runif(ndata)
#' xmle = Beta(x)
#' 
#' # iterate
#' vec.alpha = rep(0,niter)
#' vec.beta  = rep(0,niter)
#' for (i in 1:niter){
#'   # random weight
#'   ww = abs(stats::rnorm(ndata))
#' 
#'   MLE = Beta(x, weight=ww)
#'   vec.alpha[i] = MLE$alpha
#'   vec.beta[i]  = MLE$beta
#'   if ((i%%10) == 0){
#'     print(paste0(" iteration ",i,"/",niter," complete.."))
#'   }
#' }
#' 
#' # distribution of weighted estimates + standard MLE
#' opar <- par(no.readonly=TRUE)
#' par(mfrow=c(1,2))
#' hist(vec.alpha, main="shape 'alpha'")
#' abline(v=xmle$alpha, lwd=2, col="red")
#' hist(vec.beta,  main="shape 'beta'")
#' abline(v=xmle$beta, lwd=2, col="blue")
#' par(opar)
#' } 
#' 
#' @author Kisung You
#' @export
Beta <- function(x, weight=NULL){
  #############################################
  # Preprocessing
  # inputs
  x = handle_cts_bdd("Beta", x, lower=0, upper=1, include.boundary = TRUE)
  nx = length(x)
  weight = handle_weight("Beta", weight, nx)

  # other variables
  maceps  = 10*.Machine$double.eps

  #############################################
  # Optimize : DEoptim
  fopt.Beta <- function(pars){
    a = pars[1]
    b = pars[2]
    
    loglkd = (a-1)*log(x) + (b-1)*log(1-x) - lbeta(a,b)
    return(-sum(loglkd*weight))
  }
  sol = DEoptim::DEoptim(fopt.Beta, lower=c(maceps, maceps), upper=rep(1e+5,2), 
                         control=DEoptim::DEoptim.control(trace=FALSE))$optim$bestmem
  
  #############################################
  # Return
  output = list()
  output$alpha = as.double(sol[1])
  output$beta  = as.double(sol[2])
  return(output)
}

# # # personal example
# n = 1000
# x = runif(n)
# weight = rep(1, n)
# maceps  = .Machine$double.eps
kyoustat/T4mle documentation built on March 26, 2020, 12:09 a.m.