Генерация случайных значений из настроенного дистрибутива - PullRequest
3 голосов
/ 05 февраля 2020

У меня есть это распределение ниже:

using Distributions
struct OrthoNNDist <: DiscreteMultivariateDistribution
    x0::Vector{Int64}
    oc::Array{Int64,2}
    x1s::Array
    prob::Float64
    #return a new uniform distribution with all vectors in x1s orthogonal to oc
    function OrthoNNDist(x0::Vector{Int}, oc::Array{Int,2})
        x1s = []
        for i = 1:size(oc)[2]
            x1 = x0 + oc[:, i]
            if nonneg(x1)
                push!(x1s, x1)
            end
            x1 = x0 - oc[:, i]
            if nonneg(x1)
                push!(x1s, x1)
            end
        end
        new(x0, oc, x1s, 1.0/length(x1s))
    end
end

Base.length(d::OrthoNNDist) = length(d.x0)

Distributions.rand(d::OrthoNNDist, N::Integer=1) = rand(d.x1s, 1)

Distributions.pdf(d::OrthoNNDist, x::Vector) = x in d.x1s ? D.prob : 0.0
Distributions.pdf(d::OrthoNNDist) = fill(d.prob, size(d.x1s))
Distributions.logpdf(d::OrthoNNDist, x::Vector) = log(PDF(d, x))

, и я хочу сгенерировать случайные значения из него, я не знаю, как я пытался: rand(OrthoNNDist,1000) и это не сработало, я Я новичок в вероятностном c программировании, я не знаю, как я могу это сделать.


1 Ответ

4 голосов
/ 05 февраля 2020

Функция nonneg больше не предоставляется, что достаточно легко исправить:

nonneg(x::Real) = zero(x) <= x
nonneg(x::Vector{<:Real}) = all(nonneg, x)

Почти все, что вы написали, прекрасно:

using Distributions

struct OrthoNNDist <: DiscreteMultivariateDistribution
    x0::Vector{Int64}
    oc::Array{Int64,2}
    x1s::Array
    prob::Float64
    #return a new uniform distribution with all vectors in x1s orthogonal to oc
    function OrthoNNDist(x0::Vector{Int}, oc::Array{Int,2})
        x1s = []
        for i = 1:size(oc)[2]
            x1 = x0 + oc[:, i]
            if nonneg(x1)
                push!(x1s, x1)
            end
            x1 = x0 - oc[:, i]
            if nonneg(x1)
                push!(x1s, x1)
            end
        end
        new(x0, oc, x1s, 1.0/length(x1s))
    end
end

Base.length(d::OrthoNNDist) = length(d.x0)

Distributions.pdf(d::OrthoNNDist, x::Vector) = x in d.x1s ? D.prob : 0.0
Distributions.pdf(d::OrthoNNDist) = fill(d.prob, size(d.x1s))
Distributions.logpdf(d::OrthoNNDist, x::Vector) = log(PDF(d, x))

Получить rand работает .. вы почти там

using Distributions: rand

Distributions.rand(d::OrthoNNDist, n::Int=1) = rand(d.x1s, n)

теперь с некоторыми данными

julia> x0 = rand(1:1_000_000,5);
julia> oc = reshape(rand(1:1_000_000,25), (5,5));
julia> dist = OrthoNNDist(x0,oc);
julia> Distributions.rand(dist, 4)
4-element Array{Any,1}:
 [1330729, 656190, 927615, 470782, 1435138]
 [1382946, 1058057, 778316, 488440, 1304526]
 [1330729, 656190, 927615, 470782, 1435138]
 [1409093, 353679, 454229, 698320, 1271674]

(спасибо Мухаммеду Тареку за его руководство)

...