从Julia中的两个分布得到一个概率分布

从Julia中的两个分布得到一个概率分布,julia,Julia,有没有什么简单的方法可以让我在Julia中构造一个发行版,它的行为就像一个发行版,我可以调用rand()和rand,其行为如下:以概率p从分布d1中提取,以概率1-p从分布d2中提取。多谢各位 发行版。jl基本上准备好了定义新发行版的所有工具。因此,在本例中,我的尝试如下所示: using Distributions d1 = Exponential(0.2) d2 = Exponential(0.5) p = 0.7 根据应用程序的需要,可以定义更多的函数,并且可以为这种特定类型专门化函数。

有没有什么简单的方法可以让我在Julia中构造一个发行版,它的行为就像一个发行版,我可以调用
rand()
rand,其行为如下:以概率
p
从分布
d1
中提取,以概率
1-p
从分布
d2
中提取。多谢各位

发行版。jl
基本上准备好了定义新发行版的所有工具。因此,在本例中,我的尝试如下所示:

using Distributions
d1 = Exponential(0.2)
d2 = Exponential(0.5)
p = 0.7
根据应用程序的需要,可以定义更多的函数,并且可以为这种特定类型专门化函数。

您可以使用:


非常感谢你这么快推出你的版本。它实际上非常接近于内置
MixtureModel
的定义!他们只是使用分类分布而不是伯努利分布,所以它可以支持两种以上成分的混合物。谢谢马特。这个解决方案效果更好。有一个很好的机会像这样的东西被烘焙到分发包中。现在我会记住它。谢谢,这是一个很好的解决方案。如果我想让其中一个发行版返回它的值乘以-1(好像我在做一个),我该怎么做?它不像
MixtureModel([d1,-d2],[p,1-p])
@BenS。如果使用我的版本,那么求反
d2
很简单,只需将其放入
rand
函数即可。事实上,输出的任何转换都是可能的(是时候将检查返回到我的答案了;)?在转换后的函数中,MixtureModel的额外功能没有用处(平均值和密度不正确)。@Matt关于MixtureModel,它没有实现
cdf
,这是一个遗憾,因为计算cdf是可能的(而且很容易)。但堆栈溢出注释不是问题/功能请求或拉取请求的位置。
using Distributions

struct CompoundBernoulli{T<:Distributions.VariateForm,
                         S<:Distributions.ValueSupport} <:
         Distributions.Sampleable{T, S}
    p::Bernoulli
    d1::Distributions.Sampleable{T,S}
    d2::Distributions.Sampleable{T,S}
end

# outer constructor  
CompoundBernoulli(p::Real, 
                  d1::Distributions.Sampleable{S, T},
                  d2::Distributions.Sampleable{S, T}) where 
  {S<:Distributions.VariateForm, T<:Distributions.ValueSupport} = 
  CompoundBernoulli{S,T}(Bernoulli(p),d1,d2)

Base.rand(cb::CompoundBernoulli) = rand(cb.p)==0 ? rand(cb.d1) : rand(cb.d2)
julia> cb = CompoundBernoulli(0.7,Exponential(0.2),Exponential(0.5))
CompoundBernoulli{Distributions.Univariate,Distributions.Continuous}
(Distributions.Bernoulli{Float64}(p=0.7), 
Distributions.Exponential{Float64}(θ=0.2), 
Distributions.Exponential{Float64}(θ=0.5))

julia> rand(cb)
0.3247418465183849

julia> rand(cb,3,3)
3×3 Array{Float64,2}:
 0.33105   0.231418  0.271571
 0.413905  0.662144  1.42725 
 0.20196   0.091628  0.194761
julia> m = MixtureModel([d1,d2],[p,1-p])
MixtureModel{Distributions.Exponential{Float64}}(K = 2)
components[1] (prior = 0.7000): Distributions.Exponential{Float64}(θ=0.2)
components[2] (prior = 0.3000): Distributions.Exponential{Float64}(θ=0.5)

julia> mean(m)
0.29000000000000004

julia> pdf(m, 0)
4.1

julia> rand(m)
0.2574516697519676

julia> rand!(m, zeros(1,5))
1×5 Array{Float64,2}:
 0.0704624  0.264519  0.636179  0.11479  0.41158