Я покажу другое возможное решение, которое довольно широко применимо, и с сегодняшним программным обеспечением R, довольно простое в реализации. Это приближение плотности седловой точки, которое должно быть более широко известным!
Для терминологии о гамма-распределении я буду следовать https://en.wikipedia.org/wiki/Gamma_distribution с параметризацией формы / масштаба, - параметр формы, а θ - масштаб. Для приближения седловой точки я буду следовать Рональду В. Батлеру: «Приближения седловой точки с приложениями» (Кембридж UP). Приближение седловой точки объясняется здесь: Как работает приближение седловой точки?
здесь я покажу, как это используется в этом приложении.Кθ
Пусть - случайная величина с существующей порождающей момент функцией
M ( s ) = E e s X, которая должна существовать для s в некотором открытом интервале, который содержит ноль. Затем определим производящую функцию кумулянта как
K ( s ) = log M ( s ).
Известно, что E X = K ′ ( 0 ) , Var ( X ) = K ″ ( 0 )Икс
M( s )=Eeс Х
sК( s ) = журналM( s )
ЕИкс= К'( 0 ) , Var ( X)) = К''( 0 ), Уравнение является перевал
, который определяет неявный
ы как функции
х (которое должно быть в диапазоне
X ). Обозначим эту функцию неявно определенную как
з ( х ) . Обратите внимание, что уравнение седловой точки всегда имеет ровно одно решение, потому что кумулянтная функция является выпуклой.
К'(s^)=x
sxXs^(x)
Тогда перевала приближение к плотности из X задается
ф ( х ) = 1fX
f^(x)=12πK′′(s^)−−−−−−−√exp(K(s^)−s^x)
X1,X2,…,XnXi(ki,θi)
K(s)=−∑i=1nkiln(1−θis)
s<1/max(θ1,θ2,…,θn)K′(s)=∑i=1nkiθi1−θis
K′′(s)=∑i=1nkiθ2i(1−θis)2.
R
n=3k = ( 1 , 2 , 3 )θ = ( 1 , 2 , 3 )R
shape <- 1:3 #ki
scale <- 1:3 # thetai
# For this case, we get expectation=14, variance=36
make_cumgenfun <- function(shape, scale) {
# we return list(shape, scale, K, K', K'')
n <- length(shape)
m <- length(scale)
stopifnot( n == m, shape > 0, scale > 0 )
return( list( shape=shape, scale=scale,
Vectorize(function(s) {-sum(shape * log(1-scale * s) ) }),
Vectorize(function(s) {sum((shape*scale)/(1-s*scale))}) ,
Vectorize(function(s) { sum(shape*scale*scale/(1-s*scale)) })) )
}
solve_speq <- function(x, cumgenfun) {
# Returns saddle point!
shape <- cumgenfun[[1]]
scale <- cumgenfun[[2]]
Kd <- cumgenfun[[4]]
uniroot(function(s) Kd(s)-x,lower=-100,
upper = 0.3333,
extendInt = "upX")$root
}
make_fhat <- function(shape, scale) {
cgf1 <- make_cumgenfun(shape, scale)
K <- cgf1[[3]]
Kd <- cgf1[[4]]
Kdd <- cgf1[[5]]
# Function finding fhat for one specific x:
fhat0 <- function(x) {
# Solve saddlepoint equation:
s <- solve_speq(x, cgf1)
# Calculating saddlepoint density value:
(1/sqrt(2*pi*Kdd(s)))*exp(K(s)-s*x)
}
# Returning a vectorized version:
return(Vectorize(fhat0))
} #end make_fhat
fhat <- make_fhat(shape, scale)
plot(fhat, from=0.01, to=40, col="red", main="unnormalized saddlepoint approximation\nto sum of three gamma variables")
в результате на следующем участке:
Я оставлю нормализованное приближение седловой точки в качестве упражнения.