#' @rdname skewn
#'
#' @name Skew-Normal Distribution
#'
#' @title Density function, distribution function, quantiles and random number generation for the skew normal (SN) and the extended skew-normal (ESN) distribution.
#'
#' @param x vector of quantiles. Missing values (NA’s) andInf’s are allowed.
#' @param p vector of probabilities. Missing values (NAs) are allowed
#' @param xi vector of location parameters.
#' @param omega vector of scale parameters; must be positive
#' @param alpha vector of slant parameter(s);+/- Infis allowed. Withpsn, it must be of length 1 ifengine="T.Owen". With qsn, it must be of length 1
#' @param tau a single value representing the ‘hidden mean’ parameter of theESNdistribution; tau=0 (default) corresponds to a SN distribution.
#' @param dp a vector of length 3 (in the SN case) or 4 (in the ESN case), whose components represent the individual parameters described above. If dp is specified, the individual parameters cannot be set.
#' @param n a positive integer representing the sample size.
#' @param tol a scalar value which regulates the accuracy of the result of qsn, measured on the probability scale.
#' @param log logical flag used in dsn (defaul tFALSE). When TRUE, the logarithm of the density values is returned.
#' @param engine a character string which selects the computing engine; this is either "T.Owen" or "biv.nt.prob", the latter from package mnormt. If tau != 0 or length(alpha)>1, "biv.nt.prob" must be used.
#' If this argument is missing, a default selection rule is applied.
#' @param solver a character string which selects the numerical method used for solving the quan-tile equation; possible options are "NR" (default) and "RFB", described in the ‘Details’ section
#' @param ... additional parameters passed to T.Owen
#'
#' @return density (dsn), probability (psn), quantile (qsn) or random sample (rsn) from the skew-normal dis-tribution with given xi,omega and alpha parameters or from the extended skew-normal if tau!=0
#'
#' @details
#'
#' psn and qsn make use of function T.Owen or biv.nt.prob
#'
#' In qsn, the choice solver="NR" selects the Newton-Raphson method for solving the quantile equation, while optionsolver="RFB" alternates a step of regula falsi with one of bisection.
#' The "NR" method is generally more efficient, but "RFB" is occasionally required in some problematic cases.
#'
#' @export
#'
#' @references Azzalini, A. (1985). A class of distributions which includes the normal ones.Scand. J. Statist.12,171-178.
#'
#' Azzalini, A. with the collaboration of Capitanio, A. (2014).The Skew-Normal and Related Families.Cambridge University Press, IMS Monographs series.
#'
#' @examples
#'
#' pdf <- dsn(seq(-3, 3, by=0.1), alpha=3)
#' cdf <- psn(seq(-3, 3, by=0.1), alpha=3)
#' q <- qsn(seq(0.1, 0.9, by=0.1), alpha=-2)
#' r <- rsn(100, 5, 2, 5)
#' qsn(1/10^(1:4), 0, 1, 5, 3, solver="RFB")
#'
dsn = function(x, xi=0, omega=1, alpha=0, tau=0, dp=NULL, log=FALSE)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both 'dp' and component parameters")
xi = dp[1]
omega = dp[2]
alpha = dp[3]
tau = if(length(dp)>3) dp[4] else 0
}
z = (x-xi)/omega
logN = (-log(sqrt(2*pi)) -logb(omega) -z^2/2)
if(abs(alpha) < Inf)
logS = pnorm(tau * sqrt(1+alpha^2) + alpha*z, log.p=TRUE)
else
logS = log(as.numeric(sign(alpha)*z + tau > 0))
logPDF = as.numeric(logN + logS - pnorm(tau, log.p=TRUE))
logPDF = replace(logPDF, abs(x) == Inf, -Inf)
logPDF = replace(logPDF, omega <= 0, NaN)
if(log) logPDF else exp(logPDF)
}
#' @rdname skewn
#'
#' @export
#'
psn = function(x, xi=0, omega=1, alpha=0, tau=0, dp=NULL, engine, ...)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both 'dp' and component parameters")
xi = dp[1]
omega = dp[2]
alpha = dp[3]
tau = if(length(dp)>3) dp[4] else 0L
}
z = as.numeric((x-xi)/omega)
nz = length(z)
na = length(alpha)
if(missing(engine)) engine =
if(na == 1 & nz > 3 & all(alpha*z > -5) & (tau == 0L))
"T.Owen" else "biv.nt.prob"
if(engine == "T.Owen") {
if(tau != 0 | na > 1)
stop("engine='T.Owen' not compatible with other arguments")
p = pnorm(z) - 2 * T.Owen(z, alpha, ...)
}
else{ # engine="biv.nt.prob"
p = numeric(nz)
alpha = cbind(z, alpha)[,2]
delta = delta.etc(alpha)
p.tau = pnorm(tau)
for(k in seq_len(nz)) {
if(abs(alpha[k]) == Inf){
p[k] = if(alpha[k] > 0)
(pnorm(pmax(z[k],-tau)) - pnorm(-tau))/p.tau
else
1- (pnorm(tau) - pnorm(pmin(z[k], tau)))/p.tau
}
else { # SNbook: formula (2.48), p.40
R = matrix(c(1, -delta[k], -delta[k], 1), 2, 2)
p[k]= mnormt::biv.nt.prob(0, rep(-Inf,2), c(z[k], tau), c(0, 0), R)/p.tau
}
}}
p = pmin(1, pmax(0, as.numeric(p)))
replace(p, omega <= 0, NaN)
}
#' @rdname skewn
#'
#' @export
#'
qsn = function(p, xi = 0, omega = 1, alpha = 0, tau=0, dp=NULL, tol = 1e-08,
solver="NR", ...)
{ if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both 'dp' and component parameters")
xi = dp[1]
omega = dp[2]
alpha = dp[3]
tau = if(length(dp) > 3) dp[4] else 0
}
max.q = sqrt(qchisq(p,1)) + tau
min.q = -sqrt(qchisq(1-p,1)) + tau
if(tau == 0) {
if(alpha == Inf) return(as.numeric(xi + omega * max.q))
if(alpha == -Inf) return(as.numeric(xi + omega * min.q))
}
na = is.na(p) | (p < 0) | (p > 1)
zero = (p == 0)
one = (p == 1)
p = replace(p, (na | zero | one), 0.5)
dp0 = c(0, 1, alpha, tau)
if(solver == "NR") {
dp0 = c(0, 1, alpha, tau)
cum = sn.cumulants(dp=dp0, n=4)
g1 = cum[3]/cum[2]^(3/2)
g2 = cum[4]/cum[2]^2
x = qnorm(p)
x = (x + (x^2 - 1) * g1/6 + x * (x^2 - 3) * g2/24 -
x * (2 * x^2 - 5) * g1^2/36)
x = cum[1] + sqrt(cum[2]) * x
px = psn(x, dp=dp0, ...)
max.err = 1
while (max.err > tol) { # cat("qsn:", x, "\n")
# cat('x, px:', format(c(x,px)),"\n")
x1 = x - (px - p)/dsn(x, dp=dp0)
# x1 = pmin(x1,max.q)
# x1 = pmax(x1,min.q)
x = x1
px = psn(x, dp=dp0, ...)
max.err = max(abs(px-p))
if(is.na(max.err)) stop('failed convergence, try with solver="RFB"')
}
x = replace(x, na, NA)
x = replace(x, zero, -Inf)
x = replace(x, one, Inf)
q = as.numeric(xi + omega * x)
} else { if(solver == "RFB") {
abs.alpha = abs(alpha)
if(alpha < 0) p = (1-p)
x = xa = xb = xc = fa = fb = fc = rep(NA, length(p))
nc = rep(TRUE, length(p)) # not converged (yet)
nc[(na| zero| one)] = FALSE
fc[!nc] = 0
xa[nc] = qnorm(p[nc])
xb[nc] = sqrt(qchisq(p[nc], 1)) + abs(tau)
fa[nc] = psn(xa[nc], 0, 1, abs.alpha, tau, ...) - p[nc]
fb[nc] = psn(xb[nc], 0, 1, abs.alpha, tau, ...) - p[nc]
regula.falsi = FALSE
while (sum(nc) > 0) { # alternate regula falsi/bisection
xc[nc] = if(regula.falsi)
xb[nc] - fb[nc] * (xb[nc] - xa[nc])/(fb[nc] - fa[nc]) else
(xb[nc] + xa[nc])/2
fc[nc] = psn(xc[nc], 0, 1, abs.alpha, tau, ...) - p[nc]
pos = (fc[nc] > 0)
xa[nc][!pos] = xc[nc][!pos]
fa[nc][!pos] = fc[nc][!pos]
xb[nc][pos] = xc[nc][pos]
fb[nc][pos] = fc[nc][pos]
x[nc] = xc[nc]
nc[(abs(fc) < tol)] = FALSE
regula.falsi = !regula.falsi
}
# x = replace(x, na, NA)
x = replace(x, zero, -Inf)
x = replace(x, one, Inf)
Sign = function(x) sign(x) + as.numeric(x==0)
q = as.numeric(xi + omega * Sign(alpha)* x)
} else stop("unknown solver")}
names(q) = names(p)
return(q)
}
#' @rdname skewn
#'
#' @export
#'
rsn = function(n=1, xi=0, omega=1, alpha=0, tau=0, dp=NULL)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both 'dp' and component parameters")
xi = uname(dp[1])
omega = unname(dp[2])
alpha = unname(dp[3])
tau = if(length(dp)>3) dp[4] else 0
}
if(tau == 0) {
u1 = rnorm(n)
u2 = rnorm(n)
id = (u2 > alpha*u1)
u1[id] = (-u1[id])
z = u1
}
else { # for ESN use transformation method
delta = alpha/sqrt(1+alpha^2)
truncN = qnorm(runif(n, min=pnorm(-tau), max=1))
z = delta * truncN + sqrt(1-delta^2) * rnorm(n)
}
y = xi+omega*z
return(y)
}
#' @rdname skewt
#'
#' @name Skew-t Distribution
#'
#' @title Density function, distribution function, quantiles and random number generation for the skew-t (ST) distribution
#'
#' @param x vector of quantiles. Missing values (NAs) are allowed.
#' @param p vector of probabililities
#' @param xi vector of location parameters.
#' @param omega vector of scale parameters; must be positive.
#' @param alpha vector of slant parameters. Withpstandqst, it must be of length 1.
#' @param nu a single positive value representing the degrees of freedom; it can be non-integer. Default value isnu=Infwhich corresponds to the skew-normal distribution.
#' @param dp a vector of length 4, whose elements represent location, scale (positive), slant and degrees of freedom, respectively. Ifdpis specified, the individual parameters cannot be set.
#' @param n a positive integer representing the sample size.
#' @param log logical; if TRUE, densities are given as log-densities
#' @param tol a scalar value which regulates the accuracy of the result of qsn, measured on the probability scale.
#' @param method an integer value between 0 and 4 which selects the computing method; see ‘Details’ below for the meaning of these values. If method=0 (default value), an automatic choice is
#' made among the four actual computing methods, which depends on the other arguments.
#' @param ... aditional parameters passed tointegrateor pst
#'
#' @return Density (dst), probability (pst), quantiles (qst) and random sample (rst) from the skew-t distribution with given xi, omega, alpha and nu parameters.
#'
#' @details For evaluation of pst, and so indirectly of qst, four different methods are employed. Method 1 consists in using pmst with dimensiond=1. Method 2 applies integrate to the density function dst.
#' Method 3 again uses integrate too but with a different integrand, as given in Section 4.2 of Azzalini & Capitanio (2003), full version of the paper. Method 4 consists in the recursive procedure of
#' Jamalizadeh, Khosravi and Balakrishnan (2009), which is recalled in Complement 4.3 on Azza-lini & Capitanio (2014); the recursion over nu starts from the explicit expression fornu=1 given by psc.
#' Of these, Method 1 and 4 are only suitable for integer values of nu. Method 4 becomes pro-gressively less efficient as nu increases, because its value corresponds to the number of nested calls,
#' but the decay of efficiency is slower for larger values oflength(x). If the default argument value method=0 is retained, an automatic choice among the above four methods is made, which dependson
#' the values of nu, alpha, length(x). The numerical accuracy of methods 1, 2 and 3 can be regulated via the ... argument, while method 4 is conceptually exact, up to machine precision.
#'
#' If qst is called withnu>1e4, computation is transferred to qsn.
#'
#' @references Azzalini, A. and Capitanio, A. (2003). Distributions generated by perturbation of symmetry with emphasis on a multivariate skew-tdistribution.J.Roy. Statist. Soc. B65, 367–389. Full version of
#' the paper athttp://arXiv.org/abs/0911.2342.
#'
#' Azzalini, A. with the collaboration of Capitanio, A. (2014).The Skew-normal and Related Families. Cambridge University Press, IMS Monographs series.
#'
#' Jamalizadeh, A., Khosravi, M., and Balakrishnan, N. (2009). Recurrence relations for distributions of a skew-$t$ and a linear combination of order statistics from a bivariate-$t$.Comp. Statist. Data An.53, 847–852
#'
#' @export
#'
#' @examples
#'
#' pdf <- dst(seq(-4, 4, by=0.1), alpha=3, nu=5)
#' rnd <- rst(100, 5, 2, -5, 8)
#' q <- qst(c(0.25, 0.50, 0.75), alpha=3, nu=5)
#' pst(q, alpha=3, nu=5) # must give back c(0.25, 0.50, 0.75)
#' p1 <- pst(x=seq(-3,3, by=1), dp=c(0,1,pi, 3.5))
#' p2 <- pst(x=seq(-3,3, by=1), dp=c(0,1,pi, 3.5), method=2, rel.tol=1e-9)
#'
dst = function (x, xi=0, omega=1, alpha=0, nu=Inf, dp=NULL, log=FALSE)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both component parameters and dp")
xi = dp[1]
omega = dp[2]
alpha = dp[3]
nu = dp[4]
}
if (nu == Inf) return(dsn(x, xi, omega, alpha, log=log))
if (nu == 1) return(dsc(x, xi, omega, alpha, log=log))
z = (x - xi)/omega
pdf = dt(z, df=nu, log=log)
cdf = pt(alpha*z*sqrt((nu+1)/(z^2+nu)), df=nu+1, log.p=log)
if(log)
logb(2) + pdf + cdf -logb(omega)
else
2 * pdf * cdf / omega
}
#' @rdname skewt
#'
#' @export
#'
rst = function (n=1, xi = 0, omega = 1, alpha = 0, nu=Inf, dp=NULL)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both component parameters and dp")
xi = unname(dp[1])
omega = unname(dp[2])
alpha = unname(dp[3])
nu = unname(dp[4])
}
z = rsn(n, 0, omega, alpha)
if(nu < Inf) {
v = rchisq(n,nu)/nu
y = z/sqrt(v) + xi
}
else y = z+xi
return(y)
}
#' @rdname skewt
#'
#' @export
#'
pst = function (x, xi=0, omega=1, alpha=0, nu=Inf, dp=NULL, method=0, ...)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both component parameters and dp")
xi = dp[1]
omega = dp[2]
alpha = dp[3]
nu = dp[4]
}
if(length(alpha) > 1) stop("'alpha' must be a single value")
if(length(nu) > 1) stop("'nu' must be a single value")
if (nu <= 0) stop("nu must be non-negative")
if (nu == Inf) return(psn(x, xi, omega, alpha))
if (nu == 1) return(psc(x, xi, omega, alpha))
int.nu = (round(nu) == nu)
if((method == 1 | method ==4) & !int.nu)
stop("selected method does not work for non-integer nu")
ok = !(is.na(x) | (x==Inf) | (x==-Inf))
z = ((x-xi)/omega)[ok]
if(abs(alpha) == Inf) {
z0 = replace(z, alpha*z < 0, 0)
p = pf(z0^2, 1, nu)
return(if(alpha>0) p else (1-p))
}
fp = function(v, alpha, nu, t.value)
psn(sqrt(v) * t.value, 0, 1, alpha) * dchisq(v * nu, nu) * nu
if(method == 4 || (method ==0 && int.nu &&
(nu < (8.2 + 3.55* log(log(length(z)+1))))))
p = pst_int(z, 0, 1, alpha, nu) # "method 4"
else {
p = numeric(length(z))
for (i in seq_len(length(z))) {
if(abs(z[i]) == Inf)
p[i] = (1+sign(z[i]))/2
else {
if(method==1 | method == 0)
p[i] = pmst(z[i], 0, matrix(1,1,1), alpha, nu, ...) # method 1
else {
# upper = if(absalpha> 1) 5/absalpha + 25/(absalpha*nu) else 5+25/nu
upper = 10 + 50/nu
if(method==2 || (method==0 & (z[i] < upper) ))
p[i] = integrate(dst, -Inf, z[i], dp=c(0,1,alpha, nu), ...)$value
# method 2
else
p[i] = integrate(fp, 0, Inf, alpha, nu, z[i], ...)$value
# method 3
}}
}}
pr = rep(NA, length(x))
pr[x==Inf] = 1
pr[x==-Inf] = 0
pr[ok] = p
return(pmax(0,pmin(1,pr)))
}
pst_int = function (x, xi=0, omega=1, alpha=0, nu=Inf)
{# Jamalizadeh, A. and Khosravi, M. and Balakrishnan, N. (2009)
if(nu != round(nu) | nu < 1) stop("nu not integer or not positive")
z = (x-xi)/omega
if(nu == 1)
atan(z)/pi + acos(alpha/sqrt((1+alpha^2)*(1+z^2)))/pi
else { if(nu==2)
0.5 - atan(alpha)/pi + (0.5 + atan(z*alpha/sqrt(2+z^2))/pi)*z/sqrt(2+z^2)
else
(pst_int(sqrt((nu-2)/nu)*z, 0, 1, alpha, nu-2) +
pst_int(sqrt(nu-1)*alpha*z/sqrt(nu+z^2), 0, 1, 0, nu-1) * z *
exp(lgamma((nu-1)/2) +(nu/2-1)*log(nu)-0.5*log(pi)-lgamma(nu/2)
-0.5*(nu-1)*log(nu+z^2)))
}
}
#' @rdname skewt
#'
#' @export
#'
qst = function (p, xi = 0, omega = 1, alpha = 0, nu=Inf, tol = 1e-8,
dp = NULL, method=0, ...)
{
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both component parameters and dp")
xi = dp[1]
omega = dp[2]
alpha = dp[3]
nu = dp[4]
}
if(length(alpha) > 1) stop("'alpha' must be a single value")
if(length(nu) > 1) stop("'nu' must be a single value")
if (nu <= 0) stop("nu must be non-negative")
if (nu > 1e4) return(qsn(p, xi, omega, alpha))
if (nu == 1) return(qsc(p, xi, omega, alpha))
if (alpha == Inf)
return(xi + omega * sqrt(qf(p, 1, nu)))
if (alpha == -Inf)
return(xi - omega * sqrt(qf(1 - p, 1, nu)))
na = is.na(p) | (p < 0) | (p > 1)
abs.alpha = abs(alpha)
if(alpha < 0) p = (1-p)
zero = (p == 0)
one = (p == 1)
x = xa = xb = xc = fa = fb = fc = rep(NA, length(p))
nc = rep(TRUE, length(p)) # not converged (yet)
nc[(na| zero| one)] = FALSE
fc[!nc] = 0
xa[nc] = qt(p[nc], nu)
xb[nc] = sqrt(qf(p[nc], 1, nu))
fa[nc] = pst(xa[nc], 0, 1, abs.alpha, nu, method=method, ...) - p[nc]
fb[nc] = pst(xb[nc], 0, 1, abs.alpha, nu, method=method, ...) - p[nc]
regula.falsi = FALSE
while (sum(nc) > 0) { # alternate regula falsi/bisection
xc[nc] = if(regula.falsi)
xb[nc] - fb[nc] * (xb[nc] - xa[nc])/(fb[nc] - fa[nc]) else
(xb[nc] + xa[nc])/2
fc[nc] = pst(xc[nc], 0, 1, abs.alpha, nu, method=method, ...) - p[nc]
pos = (fc[nc] > 0)
xa[nc][!pos] = xc[nc][!pos]
fa[nc][!pos] = fc[nc][!pos]
xb[nc][pos] = xc[nc][pos]
fb[nc][pos] = fc[nc][pos]
x[nc] = xc[nc]
nc[(abs(fc) < tol)] = FALSE
regula.falsi = !regula.falsi
}
# x = replace(x, na, NA)
x = replace(x, zero, -Inf)
x = replace(x, one, Inf)
Sign = function(x) sign(x) + as.numeric(x==0)
q = as.numeric(xi + omega * Sign(alpha)* x)
names(q) = names(p)
return(q)
}
delta.etc = function(alpha, Omega=NULL)
{
inf = which(abs(alpha) == Inf)
if(is.null(Omega)){ # case d=1
delta = alpha/sqrt(1+alpha^2)
delta[inf] = sign(alpha[inf])
return(delta)
}
else { # d>1
if(any(dim(Omega) != rep(length(alpha),2))) stop("dimension mismatch")
Ocor = cov2cor(Omega)
if(length(inf) == 0) { # d>1, standard case
Ocor.alpha = as.vector(Ocor %*% alpha)
alpha.sq = sum(alpha * Ocor.alpha)
delta = Ocor.alpha/sqrt(1+alpha.sq)
alpha. = sqrt(alpha.sq)
delta. = sqrt(alpha.sq/(1+alpha.sq))
}
else { # d>1, case with some abs(alpha)=Inf
if(length(inf) > 1)
warning("Several abs(alpha)==Inf, I handle them as 'equal-rate Inf'")
k = rep(0,length(alpha))
k[inf] = sign(alpha[inf])
Ocor.k = as.vector(Ocor %*% k)
delta = Ocor.k/sqrt(sum(k * Ocor.k))
delta. = 1
alpha. = Inf
}
return(
list(delta=delta, alpha.star=alpha., delta.star=delta., Omega.cor=Ocor))
}
}
sn.cumulants <- function(xi = 0, omega = 1, alpha = 0, tau=0,
dp=NULL, n=4)
{
cumulants.half.norm <- function(n=4){
n <- max(n,2)
n <- as.integer(2*ceiling(n/2))
half.n <- as.integer(n/2)
m <- 0:(half.n-1)
a <- sqrt(2/pi)/(gamma(m+1)*2^m*(2*m+1))
signs <- rep(c(1, -1), half.n)[seq_len(half.n)]
a <- as.vector(rbind(signs*a, rep(0,half.n)))
coeff <- rep(a[1],n)
for (k in 2:n) {
ind <- seq_len(k-1)
coeff[k] <- a[k] - sum(ind*coeff[ind]*a[rev(ind)]/k)
}
kappa <- coeff*gamma(seq_len(n)+1)
kappa[2] <- 1 + kappa[2]
return(kappa)
}
if(!is.null(dp)) {
if(!missing(alpha))
stop("You cannot set both component parameters and dp")
dp <- c(dp,0)[1:4]
dp <- matrix(dp, 1, ncol=length(dp))
}
else dp <- cbind(xi,omega,alpha,tau)
delta <- ifelse(abs(dp[,3])<Inf, dp[,3]/sqrt(1+dp[,3]^2), sign(dp[,3]))
tau <- dp[,4]
if(all(tau==0)) {
kv <- cumulants.half.norm(n)
if(length(kv)>n) kv <- kv[-(n+1)]
kv[2] <- kv[2] - 1
kappa <- outer(delta,1:n,"^") * matrix(rep(kv,nrow(dp)),ncol=n,byrow=TRUE)
}
else{ # ESN
if(n>4){
warning("n>4 not allowed with ESN distribution")
n <- min(n, 4)
}
kappa <- matrix(0, nrow=length(delta), ncol=0)
for (k in 1:n) kappa <- cbind(kappa, zeta(k,tau)*delta^k)
}
kappa[,2] <- kappa[,2] + 1
kappa <- kappa * outer(dp[,2],(1:n),"^")
kappa[,1] <- kappa[,1] + dp[,1]
kappa[,,drop=TRUE]
}
T.Owen <- function(h, a, jmax=50, cut.point=8)
{
T.int <-function(h, a, jmax, cut.point)
{
fui <- function(h,i) (h^(2*i))/((2^i)*gamma(i+1))
seriesL <- seriesH <- NULL
i <- 0:jmax
low<- (h <= cut.point)
hL <- h[low]
hH <- h[!low]
L <- length(hL)
if (L > 0) {
b <- outer(hL, i, fui)
cumb <- apply(b, 1, cumsum)
b1 <- exp(-0.5*hL^2) * t(cumb)
matr <- matrix(1, jmax+1, L) - t(b1)
jk <- rep(c(1,-1), jmax)[1:(jmax+1)]/(2*i+1)
matr <- t(matr*jk) %*% a^(2*i+1)
seriesL <- (atan(a) - as.vector(matr))/(2*pi)
}
if (length(hH) > 0) seriesH <-
atan(a)*exp(-0.5*(hH^2)*a/atan(a)) * (1+0.00868*(hH*a)^4)/(2*pi)
series <- c(seriesL, seriesH)
id <- c((1:length(h))[low],(1:length(h))[!low])
series[id] <- series # re-sets in original order
series
}
if(!is.vector(a) | length(a)>1) stop("'a' must be a vector of length 1")
if(!is.vector(h)) stop("'h' must be a vector")
aa <- abs(a)
ah <- abs(h)
if(is.na(aa)) stop("parameter 'a' is NA")
if(aa==Inf) return(sign(a)*0.5*pnorm(-ah)) # sign(a): 16.07.2007
if(aa==0) return(rep(0,length(h)))
na <- is.na(h)
inf <- (ah == Inf)
ah <- replace(ah,(na|inf),0)
if(aa <= 1)
owen <- T.int(ah,aa,jmax,cut.point)
else
owen<- (0.5*pnorm(ah) + pnorm(aa*ah)*(0.5-pnorm(ah))
- T.int(aa*ah,(1/aa),jmax,cut.point))
owen <- replace(owen,na,NA)
owen <- replace(owen,inf,0)
return(owen*sign(a))
}
pmst <- function(x, xi=rep(0,length(alpha)), Omega, alpha, nu=Inf, dp=NULL, ...)
{
if(!(missing(alpha) & missing(Omega)) && !is.null(dp))
stop("You cannot set both component parameters and dp")
if(!is.null(dp)){
if(!is.null(dp$xi)) xi <- dp$xi else
if(!is.null(dp$beta)) xi <- as.vector(dp$beta)
Omega <- dp$Omega
alpha <- dp$alpha
nu <- dp$nu
}
if(!is.vector(x)) stop("x must be a vector")
if(any(abs(alpha) == Inf)) stop("Inf's in alpha are not allowed")
if(nu == Inf) return(pmsn(x, xi, Omega, alpha))
d <- length(alpha)
Omega<- matrix(Omega,d,d)
omega<- sqrt(diag(Omega))
Ocor <- cov2cor(Omega)
O.alpha <- as.vector(Ocor %*% alpha)
delta <- O.alpha/sqrt(1 + sum(alpha*O.alpha))
Obig <- matrix(rbind(c(1, -delta), cbind(-delta, Ocor)), d+1, d+1)
if(nu == as.integer(nu)) {
z0 <- c(0,(x-xi)/omega)
if(nu < .Machine$integer.max)
p <- 2 * mnormt::pmt(z0, mean=rep(0,d+1), S=Obig, df=nu, ...)
else
p <- 2 * mnormt::pmnorm(z0, mean=rep(0,d+1), varcov=Obig, ...)
}
else {# for fractional nu, use formula in Azzalini & Capitanio (2003),
# full-length paper, last paragraph of Section 4.2[Distr.function])
z <- (x-xi)/omega
fp <- function(v, Ocor, alpha, nu, t.value) {
pv <- numeric(length(v))
for(k in seq_len(length(v))) pv[k] <- (dchisq(v[k] * nu, nu) * nu *
pmsn(sqrt(v[k]) * t.value, rep(0,d), Ocor, alpha) )
pv}
p <- integrate(fp, 0, Inf, Ocor, alpha, nu, z, ...)$value
}
p
}
pmsn <- function(x, xi=rep(0,length(alpha)), Omega, alpha, tau=0,
dp=NULL, ...)
{
if(!(missing(alpha) & missing(Omega)) && !is.null(dp))
stop("You cannot set both component parameters and dp")
if(!is.null(dp)){
xi <- dp$xi
Omega <- dp$Omega
alpha <- dp$alpha
tau <- if(is.null(dp$tau)) 0 else dp$tau
}
if(any(abs(alpha) == Inf)) stop("Inf's in alpha are not allowed")
d <- length(alpha)
Omega <- matrix(Omega, d, d)
omega <- sqrt(diag(Omega))
delta_etc <- delta.etc(alpha, Omega)
delta <- delta_etc$delta
Ocor <- delta_etc$Omega.cor
Obig <- matrix(rbind(c(1,-delta), cbind(-delta,Ocor)), d+1, d+1)
x <- if (is.vector(x)) matrix(x, 1, d) else data.matrix(x)
if (is.vector(xi)) xi <- outer(rep(1, nrow(x)), as.vector(matrix(xi,1,d)))
z0 <- cbind(tau, t(t(x - xi))/omega)
mnormt::pmnorm(z0, mean=rep(0,d+1), varcov=Obig, ...)/pnorm(tau)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.