# How to only compile once and work for both variable being observed and unobserved cases?

• ### Question

• I have a model in which I am interested in the marginal distribution of certain variables. This model has N leaf variables, n of which will be observed. n changes from time to time. So currently, for each n, Infer.Net has to compile once.

Is there a way that Infer.Net only compiles once for all n? Below is a minimum example:

class InferNetTest
{
Variable<double> _x = Variable.GaussianFromMeanAndVariance(0, 2);
Variable<double> _y;
Variable<double> _z;
Variable<Gaussian> _a = Variable.New<Gaussian>();
InferenceEngine _engine = new InferenceEngine();

public InferNetTest()
{
_y = Variable.GaussianFromMeanAndVariance(_x, 3);
_z = Variable<double>.Random(_a);
Variable.ConstrainEqual (_y, _z);
}

public void Infer()
{
_a.ObservedValue = Gaussian.Uniform ();
Console.WriteLine(_engine.Infer(_x));
_a.ObservedValue = Gaussian.PointMass (1);
Console.WriteLine(_engine.Infer(_x));

}

In the above case, _x has a Gaussian prior distribution, and _y has a Gaussian distribution conditional on _x. I would like to build a model that can infer the "posterior" distribution of _x, and try to reuse the model whether _y is observed or not.

Here, if _y is not observed, _x is just N(0, 2). But if _y is observed to be 1, then the posterior _x is N(0.4, 1.2).

The trick I tried, is to add another variable _z that has prior _a, and enforce _z equal to _y. Thus, when I would have observed _y, I set _a.ObservedValue as a Gaussian.PointMass @ observed value. When we would not have observed _y, I set _a.ObservedValue as Uniform.

This way, the model is only compiled once, and I set _a.ObservedValue accordingly.

However, when I came to the Poisson case, I struggled.

class InferNetTest
{
Variable<double> _x = Variable.GammaFromShapeAndScale(1, 2);
Variable<int> _y;
Variable<int> _z;
Variable<Poisson> _a = Variable.New<Poisson>();
InferenceEngine _engine = new InferenceEngine();
public InferNetTest()
{
_y = Variable.Poisson(_x);
_z = Variable<int>.Random(_a);
Variable.ConstrainEqual (_y, _z);
}

public void Infer()
{
_a.ObservedValue = Poisson.Uniform ();
Console.WriteLine(_engine.Infer(_x));
_a.ObservedValue = Poisson.PointMass(3);;
Console.WriteLine(_engine.Infer(_x));

}

Now it would fail because factor equal doesn't support poisson?  What's the best approach to achieve my needs? Also, I feel even in Gaussian case the workaround seems be a bit complex. Is there any other simple shortcut?

Wednesday, October 1, 2014 2:02 PM

• The best way to do this is with Variable.If, like so:

```                var yIsObserved = Variable.New<bool>();
var yObs = Variable.Observed<int>(0);
using (Variable.If(yIsObserved))
{                    _y = Variable.Poisson(_x);
Variable.ConstrainEqual(_y, yObs);
}
yIsObserved.ObservedValue = false;
Console.WriteLine(_engine.Infer(_x));
yIsObserved.ObservedValue = true;
yObs.ObservedValue = 3;
Console.WriteLine(_engine.Infer(_x));```

Wednesday, October 1, 2014 3:23 PM