R/ShiftedGompertz.R

Defines functions ShiftedGompertz

Documented in ShiftedGompertz

#' (Weighted) MLE of Shifted Gompertz Distribution
#' 
#' Shifted Gompertz distribution is characterized by the following probability density function,
#' \deqn{f(x;b,\eta) = b \exp(-bx) \exp(-\eta \exp(-bx)) \left( 1 + \eta(1-\exp(-bx)) \right)}
#' where the domain is \eqn{x \in [0,\infty)} with two parameters 
#' \eqn{b \geq 0} for scale and \eqn{\eta \geq 0} for shape.
#' 
#' @param x a length-\eqn{n} vector of values in \eqn{[0,\infty)}.
#' @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{b}{scale parameter \eqn{b}.}
#' \item{eta}{shape parameter \eqn{\eta}.}
#' }
#' 
#' @examples
#' #  generate data from half normal
#' x = abs(stats::rnorm(100))
#' 
#' #  fit unweighted
#' ShiftedGompertz(x)
#' 
#' \dontrun{
#' # put random weights to see effect of weights
#' niter = 500
#' ndata = 200
#' 
#' # generate data as above and fit unweighted MLE
#' x    = abs(stats::rnorm(ndata))
#' xmle = ShiftedGompertz(x)
#' 
#' # iterate
#' vec.b   = rep(0,niter)
#' vec.eta = rep(0,niter)
#' for (i in 1:niter){
#'   # random weight
#'   ww = abs(stats::rnorm(ndata))
#' 
#'   MLE = ShiftedGompertz(x, weight=ww)
#'   vec.b[i]   = MLE$b
#'   vec.eta[i] = MLE$eta
#'   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.b, main="scale 'b'")
#' abline(v=xmle$b, lwd=3, col="red")
#' hist(vec.eta,  main="shape 'eta'")
#' abline(v=xmle$eta,  lwd=3, col="blue")
#' par(opar)
#' } 
#' 
#' @author Kisung You
#' @export
ShiftedGompertz <- function(x, weight=NULL){
  #############################################
  # Preprocessing
  # inputs
  x      = handle_cts_nonneg("ShiftedGompertz", x) # nonnegative real numbers
  nx     = length(x)
  weight = handle_weight("ShiftedGompertz", weight, nx)
  maceps = 10*.Machine$double.eps
  
  #############################################
  # Optimize : DEoptim
  fopt.SGompertz <- function(pars){
    # parameters
    b = pars[1]
    eta = pars[2]
    # log-likdlihood
    term1 = log(b)
    term2 = -b*x
    term3 = -eta*exp(-b*x)
    term4 = log(1 + eta*(1-exp(-b*x)))
    loglkd = term1+term2+term3+term4
    # return
    return(-sum(loglkd*weight))
  }
  sol = DEoptim::DEoptim(fopt.SGompertz, lower=c(maceps, maceps), upper=c(1e+5,1e+5), 
                         control=DEoptim::DEoptim.control(trace=FALSE))$optim$bestmem
  
  #############################################
  # Return
  output = list()
  output$b    = as.double(sol[1])
  output$eta  = as.double(sol[2])
  return(output)
}
kyoustat/T4mle documentation built on March 26, 2020, 12:09 a.m.