pchisqsum<-function(x,df,a,lower.tail=TRUE,
method=c("satterthwaite","integration","saddlepoint")){
satterthwaite<-function(a,df){
if(any(df>1)){
a<-rep(a,df)
}
tr<-mean(a)
tr2<-mean(a^2)/(tr^2)
list(scale=tr*tr2, df=length(a)/tr2)
}
## chisqphi<-function(t, df=1,a=1){
## (1-(0+2i)*a*t)^(-df/2)
## }
## make.integrand<-function(x,DF,A){
## m<-length(DF)
## function(t){
## n<-length(t)
## tmp<-matrix(chisqphi(rep(t,each=m),rep(DF,n),rep(A,n) ),ncol=n)
## phi<-apply(tmp,2,prod)
## rval<-Im(phi*exp(-(0+1i)*t*x)/(pi*t))
## rval[t==0]<-x/(pi)
## rval
## }
## }
method<-match.arg(method)
sat<-satterthwaite(a,df)
guess<-pchisq(x/sat$scale,sat$df,lower.tail=lower.tail)
if (method=="satterthwaite")
return(guess)
method<-match.arg(method)
if (method=="integration" && !(requireNamespace("CompQuadForm",quietly=TRUE))){
warning("Package 'CompQuadForm' not found, using saddlepoint approximation")
method<-"saddlepoint"
}
abstol<-guess/1000
abstol<-pmax(1e-9, abstol)
reltol<-rep(1/1000,length(abstol))
if (method=="integration"){
if (any(a<=0)){
for(i in seq(length=length(x))){
f<-CompQuadForm::davies(x[i],a,df,acc=1e-7)
if (f$ifault>0) warning("Probable loss of accuracy ")
guess[i]<-f$Qq
}
if(any(guess<1e-6)) warning("Probable loss of accuracy ")
} else{
for(i in seq(length=length(x))){
## version 1.4.2 of CompQuadForm changed the *name* of the result. Grr.
temp<-CompQuadForm::farebrother(x[i],a,df)
guess[i]<-if ("Qq" %in% names(temp)) temp$Qq else temp$res
}
if(any(guess<1e-9)) warning("Probable loss of accuracy ")
}
if (lower.tail)
guess<-1-guess
return(guess)
} else if (method=="saddlepoint"){
lambda<-rep(a,df)
sad<-sapply(x,saddle,lambda=lambda)
if (lower.tail) sad<-1-sad
guess<-ifelse(is.na(sad),guess,sad)
return(guess)
}
}
saddle<-function(x,lambda){
d<-max(lambda)
lambda<-lambda/d
x<-x/d
k0<-function(zeta) -sum(log(1-2*zeta*lambda))/2
kprime0<-function(zeta) sapply(zeta, function(zz) sum(lambda/(1-2*zz*lambda)))
kpprime0<-function(zeta) 2*sum(lambda^2/(1-2*zeta*lambda)^2)
n<-length(lambda)
if (any(lambda < 0)) {
lmin <- max(1/(2 * lambda[lambda < 0])) * 0.99999
} else if (x>sum(lambda)){
lmin <- -0.01
} else {
lmin<- -length(lambda)/(2*x)
}
lmax<-min(1/(2*lambda[lambda>0]))*0.99999
hatzeta <- uniroot(function(zeta) kprime0(zeta) - x,
lower = lmin, upper = lmax, tol = 1e-08)$root
w<-sign(hatzeta)*sqrt(2*(hatzeta*x-k0(hatzeta)))
v<-hatzeta*sqrt(kpprime0(hatzeta))
if (abs(hatzeta)<1e-4)
NA
else
pnorm(w+log(v/w)/w, lower.tail=FALSE)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.