I want to generate data from a linear model with noise (Y = X*w + e) where I can specify the distributions of input vector X and scalar noise e. For this, I specify the below struct
using Distributions
struct NoisyLinearDataGenerator
x_dist::ContinuousMultivariateDistribution
noise_dist::ContinuousUnivariateDistribution
weights::Vector{Float64}
end
and a function to generate N points from it:
function generate(nl::NoisyLinearDataGenerator, N)
x = rand(nl.x_dist, N)'
e = rand(nl.noise_dist, N)
return x, x*nl.weights + e
end
This seems to be working, however not type stable, as
nl = NoisyLinearDataGenerator(MvNormal(5, 1.0), Normal(), ones(5))
@code_warntype generate(nl,1)
yields
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
I am not sure why this is, since I would expect the type of the sampled data to be specified by using ContinuousMultivariateDistribution and ContinuousUnivariateDistribution.
What is leading to type instability here and what should a type stable implementation look like?