John Guiver replied on 02-28-2011 9:02 AM
Hi Ali
Thanks for the question. Because Infer.NET is written as an API it is difficult when you are starting out to figure out exactly what’s
going on – especially if you are fairly new to .NET and to C#.
When you ask about
new
Vector, are you asking about new
or Vector?
If the former, this is basic C# constructor syntax and I refer you to any primer on C#. If the latter,
Vector is
an Infer.NET class representing arrays of double values which you can read about in the section on
vectors and matrices in the user guide or in the
Maths section of the API document. Similarly,
PositiveDefiniteMatrix is a positive definite matrix class which you can also
read about there.
Actually, the
Vector class
no longer has a constructor which takes a list of values as you show in the example code. The equivalent for recent versions of Infer.NET is
Vector.FromArray(0.0,0.0)which
constructs an instance of type Vector with
two elements both of which are equal to 0.0.
Variable<T> where
T is some type (such as double or Vector )
is an Infer.NET type. The angle bracket is C# syntax for generic types which you can read about in a C# book.
Variable<T>
represents a random variable over the domain T. So
Variable<Vector> represents
a random variable over a vector domain - i.e. the random variate is of type
Vector. You can read about
Variable<T> here
(and also in the
model section of the API documentation).
Similarly
VariableArray<T> is
an Infer.NET type representing a variable over the domain T which sits in a graphical model plate.
The indexing for a plate uses an Infer.NET type Range. Infer.NET overrides the standard C# indexing
to allow an instance of type VariableArray<T> to
be indexed by an instance of type Range. (Other more complex types of plate are also possible).
Variable is an Infer.NET class whose main purpose
is to provide static
methods representing different ways of creating random variables (see a C# book for
static). You can think of the class as a factory for creating random variables. Almost all the code
to build your model will involve calls to methods on this class.
In the line of code you refer to, the static method
VectorGaussianFromMeanAndPrecision is invoked to provide a statistical definition for 'means'.
This method returns a random variable of type Vector
whose prior distribution is a multivariate Gaussian distribution (VectorGaussian)with
the given mean vector and positive definite matrix precision. 'means' has previously been defined as a
VariableArray<Vector>
and 'k' has been defined as a Range. 'means[k]' is expecting a stream of variables
tagged with the range k, and this can be achieved by calling ForEach(k) method on the returned random variable as described
here.
So the sequence of events that occurs when this line of code is executed is as follows:
1.
A dense vector of 2 elements is created (Vector.FromArray(0.0,0.0))
2.
A positive definite matrix is created (PositiveDefiniteMatrix.IdentityScaledBy(2,0.01))
3.
A random variable with the given prior is formed (Variable.VectorGaussianFromMeanAndPrecision(...))
4.
Multiple identically-defined copies of the random variable are created (.ForEach(k))
5.
Which are then assigned to the elements of 'means' (means[k] =
...)
Note that no model compilation or inference happen at this point. Executing this line of code merely adds to the definition of
the model. You can think of the execution of each line of modeling code as adding an addidional variable and factor to a factor graph.
The second line you mention is similar but more straightforward. Here we are defining a scalar random variable 'weights'
to have a Dirichlet prior of the given specification. The variate type of a Dirichlet-distributed variable is a
Vector, so ‘weights’ is of type
Variable<Vector>).See
the section on
Variable types and their distributions in the user guide.
John