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?