Asked by:
How to model the element relationship between 2 variables?
Question

In my model, variable 'a' is an element of variable 'b', which is a vector. How can I model this relationship with Infer. Net?
Tuesday, May 2, 2017 6:35 AM
All replies

You can use:
a = Variable.GetItem(b, index)
This operation is listed at the bottom of Double factors.
Tuesday, May 2, 2017 7:58 AMOwner 
Thanks so much for your reply.In my model, many elements of vector b are a. If I assign a = Variable.GetItem(b, 1) and a= Variable.GetItem(b, 2), it shows that "Cannot assign more than once".Tuesday, May 2, 2017 8:13 AM

It depends on what you are trying to do. Are you trying to constrain elements of a random vector to be equal? Or are you trying to construct a random vector B out of a random scalar A?Tuesday, May 2, 2017 8:17 AMOwner

Thanks so much.
I am trying to construct a random vector B out of a random scalar A.
Tuesday, May 2, 2017 8:34 AM 
For that, you can create an array of copies (using array[i] = Variable.Copy(a)) and then use b = Variable.Vector(array) to get a vector. However, copying a random variable is generally an indication that you are doing something wrong, and inference algorithms do not like it. Is there a particular reason why you need to do this?Tuesday, May 2, 2017 8:41 AMOwner

Sorry. Actually, I want constraint a vector b to the form that its first 2 elements are a and all the other elements are 1a.
Tuesday, May 2, 2017 8:49 AM 
You can do that using the same approach, by constructing an array of the desired form. But my point about copying variables remains.Tuesday, May 2, 2017 8:54 AMOwner

Thanks so much for your advice.
Assume we do not have scalar A now, then how can I constraint the form of B, for example, the first 2 elements of B are same?
Tuesday, May 2, 2017 9:03 AM 
Variable.ConstrainEqual(Variable.GetItem(b,0), Variable.GetItem(b,1)).
Tuesday, May 2, 2017 9:36 AMOwner 
By the way, my comment about copying variables also applies to constraining two random variables to be equal. The inference algorithms in Infer.NET do not like it.Tuesday, May 2, 2017 5:45 PMOwner

I read this thread with interest. Tom, what is the reason that the inference algorithms don't like the constraint about two random variables to be equal? Does this make sampling less efficient? Something intrinsically bad with EP or other samplers?
I am just curious to know. Constraining variables to be equal seems to be pretty reasonable in many applications.
Is there a difference when I constrain two discrete random variables to be equal versus two double random variables to be equal?
Thanks!
Thursday, May 4, 2017 6:35 PM 
It doesn't matter if the variables are discrete or continuous. Constraining them to be equal is bad for our algorithms. In the case of EP and VMP, this is because the posterior distribution is approximated as fully factorized. Variables constrained to be equal is as far from that approximation as you can get. In the case of Gibbs sampling, such a constraint will cause the sampler to get stuck since it can't move either of the variables in isolation. I'm curious what applications you have in mind where constraining variables to be equal would be considered reasonable.Friday, May 5, 2017 1:43 PMOwner

May I ask how to correct the following codes? I just want to use scalar variable WorkerConfusionMatrixDiag to construct matrix variable WorkerConfusionMatrix. WorkerConfusionMatrixDiag will be inferred with Infer.Net and WorkerConfusionMatrix is just an intermediate variable to generate data.
The bug is in the last line of the codes. It shows that "Error1 The best overloaded method match for 'MicrosoftResearch.Infer.Models.Variable.Vector(MicrosoftResearch.Infer.Models.Variable<double[]>)' has some invalid arguments"
Variable<double>[] array = new Variable <double>[c.SizeAsInt];
for (int myc1 = 0; myc1 < c.SizeAsInt; myc1++)
{
for (int myc2 = 0; myc2 < c.SizeAsInt; myc2++)
{
if (myc1 == myc2)
array[myc2] = Variable.Copy(WorkerConfusionMatrixDiag[k]);
else
array[myc2] = Variable.Copy((1WorkerConfusionMatrixDiag[k])/(c.SizeAsInt1));
}
WorkerConfusionMatrix[k, myc1] = Variable.Vector(array);
} Edited by TianYi12138 Friday, May 12, 2017 2:40 PM
Friday, May 12, 2017 2:39 PM 
'array' needs to be a VariableArray whose range is 'c'.
var array = Variable.Array<double>(c); using (ForEachBlock block = Variable.ForEach(c)) { var myc2 = block.Index; var isDiagonal = (myc1 == myc2); using (Variable.If(isDiagonal)) array[myc2] = Variable.Copy(WorkerConfusionMatrixDiag[k]); using (Variable.IfNot(isDiagonal)) array[myc2] = Variable.Copy((1  WorkerConfusionMatrixDiag[k]) / (c.SizeAsInt  1)); }
Saturday, May 13, 2017 11:06 AMOwner