# RxInfer

*Julia package for automatic Bayesian inference on a factor graph with reactive message passing.*

Given a probabilistic model, RxInfer allows for an efficient message-passing based Bayesian inference. It uses the model structure to generate an algorithm that consists of a sequence of local computations on a Forney-style factor graph (FFG) representation of the model. RxInfer.jl has been designed with a focus on efficiency, scalability and maximum performance for running inference with reactive message passing.

## Why RxInfer

Many important AI applications, including audio processing, self-driving vehicles, weather forecasting, and extended-reality video processing require continually solving an inference task in sophisticated probabilistic models with a large number of latent variables. Often, the inference task in these applications must be performed continually and in real-time in response to new observations.

Popular MC-based inference methods, such as the No U-Turn Sampler (NUTS) or Hamiltonian Monte Carlo (HMC) sampling, rely on computationally heavy sampling procedures that do not scale well to probabilistic models with thousands of latent states. Therefore, while MC-based inference is an very versatile tool, it is practically not suitable for real-time applications. While the alternative variational inference method (VI) promises to scale better to large models than sampling-based inference, VI requires the derivation of gradients of a "Variational Free Energy" cost function. For large models, manual derivation of these gradients might not be feasible, while automated "black-box" gradient methods do not scale either because they are not capable of taking advantage of sparsity or conjugate pairs in the model. Therefore, while Bayesian inference is known as the optimal data processing framework, in practice, real-time AI applications rely on much simpler, often ad hoc, data processing algorithms.

RxInfer aims to remedy these issues by running efficient Bayesian inference in sophisticated probabilistic models, taking advantage of local conjugate relationships in probabilistic models, and focusing on real-time Bayesian inference in large state-space models with thousands of latent variables. In addition, RxInfer provides a straightforward way to extend its functionality with custom factor nodes and message passing update rules. The engine is capable of running various Bayesian inference algorithms in different parts of the factor graph of a single probabilistic model. This makes it easier to explore different "what-if" scenarios and enables very efficient inference in specific cases.

## Package Features

- User friendly syntax for specification of probabilistic models, achieved with
`GraphPPL`

.- Support for hybrid models combining discrete and continuous latent variables.
- Factorization and functional form constraints specification.
- Graph visualisation and extensions with different custom plugins.
- Saving graph on a disk and re-loading it later on.

- Automatic generation of message passing algorithms, achieved with
`ReactiveMP`

.- Support for hybrid distinct message passing inference algorithm under a unified paradigm.
- Evaluation of Bethe Free Energy as a model performance measure.
- Schedule-free reactive message passing API.
- Scalability for large models with millions of parameters and observations.
- High performance.
- Inference procedure is differentiable.
- Easy to extend with custom nodes and message update rules.

**Curious about how RxInfer compares to other tools you might be considering?** We invite you to view a detailed comparison, where we put RxInfer head-to-head with other popular packages in the field.

## How to get started?

Head to the Getting started section to get up and running with RxInfer. Alternatively, explore various examples in the documentation.

## Table of Contents

- Comparison to other packages
- RxInfer.jl breakdown
- Getting started
- Model Specification
- Constraints Specification
- Meta Specification
- Debugging
- Examples overview
- Built-in Functional Forms
- Bethe Free Energy implementation in RxInfer
- Model construction in RxInfer
- Using methods from RxInfer
- Contributing to the examples

## References

- RxInfer: A Julia package for reactive real-time Bayesian inference - a reference paper for the
`RxInfer.jl`

framwork. - Reactive Probabilistic Programming for Scalable Bayesian Inference - a PhD dissertation outlining core ideas and principles behind
`RxInfer`

(link2, link3). - Variational Message Passing and Local Constraint Manipulation in Factor Graphs - describes theoretical aspects of the underlying Bayesian inference method.
- Reactive Message Passing for Scalable Bayesian Inference - describes implementation aspects of the Bayesian inference engine and performs benchmarks and accuracy comparison on various models.
- A Julia package for reactive variational Bayesian inference - a reference paper for the
`ReactiveMP.jl`

