如何用data.table实现离散蒙特卡洛逆变换的数值映射表?
离散分布蒙特卡洛逆变换抽样(data.table 实现)
首先明确:你提到的f(y)应该是累积分布函数(CDF),即F(y) = P(Y ≤ y)——逆变换抽样的核心逻辑是找到最小的y,使得u_i ≤ F(y),对应区间就是F(y-1) < u_i ≤ F(y)(其中F(-1)=0,对应u_i落在(0, F(0)]的情况)。
以下是用data.table实现的具体步骤和代码:
步骤1:准备基础数据与分布函数
先加载data.table,定义给定变量,同时明确你的概率质量函数(PMF)(如果f(y)已经是CDF,可跳过CDF计算步骤):
library(data.table) # 定义给定变量 y <- 0:200 # rep(0:200,1)等价于0:200,写法更简洁 u <- runif(201, 0, 1) # 示例:定义你的概率质量函数(PMF),这里用泊松分布lambda=5做演示 pmf <- function(y_val) dpois(y_val, lambda = 5)
步骤2:构建CDF映射表
用data.table生成y与对应累积分布函数值的映射,同时补充y=-1时的CDF值为0,覆盖u_i落在(0, F(0)]的边界情况:
# 计算CDF:对PMF求和得到累积概率 dt_cdf <- data.table(y = y, Fy = cumsum(pmf(y))) # 补充y=-1的CDF=0,处理u <= F(0)的情况 dt_cdf <- rbind(data.table(y = -1, Fy = 0), dt_cdf)
步骤3:匹配每个u对应的y值
用data.table的滚动连接高效匹配每个u_i对应的y——滚动连接是处理这类区间匹配最快速的方式:
# 给u表添加索引,方便对应原始顺序 dt_u <- data.table(u = u, id = seq_along(u)) # 滚动连接:找到第一个Fy >= u的行,对应的y就是目标值 setorder(dt_cdf, Fy) # 确保CDF表按Fy升序排列 result <- dt_u[, .(id, u)][dt_cdf, on = .(u <= Fy), roll = -Inf, .(id, u = x.u, sampled_y = i.y)]
结果说明
最终的result表包含三列:
id:原始u的索引,保证顺序对应u:生成的均匀随机数sampled_y:通过逆变换抽样得到的离散分布样本值
如果你的f(y)本身就是CDF(而非PMF),直接把dt_cdf中的Fy替换为f(y)即可,无需cumsum计算。
内容的提问来源于stack exchange,提问作者BrownKoi
相关产品推荐
相关产品推荐

