R/Dagum.R

Defines functions Dagum

Documented in Dagum

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