# \[ANN\]: RxInfer.jl 2.0 Julia package for automated Bayesian inference on a factor graph with reactive message passing

**URL:** <https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879>\
**Category:** Package Announcements\
**Tags:** reactiveprogramming, distributions, bayesian-inference, reactivemp, rxinfer\
**Created:** [November 7, 2022, 1:49pm UTC](https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879 "2022-11-07T13:49:56Z")\
**Posts on this page:** 4\
**Page:** 2

<div class="post-metadata">

**Author:** ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)\
**Post date:** [January 24, 2023, 10:16pm UTC](https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879/21 "2023-01-24T22:16:34Z")

</div>

Thank you, that is very helpful! So if I wanted to model a Gaussian Markov random field, say for example this simple one with four latent nodes (`a`-`d`) and two observations (`x` and `y`):

```julia
x
|
a---b
| |
c---d---y

```

what would be the correct way to specify it in the `@model` function?

---

<div class="post-metadata">

**Author:** ![albertpod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertpod/32/31336_2.png) [@albertpod](https://discourse.julialang.org/u/albertpod)\
**Post date:** [January 25, 2023, 11:31am UTC](https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879/22 "2023-01-25T11:31:47Z")

</div>

Hi @ElOceanografo!

To give a tiny bit of background, `RxInfer.jl` uses a particular type of [factor graphs](https://en.wikipedia.org/wiki/Factor_graph), which establishes the connection between the random variables. I will not go into details about the computational graph behind the package. Still, it technically means that if I want to implement your model, I need to add additional nodes (functions) in your graph representation.

For example, you can specify the graph as follows:

```julia
x
|
(f_x)
|
a---(f_a)---b
| |
(f_a) |
| |   
c--------(f_cb)--d--(f_d)--y

```

The difference with your specification is that I explicitly show the functional dependence between your variables. The graph I showed is still incomplete, though I hope it will help you to understand what’s missing from the `RxInfer.jl` perspective when implementing your graph.

Now, depending on the functional form of `f`s (let’s say Gaussians, i.e., `f_i(i, x) = N(i|x, 1.0) i in {x, a, d}` and `f_cb=N(d|c+b, 1.0)`) you can write the model and inference in `RxIner.jl` as:

```julia
using RxInfer

@model function loopy_model()

    y = datavar(Float64)
    x_0 = datavar(Float64)

    # variances are chosen arbitrary
    x ~ Normal(mean = x_0, var = 1.0)
    a ~ Normal(mean = x, var = 1.0) # f_x
    b ~ Normal(mean = a, var = 1.0) # f_a
    c ~ Normal(mean = a, var = 1.0) # f_a
    d ~ Normal(mean = c+b, var = 1.0) # f_cb

    y ~ Normal(mean = d, var = 1.0)
end

result = inference(
    model = loopy_model(),
    data = (y = 1.0, x_0=1.0),
    initmessages = (
        a = vague(NormalMeanPrecision),
    ),
    iterations = 50,
    free_energy = true
)

```

@model macro lets you specify the model in a probabilistic way, `RxInfer.jl` handles the graphical equivalent of the model under the hood for fast computations.

---

<div class="post-metadata">

**Author:** ![ElOceanografo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eloceanografo/32/624_2.png) [@ElOceanografo](https://discourse.julialang.org/u/ElOceanografo)\
**Post date:** [January 27, 2023, 10:41pm UTC](https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879/23 "2023-01-27T22:41:07Z")

</div>

So if I’m understanding the modeling language correctly, the left-hand side of each `~` is a node, and each node can only appear in one `~` statement. The right-hand side of each `~` corresponds to a factor. If a node has more than one edge coming into it, it needs to be explicitly written as a function of all the connected nodes. So a graph like this

```julia
x---a b---y
     \ /
      d
      |
      c
      |
      z

```

could be specified like this:

```julia
x = datavar(Float64)
y = datavar(Float64)
z = datavar(Float64)
# v is arbitrary
a ~ Normal(x, v)
b ~ Normal(y, v)
c ~ Normal(z, v)
d ~ Normal((a + b + c) / 3, v)

```

Is that right?

---

<div class="post-metadata">

**Author:** ![albertpod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albertpod/32/31336_2.png) [@albertpod](https://discourse.julialang.org/u/albertpod)\
**Post date:** [January 28, 2023, 4:37pm UTC](https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879/24 "2023-01-28T16:37:44Z")

</div>

`RxInfer.jl` uses [Forney-style Factor Graphs](https://people.binf.ku.dk/~thamelry/MLSB08/hal.pdf) (FFGs) as the graphical representation of the generative model. We use edges to represent variables and nodes for factors/functions. Indeed, you can think of the left-hand side of ~ as a variable defined by an edge (or a node in your description/ it really doesn’t matter for now). The right-hand side of ~ is indeed a factor.

If a node has more than one edge coming into it (in the case of a multi-argument function), you would need to pass all the required variables inside the function.

For example, if you have a gaussian factor node `N(y|x, z)`, it has three edges for out `y`, mean `x`, and variance `z`. In your model definition, you would have to write something like this:

```julia
...
y ~ Normal(mean=x, variance=z)
...

```

As for the model you have specified, yes, that could be an option.

[Previous page](https://discourse.julialang.org/t/ann-rxinfer-jl-2-0-julia-package-for-automated-bayesian-inference-on-a-factor-graph-with-reactive-message-passing/89879.md?page=1)
