gpt4 book ai didi

julia - 具有指定分布的随机数据中的类型不稳定性

转载 作者:行者123 更新时间:2023-12-03 21:16:02 25 4
gpt4 key购买 nike

我想从带有噪声的线性模型 (Y = X*w + e) 生成数据,我可以在其中指定输入向量 X 和标量噪声 e 的分布。为此,我指定了以下结构

using Distributions

struct NoisyLinearDataGenerator
x_dist::ContinuousMultivariateDistribution
noise_dist::ContinuousUnivariateDistribution
weights::Vector{Float64}
end

以及从中生成 N 个点的函数:
function generate(nl::NoisyLinearDataGenerator, N)
x = rand(nl.x_dist, N)'
e = rand(nl.noise_dist, N)
return x, x*nl.weights + e
end

这似乎有效,但类型不稳定,因为
nl = NoisyLinearDataGenerator(MvNormal(5, 1.0), Normal(), ones(5))

@code_warntype generate(nl,1)

产量
Variables
#self#::Core.Compiler.Const(generate, false)
nl::NoisyLinearDataGenerator
N::Int64
x::Any
e::Any

Body::Tuple{Any,Any}
1 ─ %1 = Base.getproperty(nl, :x_dist)::Distribution{Multivariate,Continuous}
│ %2 = Main.rand(%1, N)::Any
│ (x = Base.adjoint(%2))
│ %4 = Base.getproperty(nl, :noise_dist)::Distribution{Univariate,Continuous}
│ (e = Main.rand(%4, N))
│ %6 = x::Any
│ %7 = x::Any
│ %8 = Base.getproperty(nl, :weights)::Array{Float64,1}
│ %9 = (%7 * %8)::Any
│ %10 = (%9 + e)::Any
│ %11 = Core.tuple(%6, %10)::Tuple{Any,Any}
└── return %11


我不确定为什么会这样,因为我希望使用 ContinuousMultivariateDistribution 指定采样数据的类型。和 ContinuousUnivariateDistribution .

是什么导致类型不稳定,类型稳定的实现应该是什么样的?

最佳答案

问题是ContinuousMultivariateDistributionContinuousUnivariateDistribution是抽象类型。虽然您的统计知识告诉您他们可能应该返回 Float64 ,在语言层面上不能保证有人不会实现,比如 ContinuousUnivariateDistribution返回一些其他对象。因此编译器无法知道所有 ContinuousUnivariateDistribution产生任何特定类型。

例如,我可能会写:

struct BadDistribution <: ContinuousUnivariateDistribution end
Base.rand(::BadDistribution, ::Integer) = nothing

现在,您可以制作 NoisyLinearDataGenerator包含 BadDistributionx_dist .那么输出类型是什么?

换句话说, generate 的输出只是 不能只能根据其输入类型进行预测。

要解决此问题,您需要指定 具体 新类型的分布,或者使新类型参数化。在 Julia 中,每当我们有一个不能指定为具体类型的类型的字段时,我们通常将它作为类型参数。因此,一种可能的解决方案是:
using Distributions

struct NoisyLinearDataGenerator{X,N}
x_dist::X
noise_dist::N
weights::Vector{Float64}

function NoisyLinearDataGenerator{X,N}(x::X, n::N, w::Vector{Float64}) where {
X <: ContinuousMultivariateDistribution,
N <: ContinuousUnivariateDistribution}
return new{X,N}(x,n,w)
end
end

function NoisyLinearDataGenerator(x::X, n::N, w::Vector{Float64}) where {
X <: ContinuousMultivariateDistribution,
N <: ContinuousUnivariateDistribution}
return NoisyLinearDataGenerator{X,N}(x,n,w)
end

function generate(nl::NoisyLinearDataGenerator, N)
x = rand(nl.x_dist, N)'
e = rand(nl.noise_dist, N)
return x, x*nl.weights + e
end
nl = NoisyLinearDataGenerator(MvNormal(5, 1.0), Normal(), ones(5))

这里, nl的类型是 NoisyLinearDataGenerator{MvNormal{Float64,PDMats.ScalMat{Float64},FillArrays.Zeros{Float64,1,Tuple{Base.OneTo{Int64}}}},Normal{Float64}} (是的,我知道,读起来很糟糕),但它的类型包含编译器完全预测 generate 的输出类型所需的所有信息。 .

关于julia - 具有指定分布的随机数据中的类型不稳定性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60615429/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com