You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中对无法手动求逆的CDF进行抽样?

在R中实现该CDF的抽样方法

因为无法手动推导该CDF的逆函数,我们可以用数值逆变换抽样的方法来生成样本,核心逻辑是:

  1. 生成服从均匀分布U(0,1)的随机数;
  2. 对每个均匀随机数,通过数值方法求解方程 flc_F(x) = u,得到对应的x值,即为目标分布的样本。

具体实现代码

1. 定义原CDF函数

a <- 3.1
be <- -0.15
ga <- 0.78
delt <- 0.12

c <- 3.5

b <- exp(a + be * c * (1 + c))
g <- exp((ga + delt * c) * c)

flc_F <- function(x) {
  # x取值范围为0到1
  if (x < 1) {
    return((b * (g - 1) * (1 - b^x)) / (b * (g - 1) + (1 - b * g) * b^x))
  } else {
    return(1)
  }
}

2. 实现数值逆CDF函数

利用R内置的uniroot函数求解方程,由于该CDF在x∈[0,1]上严格单调递增(从0到1),每个u∈(0,1)对应唯一的x:

flc_F_inv <- function(u) {
  # 处理边界情况
  if (u == 0) return(0)
  if (u == 1) return(1)
  # 解方程 flc_F(x) - u = 0
  root <- uniroot(function(x) flc_F(x) - u, interval = c(0, 1))
  return(root$root)
}

3. 生成样本

生成指定数量的样本,只需生成均匀随机数后逐个传入逆函数:

# 生成1000个样本
n <- 1000
u_samples <- runif(n)
x_samples <- sapply(u_samples, flc_F_inv)

4. 验证抽样结果

可以绘制样本直方图,并叠加原分布的PDF(CDF求导得到)来验证:

# 定义PDF函数(CDF的导数)
flc_f <- function(x) {
  if (x < 1) {
    numerator <- b*(g-1)*log(b)*b^x * (b*(g-1) + (1 - b*g)*b^x) + b*(g-1)*(1 - b^x)*(1 - b*g)*log(b)*b^x
    denominator <- (b*(g-1) + (1 - b*g)*b^x)^2
    return(numerator / denominator)
  } else {
    return(0)
  }
}

# 绘图验证
hist(x_samples, prob = TRUE, breaks = 30, main = "抽样样本直方图与PDF", xlab = "x")
curve(flc_f(x), from = 0, to = 1, add = TRUE, col = "red", lwd = 2)

注意事项

  • uniroot要求目标函数在区间端点符号相反,这里flc_F(0)=0 < u、flc_F(1)=1 > u,完全满足求解条件,结果稳定;
  • 边界值u=0和u=1直接返回x=0和x=1,无需调用数值求解。

内容的提问来源于stack exchange,提问作者user33484

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 20:45:46