BIFMHelper
Overview
BIFMHelper starts a chain of BIFM nodes, between the prior of the first state and the first state itself. It is where the backward pass turns into the forward one: it passes the backward message through towards the prior, and sends the prior's marginal forward as the chain's starting marginal.
Definition
In an RxInfer model the helper is written out ~ BIFMHelper(in), with out the first state and in its prior. As a density it is the identity, p(out | in) = δ(out - in); its rules implement the switch between the passes rather than a product with it.
Interfaces
using BIFMMessagePassingRules, MessagePassingRulesBase, BayesBase, ExponentialFamily
MessagePassingRulesBase.nodespec(BIFMHelper)| interface | aliases | |
|---|---|---|
out | ||
in |
| default algorithm | MessagePassingRulesBase.DefaultAlgorithm() |
|---|---|
| static inputs | none |
| defined | src/bifm_helper.jl:39 |
The node has two interfaces.
| name | meaning | messages and marginals the rules take |
|---|---|---|
out | the first state of the chain | the message on out, any type, towards in |
in | the prior of the first state | the marginal q(in), any type, towards out |
Towards in the rule passes the message on out through unchanged; towards out it sends TerminalProdArgument(q(in)), which the first BIFM reads as the marginal of its zprev.
Algorithm
BIFMHelper runs under the default algorithm, DefaultAlgorithm, and a model names none. The model keeps in and out in separate clusters, q(in) q(out). The node declares its dependencies, the inputs each target's rule takes:
MessagePassingRulesBase.dependencies_spec(BIFMHelper, DefaultAlgorithm())| free-energy partition | from the factorisation |
|---|
The rule towards out takes the input of the default scheme, the marginal of in. The rule towards in takes the message on out instead, which the default scheme would not give it under q(in) q(out).
Supported rules
MessagePassingRulesBase.rule_coverage(BIFMHelper)| DefaultAlgorithm | |
|---|---|
| → out | ✓ |
| → in | ✓ |
| average energy | ✓ |
The rule towards in reads the message on out and the rule towards out the marginal of in, as the switch between the passes needs. The average energy exists only to throw a BIFMFreeEnergyError.
Example
At the start of the forward pass, the helper sends the marginal of the prior towards the first state:
@call_message_update_rule(
node = BIFMHelper, target = :out,
q = (in = MvNormalMeanCovariance([1.0], [2.0;;]),),
)Result
| value | TerminalProdArgument(MvNormalMeanCovariance( μ: [1.0] Σ: [2.0;;] ) ) |
|---|---|
| type | BayesBase.TerminalProdArgument{ExponentialFamily.MvNormalMeanCovariance{Float64, Vector{Float64}, Matrix{Float64}}} |
| log scale | undefined: the message rule for BIFMHelper towards :out under MessagePassingRulesBase.DefaultAlgorithm declares no `logscale` |
Inputs
| edge | value | |
|---|---|---|
| in | q | MvNormalMeanCovariance( μ: [1.0] Σ: [2.0;;] ) |
Rule
| declared inputs | q[:in]::Any |
|---|---|
| algorithm | DefaultAlgorithm() |
| log scale | none |
| defined | src/bifm_helper.jl:46 |
| body | args->TerminalProdArgument(args.q[:in]) |
@call_message_update_rule runs the rule and draws the marginal it read. The result wraps that marginal in a TerminalProdArgument, which getresult returns:
julia> using BIFMMessagePassingRules, MessagePassingRulesBase, BayesBase, ExponentialFamily
julia> result = @call_message_update_rule(
node = BIFMHelper, target = :out,
q = (in = MvNormalMeanCovariance([1.0], [2.0;;]),),
);
julia> getresult(result) isa TerminalProdArgument
trueAt the end of the backward pass, the helper passes the backward message on the first state through towards the prior, unchanged:
@call_message_update_rule(
node = BIFMHelper, target = :in,
m = (out = MvNormalWeightedMeanPrecision([1.0], [0.5;;]),),
)Result
| value | MvNormalWeightedMeanPrecision( xi: [1.0] Λ: [0.5;;] ) |
|---|---|
| type | ExponentialFamily.MvNormalWeightedMeanPrecision{Float64, Vector{Float64}, Matrix{Float64}} |
| log scale | undefined: the message rule for BIFMHelper towards :in under MessagePassingRulesBase.DefaultAlgorithm declares no `logscale` |
Inputs
| edge | value |
|---|
Rule
| declared inputs | m[:out]::Any |
|---|---|
| algorithm | DefaultAlgorithm() |
| log scale | none |
| defined | src/bifm_helper.jl:44 |
| body | args->args.m[:out] |
Limitations
- No free energy: its average energy throws a
BIFMFreeEnergyError. - It is meaningful only at the start of a chain of
BIFMnodes.
API
BIFMMessagePassingRules.BIFMHelper — Type
BIFMHelperThe stochastic node that starts a chain of BIFM nodes, out ~ BIFMHelper(in), with out the first state and in its prior. It turns the backward pass into the forward one: towards in it passes the backward message on out through, and towards out it sends the marginal of in as a TerminalProdArgument, the starting marginal of the forward pass.
Interfaces
out: the first state of the chain;in: its prior.
Its rule towards in reads the message on out, and its rule towards out the marginal of in, of any type: the model keeps in and out in separate clusters, q(in) q(out). It runs under the default algorithm, and needs none.
Limitations
- No free energy. Its average energy throws a
BIFMFreeEnergyError.
Examples
julia> result = @call_message_update_rule(
node = BIFMHelper, target = :out,
q = (in = MvNormalMeanCovariance([1.0], [2.0;;]),),
);
julia> getresult(result) isa TerminalProdArgument
trueSee also BIFM, BIFMSmoother.