# Prod implementation

`ReactiveMP.prod_analytical_rule`

— Function`prod_analytical_rule(::Type, ::Type)`

Returns either `ProdAnalyticalRuleAvailable`

or `ProdAnalyticalRuleUnknown`

for two given distribution types. Returns `ProdAnalyticalRuleUnknown`

by default.

See also: `prod`

, `ProdAnalytical`

, `ProdGeneric`

`ReactiveMP.resolve_prod_constraint`

— Function`resolve_prod_constraint(left, right)`

Given two product constraints returns a single one that has a higher priority (if possible).

See also: `prod`

, `ProdAnalytical`

, `ProdGeneric`

`Base.prod`

— Method`prod(strategy, left, right)`

`prod`

function is used to find a product of two probability distrubutions (or any other objects) over same variable (e.g. 𝓝(x|μ*1, σ*1) × 𝓝(x|μ*2, σ*2)). There are multiple strategies for prod function, e.g. `ProdAnalytical`

, `ProdGeneric`

or `ProdPreserveType`

.

**Examples:**

```
using ReactiveMP
product = prod(ProdAnalytical(), NormalMeanVariance(-1.0, 1.0), NormalMeanVariance(1.0, 1.0))
mean(product), var(product)
# output
(0.0, 0.5)
```

See also: `prod_analytical_rule`

, `ProdAnalytical`

, `ProdGeneric`

`ReactiveMP.ProdAnalytical`

— Type`ProdAnalytical`

`ProdAnalytical`

is one of the strategies for `prod`

function. This strategy uses analytical prod methods but does not constraint a prod to be in any specific form. It throws an `NoAnalyticalProdException`

if no analytical rules is available, use `ProdGeneric`

prod strategy to fallback to approximation methods.

Note: `ProdAnalytical`

ignores `missing`

values and simply returns the non-`missing`

argument. Returns `missing`

in case if both arguments are `missing`

.

See also: `prod`

, `ProdPreserveType`

, `ProdGeneric`

`ReactiveMP.ProdFinal`

— Type`ProdFinal{T}`

The `ProdFinal`

is a wrapper around a distribution. By passing it as a message along an edge of the graph the corresponding marginal is calculated as the distribution of the `ProdFinal`

. In a sense, the `ProdFinal`

ignores any further prod with any other distribution for calculating the marginal and only check for variate types of two distributions. Trying to prod two instances of `ProdFinal`

will result in an error. Note: `ProdFinal`

is not a prod strategy, as opposed to `ProdAnalytical`

and `ProdGeneric`

.

See also: [`BIFM`

]

`ReactiveMP.ProdPreserveType`

— Type`ProdPreserveType{T}`

`ProdPreserveType`

is one of the strategies for `prod`

function. This strategy constraint an output of a prod to be in some specific form. By default it fallbacks to a `ProdAnalytical`

strategy and converts an output to a prespecified type but can be overwritten for some distributions for better performance.

See also: `prod`

, `ProdAnalytical`

, `ProdPreserveTypeLeft`

, `ProdPreserveTypeRight`

`ReactiveMP.ProdPreserveTypeLeft`

— Type`ProdPreserveTypeLeft`

`ProdPreserveTypeLeft`

is one of the strategies for `prod`

function. This strategy constraint an output of a prod to be in the functional form as `left`

argument. By default it fallbacks to a `ProdPreserveType`

strategy and converts an output to a prespecified type but can be overwritten for some distributions for better performance.

See also: `prod`

, `ProdPreserveType`

, `ProdPreserveTypeRight`

`ReactiveMP.ProdPreserveTypeRight`

— Type`ProdPreserveTypeRight`

`ProdPreserveTypeRight`

is one of the strategies for `prod`

function. This strategy constraint an output of a prod to be in the functional form as `right`

argument. By default it fallbacks to a `ProdPreserveType`

strategy and converts an output to a prespecified type but can be overwritten for some distributions for better performance.

See also: `prod`

, `ProdPreserveType`

, `ProdPreserveTypeLeft`

## Dist product

`ReactiveMP.DistProduct`

— Type`DistProduct`

If inference backend cannot return an analytical solution for a product of two distributions it may fallback to the `DistProduct`

structure `DistProduct`

is useful to propagate the exact forms of two messages until it hits some approximation method for form-constraint. However `DistProduct`

cannot be used to compute statistics such as mean or variance. It has to be approximated before using in actual inference procedure.

Backend exploits form constraints specification which usually help to deal with intractable distributions products.

See also: `prod`

, `ProdGeneric`

`ReactiveMP.ProdGeneric`

— Type`ProdGeneric{C}`

`ProdGeneric`

is one of the strategies for `prod`

function. This strategy does not fail in case of no analytical rule is available, but simply creates a product tree, there all nodes represent the `prod`

function and all leaves are valid `Distribution`

object. This object does not define any statistical properties (such as `mean`

or `var`

etc) and cannot be used during the inference procedure. However this object plays imporant part in the functional form constraints implementation. In a few words this object keeps all the information of a product of messages and propagates this information in the functional form constraint.

`ProdGeneric`

has a "fallback" method, which it may or may not use under some circumstances. For example if the `fallback`

method is `ProdAnalytical`

(which is the default one) - `ProdGeneric`

will try to optimize `prod`

tree with analytical solutions where possible.

See also: `prod`

, `DistProduct`

, `ProdAnalytical`

, `ProdPreserveType`

, `prod_analytical_rule`

, `GenericLogPdfVectorisedProduct`

`ReactiveMP.GenericLogPdfVectorisedProduct`

— Type`GenericLogPdfVectorisedProduct`

An efficient **linearized** implementation of product of multiple generic log-pdf objects. This structure prevents `DistProduct`

tree from growing too much in case of identical log-pdf objects. This trick significantly reduces Julia compilation times when analytical product rules are not available but messages are of the same type. Essentially this structure linearizes leafes of the `DistProduct`

tree in case if it sees objects of the same type (via dispatch).

See also: `DistProduct`