StaticArrays is unrelated here, as using a Vector
produces the same result. I suspect SMC selects the number of particles to sample based on the number of draws you have requested. Request more draws, and you at least get non-zero variance:
julia> chain = sample(testmodel(data), SMC(), 1_000)
Chains MCMC chain (1000×5×1 Array{Float64, 3}):
Log evidence = -25.733669871912777
Iterations = 1:1:1000
Number of chains = 1
Samples per chain = 1000
Wall duration = 0.42 seconds
Compute duration = 0.42 seconds
parameters = x[1], x[2], x[3]
internals = lp, weight
Summary Statistics
parameters mean std naive_se mcse ess rhat ess_per_sec
Symbol Float64 Float64 Float64 Float64 Float64 Float64 Float64
x[1] 1.9258 0.0746 0.0024 0.0128 4.3333 1.2212 10.3669
x[2] 2.4460 0.2640 0.0083 0.0466 4.2160 1.2249 10.0861
x[3] -0.1714 0.2859 0.0090 0.0328 41.5919 0.9999 99.5021
Quantiles
parameters 2.5% 25.0% 50.0% 75.0% 97.5%
Symbol Float64 Float64 Float64 Float64 Float64
x[1] 1.8926 1.8926 1.8926 1.8926 2.0801
x[2] 2.3277 2.3277 2.3277 2.3277 3.0491
x[3] -0.1800 -0.1800 -0.1800 -0.1800 0.1550
(though ESS and R-hat are bad; these draws should not be trusted)
On an unrelated note, setting data
as a field of TestDistribution
of the same eltype as the parameter vector a
will not work with all samplers. In particular, when using gradient-based samplers with an operator-overloading AD such as ForwardDiff, the constructor will error, since data
and a
will have different eltypes. I recommend allowing data
to have a different eltype, or, in this case, just store n=length(data)
in TestDistribution
.