使用自适应抑制采样方法(R)对对数凹分布进行采样
我不太熟悉使用自适应抑制采样方法(R)对对数凹分布进行采样,r,random,distribution,sampling,R,Random,Distribution,Sampling,我不太熟悉R。我一直在尝试使用R中的方法实现,以便从以下分布中进行采样: 这是我的R代码: library(ars) g1 <- function(x,r){(1./r)*((1-x)^r)} f1 <- function(x,a,k) { add<-0 for(i in 1:k) { add<- add+g1(x,i) } res <- (a* add)+(a-1)*log(x)+k*log(1-x) return(res) } g2
R
。我一直在尝试使用R
中的方法实现,以便从以下分布中进行采样:
这是我的R
代码:
library(ars)
g1 <- function(x,r){(1./r)*((1-x)^r)}
f1 <- function(x,a,k) {
add<-0
for(i in 1:k) {
add<- add+g1(x,i)
}
res <- (a* add)+(a-1)*log(x)+k*log(1-x)
return(res)
}
g2 <- function(x,r){(1-x)^(r-1)}
f1prima <- function(x,a,k) {
add<-0
for(i in 1:k) {
add<- add-g2(x,i)
}
res <- (a* add)+(a-1)/x-k/(1-x)
return(res)
}
mysample1<-ars(20,f1,f1prima,x=c(0.001,0.09),m=2,emax=128,lb=TRUE,xlb=0.0, ub=TRUE, xub=1,a=0.5,k=100)
库(ars)
g1首先,您已经注意到,对数凹函数在x=0和x=1.0时的定义不是很好。所以有用的间隔应该是0.01…0.99,而不是0.0…1.0
第二,我不喜欢在求和项中计算数百项。
所以,好主意可能是用下面的方式来表达,从导数开始
S1N-1 qi具有明显的可替代性
(1-qN)/(1-q),其中q=1-x
这是导数,所以要得到函数本身的类似项,只需积分它
将返回正对数
-qN+12f1(1,N+1;N+2;q)/(N+1)-log(1-q)
注意:它与之前的Beta积分相同,但处理起来有点麻烦
因此,计算这些术语的代码:
library(gsl)
library(ars)
library(ggplot2)
Gauss2F1 <- function(a, b, c, x) {
ifelse(x >= 0.0 & x < 1.0, hyperg_2F1(a, b, c, x), hyperg_2F1(c - a, b, c, 1.0 - 1.0/(1.0 - x))/(1.0 - x)^b)
}
f1sum <- function(x, N) {
q <- 1.0 - x
- q^(N+1) * Gauss2F1(1, N+1, N+2, q)/(N+1) - log(1.0 - q)
}
f1sum.1 <- function(x, N) {
q <- 1.0 - x
res <- rep(0.0, length.out = length(x))
s <- rep(1.0, length.out = length(x))
for(k in 1:N) {
s <- s * q / as.numeric(k)
res <- res + s
}
res
}
f1 <- function(x, a, N) {
a * f1sum(x, N) + (a - 1.0)*log(x) + N*log(1.0 - x)
}
f1.1 <- function(x, a, N) {
a * f1sum.1(x, N) + (a - 1.0)*log(x) + N*log(1.0 - x)
}
f1primesum <- function(x, N) {
q <- 1.0 - x
(1.0 - q^N)/(1.0 - q)
}
f1primesum.1 <- function(x, N) {
res <- rep(0.0, length.out = length(x))
s <- rep(1.0, length.out = length(x))
for(k in 1:N) {
res <- res + s
s <- s * q
}
-res
}
f1prime <- function(x, a, N) {
a* f1primesum(x, N) + (a - 1.0)/x - N/(1.0 - x)
}
f1prime.1 <- function(x, a, N) {
a* f1primesum.1(x, N) + (a - 1.0)/x - N/(1.0 - x)
}
p <- ggplot(data.frame(x = c(0, 1)), aes(x = x)) +
stat_function(fun = f1, args = list(0.5, 100), colour = "#4271AE") +
stat_function(fun = f1.1, args = list(0.5, 100), colour = "#1F3552") +
scale_x_continuous(name = "X", breaks = seq(0, 1, 0.2), limits=c(0.001, 0.5)) +
scale_y_continuous(name = "F") +
ggtitle("Log-concave function")
p
库(gsl)
图书馆(ars)
图书馆(GG2)
高斯2F1=0.0&x<1.0,hyperg_2F1(a,b,c,x),hyperg_2F1(c-a,b,c,1.0-1.0/(1.0-x))/(1.0-x)^b)
}
f1sum你解决了吗?@SeverinPapadeux很好,不是完全解决了,而是部分解决了。这将ars抽样的下限设置为0.1,如下所示:mysample1ok,让我开始写一些关于这个问题的东西,也许在接下来的几天里,我们会得到一些答案。我尝试了您为ars采样建议的下限和上限,但它返回错误消息。关于最初的形式主义,我基本上是在尝试实现,上面的等式引用了本文中的等式25,其中N
不仅仅是一个大数字,而是矩阵z
中的行数。因此,我不知道扩大规模是处理这一问题的正确方法equation@Dalek请看一下更新,告诉我你的想法think@ServerinPappadeux很抱歉,过了一会儿我又回到这个问题上来。在数学和理解如何将sum{I=1}^N(1/I)(1-x)^I
转换为几何级数之后,我有一个问题?你能解释一下吗?@Dalek我们知道的是如何求和\sum{i=1}^N(q)^i,其中q=1-x
-这是几何级数。我们要做的是将我们的和转换成几何形式——要做到这一点,我们将它与q
区分开来。之后,可以求和序列(表示tiM(q)
),现在我们有微分方程dS(q)/dq=M(q)
。为了得到S(q)
我们只需要积分,就是这样。积分将产生超几何函数。请仔细检查所有的数学运算。@serverinpapadeux所以即使使用您建议的近似值,函数也不是接近零的对数凹函数,对吗?所以ARS可以用于接近零的值?!!我理解对了吗?是否有任何下限,它可能会工作?