Infer.NET user guide : The Infer.NET Modelling API
The importance of using SetTo
The New/SetTo constructs are crucial when using branches. Suppose in the scalar mixture model on the previous page, we used ordinary C# assignments:
Variable<int> c = Variable.Discrete(new double[] { 0.5, 0.5 });
Variable<double> x = Variable.New<double>();
using (Variable.Case(c,0))
{
// incorrect!!
x = Variable.GaussianFromMeanAndVariance(1,1);
}
using (Variable.Case(c,1))
{
// incorrect!! - clobbers the assignment to x above
x = Variable.GaussianFromMeanAndVariance(2,1);
}
This code fails because of the imperative execution of C#. The second assignment to x destroys the random variable created in the first case. As the C# equality operator cannot be overridden, the Infer.NET API cannot intercept this assignment to provide different behaivour. Instead, Infer.NET provides New/SetTo to allow both definitions to exist in the model, with switching done at runtime. The correct code is:
Variable<int> c = Variable.Discrete(new double[] { 0.5, 0.5 });
Variable<double> x = Variable.New<double>();
using (Variable.Case(c,0))
{
// correct
x.SetTo(Variable.GaussianFromMeanAndVariance(1,1));
}
using (Variable.Case(c,1))
{
// correct - the previous definition of x is retained
x.SetTo(Variable.GaussianFromMeanAndVariance(2,1));
}
For more help with building mixture models, see the Mixture of Gaussians tutorial.
Another thing to note about assignment and SetTo
is that you should never assign one variable directly to another, like so:
// incorrect!! - two references to the same variable object
observedLabel = label;
// incorrect!! - two references to the same variable object
observedLabel.SetTo(label);
Instead make a new variable using Variable.Copy
:
observedLabel.SetTo(Variable.Copy(label));