#' 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 }