我的问题与我之前的Generate random variables from a distribution function using inverse sampling有关 现在我想使用反向采样从分布函数生成随机变量,但应该对采样进行调节。 例如,如果我的cdf的反转是:
invcdf <- function(y) a2 * log(a1/y - 1) + a3
我使用逆采样生成10 rv,如下所示:
invcdf(runif(10))
现在,问题在于我希望生成的值大于或小于某个值。 我该如何在随机发生器中引入这个条件?
当我使用它来获得大于500的值时:
invcdf(runif(10,500,1e6))
我收到此错误消息: 警告信息: 在log((a0 / y) - 1)中:产生NaNs
我已经尝试重复这个过程,直到让值满足我的约束,但效率不高!
repeat{
x=invcdf(runif(1))
if(x>100){
break
}
答案 0 :(得分:2)
正如@ spf614所说,你最好在你的功能中检查,如
invcdf <- function(y) {
if (a1 > y) {
return( a2 * log(a1/y - 1) + a3 )
}
NaN
}
然后它适用于所有参数
抽样将是
low <- ...
r <- invcdf(runif(low, a1, 1e6))
更新
检查输出中的NaN
nof_nans <- sum(is.nan(r))
if (nof_nans > 0) {
....
答案 1 :(得分:1)
你获得NaN的原因是R试图取负数的对数。您希望日志字词为log((a1/y)-1)
还是log(a1/(y-1))
?您当前使用第一种方式编写函数,当y得到非常高的值时,术语a1/y
接近零(其接近零的速度取决于a1
的值)。因此,减去1会在日志函数中显示负数。因此,如果该术语的意思是您的编写方式(log(a1/y-1)
),那么您根本无法计算出y
以上的特定值。
简单的修复只是
invcdf <- function(y){
a2 * log(a1/(y-1)) + a3
}