Skip to content

A Discrete Bayesian Graph #210

@erlebach

Description

@erlebach

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.

Metadata

Metadata

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions