67
##' @title tan(pi/2*x), for x in [-1,1] with correct limits
68
##' i.e. tanpi2(-/+ 1) == -/+ Inf
69
##' @param x numeric vector
70
##' @return numeric vector of values tan(pi/2*x)
71
##' @author Martin Maechler
72
tanpi2 <- function(x) {
74
if(any(i <- x & x == round(x)))# excluding 0
75
r[i] <- (2 - (x[i] %% 4))*Inf
77
r[io] <- tan(pi2* x[io])
81
##' @title cos(pi/2*x), for x in [-1,1] with correct limits
82
##' i.e. cospi2(+- 1) == 0
83
##' @param x numeric vector
84
##' @return numeric vector of values cos(pi/2*x)
85
##' @author Martin Maechler
86
cospi2 <- function(x) {
88
if(any(i <- x == round(x)))
89
r[i] <- as.numeric(x[i] == 0)# 1 or 0 - iff x \in [-1,1] !
91
r[io] <- cos(pi2* x[io])
67
95
##' According to Nolan's "tail.pdf" paper, where he takes *derivatives*
68
96
##' of the tail approximation 1-F(x) ~ (1+b) C_a x^{-a} to prove
69
97
##' that f(x) ~ a(1+b) C_a x^{-(1+a)} ...
244
.e.plus <- function(x, eps) x + eps* abs(x)
245
.e.minus<- function(x, eps) x - eps* abs(x)
246
pi2.. <- function(eps) pi2 * (1 - eps) ## == .e.minus(pi/2, eps), slight more efficiently
216
249
.fct1 <- function(x, zeta, alpha, theta0, tol, subdivisions, zeta.tol,
217
250
verbose = getOption("dstable.debug", default=FALSE))
235
268
## zeta <- -beta * tan(pi*alpha/2)
236
269
## theta0 <- (1/alpha) * atan( beta * tan(pi*alpha/2))
237
270
## x.m.zet <- abs(x - zeta)
271
##-------->>> identically as in .FCT1() for pstable() below: <<<-----------
239
273
cat0 <- cos(at0 <- alpha*theta0)
274
##' g() is strictly monotone -- Nolan(1997) ["3. Numerical Considerations"]
275
##' alpha >= 1 <==> g() is falling, ie. from Inf --> 0; otherwise growing from 0 to +Inf
241
276
g <- function(th) {
243
278
## g(-pi/2) or g(pi/2) could become NaN --> work around
244
i.bnd <- abs(pi/2 -sign(a_1)*th) < 64*.Machine$double.eps
279
i.bnd <- abs(pi2 -sign(a_1)*th) < 64*.Machine$double.eps
246
281
th <- th[io <- !i.bnd]
247
282
att <- at0 + alpha*th ## = alpha*(theta0 + theta)
367
397
##' @param beta 0 < |beta| <= 1
369
399
##' @param subdivisions
370
.fct2 <- function(x, beta, tol, subdivisions)
400
.fct2 <- function(x, beta, tol, subdivisions,
401
verbose = getOption("dstable.debug", default=FALSE))
372
403
i2b <- 1/(2*beta)
373
404
p2b <- pi*i2b # = pi/(2 beta)
374
if(abs(ea <- -p2b*x) > .large.exp.arg) ## ==> g(.) == 0 or == Inf
406
if(is.infinite(ea)) return(0)
377
408
##' g() is strictly monotone;
378
##' for beta > 0: increasing from g(-pi/2) = 0 to g(+pi/2) = Inf
379
##' for beta < 0: decreasing from g(-pi/2) = Inf to g(+pi/2) = 0
381
h <- p2b+ th # == g'/beta where g' := pi/2 + beta*th
382
g.x * (h/p2b) * exp(h*tan(th))/cos(th)
384
t0 <- -sign(beta)*pi2# g(t0) == 0 mathematically, but not always numerically
385
if(is.na(g0 <- g(t0))) { ## numerical problem ==> need more careful version of g()
386
## find a left threshold instead of -pi/2 where g(.) is *not* NA
389
while(is.na(g(lt))) lt <- lt*f
393
r[i <- (beta*(lt - th) > 0)] <- 0
409
##' g(u) := original_g(u*pi/2)
410
##' for beta > 0: increasing from g(-1) = 0 to g(+1) = Inf
411
##' for beta < 0: decreasing from g(-1) = Inf to g(+1) = 0
412
##t0 <- -sign(beta)*pi2# g(t0) == 0 mathematically, but not always numerically
413
u0 <- -sign(beta)# g(u0) == 0 mathematically, but not always numerically
416
r[i <- abs(u-u0) < 1e-10] <- 0
419
h <- p2b+ th # == g'/beta where g' := pi/2 + beta*th = pi/2* (1 + beta*u)
420
r[!i] <- (h/p2b) * exp(ea + h*tanpi2(u)) / cospi2(u)
399
## Function to Integrate; th is a non-sorted vector!
424
## Function to Integrate; u is a non-sorted vector!
401
426
## g2 = g(.) exp(-g(.))
405
430
## We know that the maximum of g2(.) is = exp(-1) = 0.3679 "at" g(.) == 1
406
431
## find that by uniroot :
407
ur <- uniroot(function(th) g(th) - 1, lower = -pi2, upper = pi2, tol = tol)
410
r1 <- .integrate2(g2, lower = -pi2, upper = theta2,
411
subdivisions = subdivisions, rel.tol = tol, abs.tol = tol)
412
r2 <- .integrate2(g2, lower = theta2, upper = pi2,
413
subdivisions = subdivisions, rel.tol = tol, abs.tol = tol)
432
ur <- uniroot(function(u) g(u) - 1, lower = -1, upper = 1, tol = tol)
435
r1 <- .integrate2(g2, lower = -1, upper = u2,
436
subdivisions = subdivisions, rel.tol = tol, abs.tol = tol)
437
r2 <- .integrate2(g2, lower = u2, upper = 1,
438
subdivisions = subdivisions, rel.tol = tol, abs.tol = tol)
442
cat(sprintf(".fct2(%.11g, %.6g,..): c*sum(r1+r2)= %.11g*(%6.4g + %6.4g)= %g\n",
443
x,beta, cc, r1, r2, cc*(r1+r2)))
417
448
### ------------------------------------------------------------------------------
473
504
r <- if(lower.tail) (1/2- theta0/pi) else 1/2+ theta0/pi
474
505
if(log.p) log(r) else r
508
((z > zeta && lower.tail) ||
509
(z < zeta && !lower.tail))
476
510
## FIXME: for alpha > 1 -- the following computes F1 = 1 -c3*r(x)
477
.F1 <- .FCT1(z, zeta, alpha=alpha,
478
theta0= sign(z - zeta)* theta0,
511
## and suffers from cancellation when 1-F1 is used below:
512
giveI <- !useLower && alpha > 1 # if TRUE, .FCT1() return 1-F
513
.F1 <- .FCT1(z, zeta, alpha=alpha, theta0=theta0,
479
515
tol = tol, subdivisions = subdivisions)
480
retValue(.F1, useLower =
481
((z > zeta && lower.tail) ||
482
(z < zeta && !lower.tail)))
517
if(log.p) log(.F1) else .F1
518
else retValue(.F1, useLower=useLower)
486
522
## Special Case alpha == 1 and -1 <= beta <= 1 (but not = 0) :
487
523
else { ## (alpha == 1) and 0 < |beta| <= 1 from above
532
if(giveI <- !useL && !log.p)
488
534
## Loop over all x values:
489
vapply(x, function(z) {
491
retValue(.FCT2( z, beta = beta,
492
tol = tol, subdivisions = subdivisions),
495
retValue(.FCT2(-z, beta = -beta,
496
tol = tol, subdivisions = subdivisions),
535
retValue(vapply(x, function(z)
536
.FCT2(z, beta = beta, tol=tol, subdivisions=subdivisions,
504
544
## ------------------------------------------------------------------------------
506
546
##' Auxiliary for pstable() (for alpha != 1)
507
.FCT1 <- function(x, zeta, alpha, theta0, tol, subdivisions)
547
.FCT1 <- function(x, zeta, alpha, theta0, giveI, tol, subdivisions,
548
verbose = getOption("pstable.debug", default=FALSE))
509
550
if(is.infinite(x))
551
return(if(giveI) 0 else 1)
511
552
x.m.zet <- abs(x - zeta)
512
## identically as in .fct1() for dstable():
553
##-------->>> identically as in .fct1() for dstable() above: <<<-----------
554
if(x < zeta) theta0 <- -theta0
514
557
cat0 <- cos(at0 <- alpha*theta0)
515
## Nolan(1997) shows that g() is montone
516
559
g <- function(th) {
518
561
## g(-pi/2) or g(pi/2) could become NaN --> work around
519
i.bnd <- abs(pi/2 -sign(a_1)*th) < 64*.Machine$double.eps
562
i.bnd <- abs(pi2 -sign(a_1)*th) < 64*.Machine$double.eps
521
564
th <- th[io <- !i.bnd]
522
565
att <- at0 + alpha*th ## = alpha*(theta0 + theta)
527
## as g() is montone, the integrand exp(-g(.)) is too -- so the maximum is at the boundary
570
if(verbose) cat(sprintf(".FCT1(%9g, %10g, th0=%.10g, %s..): ",
571
x,zeta, theta0, if(giveI)"giveI=TRUE," else ""))
573
## as g() is montone, the integrand exp(-g(.)) is too ==> maximum is at the boundary
574
## however, integration can be inaccuracte when g(.) quickly jumps from Inf to 0
575
## _BUT_ empirically I find that good values l.th / u.th below are *INDEPENDENT* of x,
576
l.th <- .e.plus(-theta0, 1e-6)
577
if(alpha > 1 && g(l.th) == Inf) {
578
ur <- uniroot(function(t) 1-2*(g(t)==Inf), lower=l.th, upper=pi2,
579
f.lower= -1, f.upper= 1, tol = 1e-8)
581
if(verbose) cat(sprintf(" g(-th0 +1e-6)=Inf: unirt(%d it) -> l.th=%.10g ",
584
u.th <- .e.minus(pi2, 1e-6)
585
if(alpha < 1 && g(u.th) == Inf) {
586
ur <- uniroot(function(t) 1-2*(g(t)==Inf), lower=l.th, upper=u.th,
587
f.upper= -1, tol = 1e-8)
589
if(verbose) cat(sprintf(" g(pi/2 -1e-6)=Inf: unirt(%d it) -> u.th=%.10g ",
528
592
r <- .integrate2(function(th) exp(-g(th)),
529
lower = -theta0, upper = pi2, subdivisions = subdivisions,
593
lower = l.th, upper = u.th, subdivisions = subdivisions,
530
594
rel.tol = tol, abs.tol = tol)
532
c1 <- if(alpha < 1) 1/2 - theta0/pi else 1
533
c3 <- sign(1-alpha)/pi
534
## = 1 - |.|*r(x) <==> cancellation iff we eventually want 1 - F() -- FIXME
596
if(verbose) cat(sprintf("--> Int r= %.11g\n", r))
597
if(giveI) { ## { ==> alpha > 1 ==> c1 = 1; c3 = -1/pi}
598
## return (1 - F) = 1 - (1 -1/pi * r) = r/pi :
601
c1 <- if(alpha < 1) 1/2 - theta0/pi else 1
602
c3 <- sign(1-alpha)/pi
603
## = 1 - |.|*r(x) <==> cancellation iff we eventually want 1 - F() -- FIXME
538
608
## ------------------------------------------------------------------------------
542
612
##' @param beta >= 0 here
544
614
##' @param subdivisions
545
.FCT2 <- function(x, beta, tol, subdivisions)
615
.FCT2 <- function(x, beta, tol, subdivisions, giveI = FALSE,
616
verbose = getOption("pstable.debug", default=FALSE))
547
618
i2b <- 1/(2*beta)
548
619
p2b <- pi*i2b # = pi/(2 beta)
549
if((ea <- -p2b*x) < -.large.exp.arg) ## ==> g(.) == 0 ==> G2(.) == 1
551
if(ea > .large.exp.arg) ## ==> g(.) == Inf ==> G2(.) == 0
622
return(R.D.Lval(if(ea < 0) ## == -Inf ==> g(.) == 0 ==> G2(.) == 1
623
1 else 0, ## == +Inf ==> g(.) == Inf ==> G2(.) == 0
554
626
##' g() is strictly monotone;
555
##' for beta > 0: increasing from g(-pi/2) = 0 to g(+pi/2) = Inf
556
##' for beta < 0: decreasing from g(-pi/2) = Inf to g(+pi/2) = 0
558
h <- p2b+ th # == g'/beta where g' := pi/2 + beta*th
559
g.x * (h/p2b) * exp(h*tan(th))/cos(th)
627
##' g(u) := original_g(u*pi/2)
628
##' for beta > 0: increasing from g(-1) = 0 to g(+1) = Inf
629
##' for beta < 0: decreasing from g(-1) = Inf to g(+1) = 0
631
## g <- function(th) {
632
## h <- p2b+ th # == g'/beta where g' := pi/2 + beta*th
633
## (h/p2b) * exp(ea + h*tan(th)) / cos(th)
635
##t0 <- -pi2# g(t0) == 0 mathematically, but not always numerically
636
u0 <- -1 # g(u0) == 0 mathematically, but not always numerically
639
r[i <- abs(u-u0) < 1e-10] <- 0
642
h <- p2b+ th # == g'/beta where g' := pi/2 + beta*th = pi/2* (1 + beta*u)
643
r[!i] <- (h/p2b) * exp(ea + h*tanpi2(u)) / cospi2(u)
561
t0 <- -sign(beta)*pi2# g(t0) == 0 mathematically, but not always numerically
562
if(is.na(g0 <- g(t0))) { ## numerical problem ==> need more careful version of g()
563
## find a left threshold instead of -pi/2 where g(.) is *not* NA
566
while(is.na(g(lt))) lt <- lt*f
570
r[i <- (beta*(lt - th) > 0)] <- 0
648
cat(sprintf(".FCT2(%.11g, %.6g, %s..): ",
649
x,beta, if(giveI) "giveI=TRUE," else ""))
651
## g(-u0) == +Inf {at other end}, mathematically ==> exp(-g(.)) == 0
652
## in the outer tails, the numerical integration can be inaccurate,
653
## because g(.) jumps from 0 to Inf, but is 0 almost always
654
## <==> g1(.) = exp(-g(.)) jumps from 1 to 0 and is 1 almost everywhere
655
## ---> the integration "does not see the 0" and returns too large..
657
if(g(uu <- .e.minus(u., 1e-6)) == Inf) {
658
ur <- uniroot(function(t) 1-2*(g(t)==Inf), lower=-1, upper= uu,
659
f.lower= +1, f.upper= -1, tol = 1e-8)
661
if(verbose) cat(sprintf(" g(%g)=Inf: unirt(%d it) -> u.=%.10g",
576
665
##' G2(.) = exp(-g(.)) is strictly monotone .. no need for 'theta2' !
577
.integrate2(function(th) exp(-g(th)), lower = -pi2, upper = pi2,
578
subdivisions = subdivisions, rel.tol = tol, abs.tol = tol) / pi
666
G2 <- if(giveI) function(u) expm1(-g(u)) else function(u) exp(-g(u))
667
r <- .integrate2(G2, lower = -1, upper = u.,
668
subdivisions = subdivisions, rel.tol = tol, abs.tol = tol) / 2
669
if(verbose) cat(sprintf("--> Int r= %.11g\n", r))
581
673
### ------------------------------------------------------------------------------