I am implementing a discrete Bayesian network using a few Nonlinear functions and cannot get the messagePassingAlgorithm() method to run without error. The resulting graph has all its edges terminated either by Clamp or via a placeholder. Here is the code, which is rather simple:
using ForneyLab
using Plots
gA = 3
gB = 5
gC = 8
# Three deterministic functions
function grade(i, d)
if i == 0 && d == 0
g1,g2,g3 = [0.3, 0.4, 0.3]
elseif i == 0 && d == 1
g1,g2,g3 = [0.05, 0.25, 0.7]
elseif i == 1 && d == 0
g1,g2,g3 = [0.9, 0.08, 0.02]
else
g1,g2,g3 = [0.5, 0.3, 0.2]
end
return [g1, g2, g3]
end
function letter(g)
if g == gA
l = .9
elseif g == gB
l = .6
else
l = 0.01
end
return l
end
function score(i)
if i == 0
s = 0.05
else
s = 0.8
end
return s
end
# The model
gr = FactorGraph()
# @RV b1 ~ Clamp(0.4)
# @RV b2 ~ Clamp(0.3)
@RV d ~ Bernoulli(0.4)
@RV i ~ Bernoulli(0.3)
@RV grade_ ~ Nonlinear{Sampling}(i, d, g=grade, n_samples=50)
@RV g ~ Categorical(grade_)
@RV letter_ ~ Nonlinear{Sampling}(g, g=letter, n_samples=50)
@RV l ~ Bernoulli(letter_)
@RV score_ ~ Nonlinear{Sampling}(i, g=score, n_samples=50)
@RV s ~ Bernoulli(score_)
# placeholder(d, :d)
placeholder(i, :i)
placeholder(s, :s)
placeholder(l, :l)
placeholder(g, :g)
# The line the produces the error:
algo = messagePassingAlgorithm([d]) # <<<<< ERROR
source_code = algorithmSourceCode(algo)
eval(Meta.parse(source_code));
The error produced is:
No applicable SumProductRule{Categorical} update for Categorical node with inbound types: Message{SampleList}, Nothing
Stacktrace:
[1] error(s::String)
@ Base ./error.jl:33
[2] inferUpdateRule!(entry::ScheduleEntry, rule_type::Type{SumProductRule{Categorical}}, inferred_outbound_types::Dict{Interface, Type})
@ ForneyLab ~/src/2022/ForneyLab.jl/src/algorithms/sum_product.jl:75
[3] inferUpdateRules!(schedule::Vector{ScheduleEntry}; inferred_outbound_types::Dict{Interface, Type})
@ ForneyLab ~/src/2022/ForneyLab.jl/src/message_passing.jl:203
[4] messagePassingSchedule(pf::PosteriorFactor)
@ ForneyLab ~/src/2022/ForneyLab.jl/src/algorithms/posterior_factor.jl:75
[5] messagePassingAlgorithm(target_variables::Vector{Variable}, pfz::PosteriorFactorization; ep_sites::Vector{Tuple}, id::Symbol, free_energy::Bool)
@ ForneyLab ~/src/2022/ForneyLab.jl/src/algorithms/inference_algorithm.jl:82
[6] messagePassingAlgorithm (repeats 2 times)
@ ~/src/2022/ForneyLab.jl/src/algorithms/inference_algorithm.jl:58 [inlined]
[7] top-level scope
@ In[31]:1
[8] eval
@ ./boot.jl:373 [inlined]
[9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1196
Clearly, this means that there is no SumProduct rule to handle categorical variables with a SampleMessage Input. So my question is: how is this case treated? Would a straightforward variation technique be appropriate? Thanks.
I am implementing a discrete Bayesian network using a few Nonlinear functions and cannot get the
messagePassingAlgorithm()method to run without error. The resulting graph has all its edges terminated either byClampor via aplaceholder. Here is the code, which is rather simple:The error produced is:
No applicable SumProductRule{Categorical} update for Categorical node with inbound types: Message{SampleList}, Nothing Stacktrace: [1] error(s::String) @ Base ./error.jl:33 [2] inferUpdateRule!(entry::ScheduleEntry, rule_type::Type{SumProductRule{Categorical}}, inferred_outbound_types::Dict{Interface, Type}) @ ForneyLab ~/src/2022/ForneyLab.jl/src/algorithms/sum_product.jl:75 [3] inferUpdateRules!(schedule::Vector{ScheduleEntry}; inferred_outbound_types::Dict{Interface, Type}) @ ForneyLab ~/src/2022/ForneyLab.jl/src/message_passing.jl:203 [4] messagePassingSchedule(pf::PosteriorFactor) @ ForneyLab ~/src/2022/ForneyLab.jl/src/algorithms/posterior_factor.jl:75 [5] messagePassingAlgorithm(target_variables::Vector{Variable}, pfz::PosteriorFactorization; ep_sites::Vector{Tuple}, id::Symbol, free_energy::Bool) @ ForneyLab ~/src/2022/ForneyLab.jl/src/algorithms/inference_algorithm.jl:82 [6] messagePassingAlgorithm (repeats 2 times) @ ~/src/2022/ForneyLab.jl/src/algorithms/inference_algorithm.jl:58 [inlined] [7] top-level scope @ In[31]:1 [8] eval @ ./boot.jl:373 [inlined] [9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String) @ Base ./loading.jl:1196Clearly, this means that there is no SumProduct rule to handle categorical variables with a SampleMessage Input. So my question is: how is this case treated? Would a straightforward variation technique be appropriate? Thanks.