In this post, I have two questions I am not sure are completely separate or not, so I ask them both here.
I define a structure and a substructure that has a field B
which is an array of Distributions
. It can be univariate, product, multivariate etc.
I define the structure like that
using Distributions
abstract type mainT{F<:VariateForm} end
struct SubT{F} <: mainT{F}
B::AbstractArray{Distribution{F}}
end
However, when I try to define a SubT
from an array of Bernoulli
it does not work
K = 5
T = 2
B = Bernoulli.(rand(K,T)) # Array of Bernoulli distributions
h = SubT(B) # Fail
ERROR: MethodError: no method matching SubT(::Matrix{Bernoulli{Float64}})
Closest candidates are:
SubT(::AbstractArray{Distribution{F, S} where S<:ValueSupport, N} where N) where F at REPL[3]:2
So I can do the following to make it work
B = convert(Matrix{UnivariateDistribution{S} where S<:ValueSupport}, B)
h = SubT2(B) # Works
This type re-definition is problematic for many reason so I would like to avoid and be able to define my h
the first way. Ideally, the type of h
would not be UnivariateDistribution{S} where S<:ValueSupport
but specific to each choice of distribution, e.g. here Matrix{Bernoulli{Float64}}
.
The second problem is, when I want to sort columns of my array in some specific way with in place modification. I have the function
function sort_wrt_ref!(B::AbstractVector)
K = size(B, 1)
sorting = [succprob(h.B[k]) for k in 1:K]
B[:] = B[sortperm(sorting)]
end
However, it does not seem to modify in place the columns of my array.
julia> h.B
5×2 Matrix{UnivariateDistribution{S} where S<:ValueSupport}:
Bernoulli{Float64}(p=0.958907) Bernoulli{Float64}(p=0.204364)
Bernoulli{Float64}(p=0.0382291) Bernoulli{Float64}(p=0.898818)
Bernoulli{Float64}(p=0.953247) Bernoulli{Float64}(p=0.367522)
Bernoulli{Float64}(p=0.196388) Bernoulli{Float64}(p=0.0861771)
Bernoulli{Float64}(p=0.333265) Bernoulli{Float64}(p=0.275637)
julia> sort_wrt_ref!(h.B[:,1]) # it is sorting as the output shows but not changing the column h.B[:,1]
5-element Vector{UnivariateDistribution{S} where S<:ValueSupport}:
Bernoulli{Float64}(p=0.038229098624871005)
Bernoulli{Float64}(p=0.1963878250239648)
Bernoulli{Float64}(p=0.3332646196249027)
Bernoulli{Float64}(p=0.9532465128727561)
Bernoulli{Float64}(p=0.958907107799279)
julia> h.B
5×2 Matrix{UnivariateDistribution{S} where S<:ValueSupport}:
Bernoulli{Float64}(p=0.958907) Bernoulli{Float64}(p=0.204364)
Bernoulli{Float64}(p=0.0382291) Bernoulli{Float64}(p=0.898818)
Bernoulli{Float64}(p=0.953247) Bernoulli{Float64}(p=0.367522)
Bernoulli{Float64}(p=0.196388) Bernoulli{Float64}(p=0.0861771)
Bernoulli{Float64}(p=0.333265) Bernoulli{Float64}(p=0.275637)
I have the same issue with other in place function. They work as expected on vector
but not on slice of array.