-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnbl.R
83 lines (70 loc) · 1.8 KB
/
nbl.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Negative-Binomial-Lindly distribution
# rnbl(n,r,theta) - random numbers from NBL
# dnbl(x,r,theta) - NBL pmf at x
# pnbl(q,r,theta) - NBL cdf at x
# qnbl(p,r,theta) - NBL inverse at p
# Soma S Dhavala, 11/5/2013
# GNU Public License, free to use/copy with/without attribution
# nbl random numbers
rnbl <- function(n,r,theta)
{
lambda <- ifelse(runif(n) < theta/(1 + theta), rexp(n, theta),
rgamma(n,shape = 2, scale = 1/theta))
p <- exp(-lambda)
x <- rnbinom(n,r,prob=p)
}
# pmf of a vector based on numerical integration
dnbl <- function(x,r,theta)
{
nbl.integrand <- function(x,k,r,theta)
{
nlogp <- -log(x)
tmp1 <- dnbinom(k,r,x,log=TRUE)
tmp2 <- -theta*nlogp
tmp3 <- 2*log(theta)-log(1+theta)
tmp4 <- log(1+nlogp)
y <- exp(nlogp+tmp1+tmp2+tmp3+tmp4)
return(y)
}
nbl.pmf <- function(x,r,theta)
{
return(integrate(nbl.integrand,lower=0,upper=1,k=x,r=r,theta=theta)$value)
}
p <- sapply(x,nbl.pmf,r=r,theta=theta)
return(p)
}
# cdf of a vector based on numerical integration
pnbl <- function(x,r,theta)
{
nbl.integrand <- function(x,k,r,theta)
{
nlogp <- -log(x)
tmp1 <- pnbinom(k,r,x,log.p=TRUE)
tmp2 <- -theta*nlogp
tmp3 <- 2*log(theta)-log(1+theta)
tmp4 <- log(1+nlogp)
y <- exp(nlogp+tmp1+tmp2+tmp3+tmp4)
return(y)
}
nbl.cdf <- function(x,r,theta)
{
return(integrate(nbl.integrand,lower=0,upper=1,k=x,r=r,theta=theta)$value)
}
p <- sapply(x,nbl.cdf,r=r,theta=theta)
return(p)
}
# inverse-cdf but based on monte-carlo estimates
qnbl <- function(p,r,theta,nboot=10000)
{
x <- rnbl(nboot,r,theta)
q <- quantile(x,probs=p)
return(q)
}
# example
theta <- 100
r <- 20
n = 1000
dnbl(c(0,1,2),r,theta)
pnbl(c(0,1,2),r,theta)
qnbl(c(0.1,0.5,0.88,0.99),r,theta)