julia - 我如何在 Julia 中编写任意连续分布,或者至少模拟一个连续分布的采样?

标签 julia probability

假设我有一个任意概率分布函数 (PDF),定义为函数 f,例如:

using Random, Distributions

#// PDF with parameter θ ϵ (0,1), uniform over 
#// segments [-1,0) and [0,1], zero elsewhere
f = θ -> x -> 
  (-1 <= x < 0) ? θ^2 :
  (0 <= x <= 1) ? 1-θ^2 :
  0

如何在 Julia 中使用此 PDF 从随机变量中采样值? (或者,我至少如何模拟从这样的随机变量中进行采样?)

即我想要相当于 rand(Normal(),10) 的(标准)正态分布中的 10 个值,但我想使用函数 f 来定义分布使用(类似于 rand(f(0.4),10) - 但这不起作用)

(这已经是How can I write an arbitrary discrete distribution in Julia?处离散分布的答案:但是我想使用连续分布。在https://juliastats.org/Distributions.jl/v0.14/extends.html处创建采样器有一些细节,我认为这可能有用,但我不知道不明白如何应用它们。同样在 R 中,我使用了 https://blogs.sas.com/content/iml/2013/07/22/the-inverse-cdf-method.html 中描述的逆 CDF 技术来模拟此类随机变量,但我不确定如何在 Julia 中最好地实现它。)

最佳答案

第一个问题是,您提供的并不是概率分布的完整规范,因为它没有说明区间 [-1, 0) 内或区间内的分布。间隔[0, 1]。因此,出于本答案的目的,我将假设您的概率分布函数在每个间隔上都是均匀的。鉴于此,我认为实现您自己的分布的最朱利安方法是创建一个新的子类型,在本例中为 ContinouslyUnivariateDistribution。示例代码如下:

using Distributions
struct MyDistribution <: ContinuousUnivariateDistribution
    theta::Float64
    function MyDistribution(theta::Float64)
        !(0 <= theta <= 1) && error("Invalid theta: $(theta)")
        new(theta)
    end
end
function Distributions.rand(d::MyDistribution)::Float64
    if rand() < d.theta^2
        x = rand() - 1
    else
        x = rand()
    end
    return x
end
function Distributions.quantile(d::MyDistribution, p::Real)::Float64
    !(0 <= p <= 1) && error("Invalid probability input: $(p)")
    if p < d.theta^2
        x = -1.0 + (p / d.theta^2)
    else
        x = (p - d.theta^2) / (1 - d.theta^2)
    end
    return x
end

在上面的代码中,我为新分布实现了 randquantile 方法,这是能够进行像 rand( MyDistribution(0.4), 20) 从新分布中抽取 20 个随机数。请参阅here有关您可能想要添加到新的分发类型中的其他方法的列表(取决于您的用例,也许您不会打扰)。

请注意,如果效率是一个问题,您可以研究一些可以最大程度地减少 d.theta^2 操作数量的方法,例如Distributions.sampler。或者,您可以将 theta^2 存储在 MyDistribution 内部,但始终显示底层 theta。真的取决于你。

最后,您实际上并不需要函数输出上的类型注释。为了清楚起见,我只是将它们包括在内。

关于julia - 我如何在 Julia 中编写任意连续分布,或者至少模拟一个连续分布的采样?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68796221/

相关文章:

Java Random.nextDouble() 概率

algorithm - 计算 N 面骰子每个面在 M 次掷骰中出现的次数的最快方法

python - PyCall无法使用pipenv版本的python InitError :Incompatible `libpython` detected

c# - 创建你自己的 Tinyurl 风格的 uid

python - 以非逐步方式通过转换矩阵进行优化

math - 为什么简化的数学方程比在 Julia-Lang 中有更多运算的等价方程运行得(稍微)慢?

algorithm - 在哪里可以找到自然语言处理的维特比算法转换值?

julia - 如何使用 Julia 生成 PDF 文档

date - Julia @子集日期

time - 如何测量Julia程序的时间?