package, the underlying inference engine. - The Factor Graph Approach to Model-Based Signal Processing - an introduction to message passing and FFGs.

## Ecosystem

The `RxInfer`

is a part of the `ReactiveBayes`

ecosystem unites 3 core packages into one powerful reactive message passing-based Bayesian inference framework:

`ReactiveMP.jl`

- core package for efficient and scalable for reactive message passing`GraphPPL.jl`

- package for model and constraints specification`Rocket.jl`

- reactive programming tools

`ReactiveMP.jl`

engine is a successor of the `ForneyLab`

package. It follows the same ideas and concepts for message-passing based inference, but uses new reactive and efficient message passing implementation under the hood. The API between two packages is different due to a better flexibility, performance and new reactive approach for solving inference problems.

While these packages form the core, `RxInfer`

relies on numerous other excellent open-source packages. The developers of `RxInfer`

express their deep appreciation to the entire open-source community for their tremendous efforts.

## Index

`RxInfer.BetheFreeEnergyDefaultMarginalSkipStrategy`

`RxInfer.BetheFreeEnergyDefaultScheduler`

`RxInfer.DefaultObjectiveDiagnosticChecks`

`RxInfer.ReactiveMPNodeAliases`

`RxInfer.AutoProposal`

`RxInfer.AutoUpdateFetchMarginalArgument`

`RxInfer.AutoUpdateFetchMessageArgument`

`RxInfer.AutoUpdateMapping`

`RxInfer.AutoUpdateSpecification`

`RxInfer.AutoUpdateVariableLabel`

`RxInfer.BetheFreeEnergy`

`RxInfer.ConditionedModelGenerator`

`RxInfer.DefaultPostprocess`

`RxInfer.DeferredDataHandler`

`RxInfer.FixedMarginalFormConstraint`

`RxInfer.IndividualAutoUpdateSpecification`

`RxInfer.InferenceResult`

`RxInfer.InitializationPlugin`

`RxInfer.KeepEach`

`RxInfer.KeepLast`

`RxInfer.LeftProposal`

`RxInfer.NoopPostprocess`

`RxInfer.ObjectiveDiagnosticCheckInfs`

`RxInfer.ObjectiveDiagnosticCheckNaNs`

`RxInfer.PointMassFormConstraint`

`RxInfer.ProbabilisticModel`

`RxInfer.ReactiveMPFreeEnergyPlugin`

`RxInfer.ReactiveMPGraphPPLBackend`

`RxInfer.ReactiveMPInferenceOptions`

`RxInfer.RightProposal`

`RxInfer.RxInferenceEngine`

`RxInfer.RxInferenceEvent`

`RxInfer.SampleListFormConstraint`

`RxInfer.UnpackMarginalPostprocess`

`Base.:|`

`Base.isempty`

`GraphPPL.create_model`

`GraphPPL.getmodel`

`RxInfer.addspecification`

`RxInfer.apply_diagnostic_check`

`RxInfer.autoupdate_check_reserved_expressions`

`RxInfer.compose_simple_operators_with_brackets`

`RxInfer.condition_on`

`RxInfer.convert_init_object`

`RxInfer.default_point_mass_form_constraint_boundaries`

`RxInfer.default_point_mass_form_constraint_optimizer`

`RxInfer.default_point_mass_form_constraint_starting_point`

`RxInfer.error_datavar_constvar_randomvar`

`RxInfer.getautoupdate`

`RxInfer.getconstantvars`

`RxInfer.getdatavars`

`RxInfer.getfactornodes`

`RxInfer.getmapping`

`RxInfer.getrandomvars`

`RxInfer.getreturnval`

`RxInfer.getvardict`

`RxInfer.getvarlabels`

`RxInfer.infer`

`RxInfer.inference_postprocess`

`RxInfer.inject_tilderhs_aliases`

`RxInfer.iserror`

`RxInfer.issuccess`

`RxInfer.numautoupdates`

`RxInfer.parse_autoupdates`

`RxInfer.prepare_autoupdates_for_model`

`RxInfer.start`

`RxInfer.stop`

`RxInfer.@autoupdates`

`RxInfer.@initialization`

`RxInfer.@model`