R/dWALD.R

Defines functions rWALD qWALD pWALD dWALD

Documented in dWALD pWALD qWALD rWALD

#' The Wald distribution
#'
#' @author Sofia Cuartas, \email{scuartasg@unal.edu.co}
#'
#' @description
#' These functions define the density, distribution function, quantile
#' function and random generation for the Wald distribution
#' with parameter \eqn{\mu} and \eqn{\sigma}.
#'
#' @param x,q vector of (non-negative integer) quantiles.
#' @param p vector of probabilities.
#' @param mu vector of the mu parameter.
#' @param sigma vector of the sigma parameter.
#' @param n number of random values to return.
#' @param log,log.p logical; if TRUE, probabilities p are given as log(p).
#' @param lower.tail logical; if TRUE (default), probabilities are 
#' P[X <= x], otherwise, P[X > x].
#' 
#' @seealso \link{WALD}
#'
#' @references
#' Heathcote, A. (2004). Fitting Wald and ex-Wald distributions to 
#' response time data: An example using functions for the S-PLUS package. 
#' Behavior Research Methods, Instruments, & Computers, 36, 678-694.
#'
#' @seealso \link{WALD}.
#'
#' @details
#' The Wald distribution with parameters \eqn{\mu} and \eqn{\sigma} has density given by
#'
#' \eqn{f(x |\mu, \sigma)=\frac{\sigma}{\sqrt{2 \pi x^3}} \exp \left[-\frac{(\sigma-\mu x)^2}{2x}\right ],}
#' 
#' for \eqn{x < 0}.
#'
#' @return
#' \code{dWALD} gives the density, \code{pWALD} gives the distribution
#' function, \code{qWALD} gives the quantile function, \code{rWALD}
#' generates random deviates.
#'
#' @example  examples/examples_dWALD.R
#'
#' @export
dWALD <- function(x, mu, sigma, log=FALSE) {
  if (any(x <= -1e-15)) stop(paste("x must be positive", "\n", ""))
  if (any(mu <= 0))     stop(paste("mu must  be positive 0", "\n", ""))
  if (any(sigma <= 0))  stop(paste("sigma must be positive", "\n", ""))
  
  res <- log(sigma) - 0.5*log(2*pi) - 1.5*log(x) - (sigma-mu*x)^2/(2*x)
  
  if(log == FALSE)
    return(exp(res))
  else
    return(res)
}
#' @export
#' @rdname dWALD
#' @importFrom stats pnorm
pWALD <- function(q, mu , sigma, lower.tail = TRUE, log.p = FALSE){
  if (any(q <= -1e-15)) stop(paste("q must be positive", "\n", ""))
  if (any(mu <= 0))     stop(paste("mu must  be positive", "\n", ""))
  if (any(sigma <= 0))  stop(paste("sigma must be positive", "\n", ""))
  sqrtq <- sqrt(q)
  k1 <- (mu*q-sigma)/sqrtq
  k2 <- (mu*q+sigma)/sqrtq
  p1 <- exp(2*sigma*mu)
  p2 <- pnorm(-k2)
  bad <- (p1==Inf) | (p2==0)
  p <- p1*p2
  p[bad] <- (exp(-(k1[bad]^2)/2 - 0.94/(k2[bad]^2))/(k2[bad]*((2*pi)^.5)))
  cdf <- p + pnorm(k1)
  if (lower.tail == TRUE) {
    cdf <- cdf
  }
  else {
    cdf <- 1 - cdf
  }
  if (log.p == FALSE){
    cdf <- cdf}
  else {cdf <- log(cdf)}
  return(cdf)
}
#' @export
#' @rdname dWALD
qWALD <- function(p, mu, sigma, lower.tail=TRUE, log.p=FALSE){
  if (any(mu <= 0))    stop(paste("mu must  be positive 0", "\n", ""))
  if (any(sigma <= 0)) stop(paste("sigma must be positive", "\n", ""))
  
  if (log.p == TRUE) p <- exp(p)
  else p <- p
  if (lower.tail == TRUE) p <- p
  else p <- 1 - p
  
  if (any(p < 0) | any(p > 1))  stop(paste("p must be between 0 and 1", "\n", ""))
  
  F.inv <- function(y, mu, sigma, nu) {
    uniroot(function(x) {pWALD(x,mu,sigma) - y},
            interval=c(0, 99999))$root
  }
  F.inv <- Vectorize(F.inv)
  F.inv(p, mu, sigma)
}
#' @export
#' @rdname dWALD
#' @importFrom stats rchisq
rWALD <- function(n, mu, sigma){
  if (any(n <= 0))     stop(paste("n must be positive","\n",""))
  if (any(mu <= 0))    stop(paste("mu must  be positive 0", "\n", ""))
  if (any(sigma <= 0)) stop(paste("sigma must be positive", "\n", ""))
  y2 <- rchisq(n, 1)
  y2onm <- y2/mu
  u <- runif(n)
  r1 <- (2*sigma + y2onm - sqrt(y2onm*(4*sigma+y2onm)))/(2*mu)
  r2 <- (sigma/mu)^2/r1
  r <- ifelse(u < sigma/(sigma+mu*r1), r1, r2)
  r
}
ousuga/RelDists documentation built on July 4, 2025, 10:55 a.m.