Answered by:
A Better Way to Create an Array of Constant Bernoulli Distr.? (Migrated from community.research.microsoft.com)

Question
-
nbeckman posted on 07-02-2010 1:02 PM
Hi,
Looks like I've been asking a lot of questions here recently! Sorry for my ignorance, but I really appreciate the help and the hard work the Infer.NET team has done.
Sadly, I am getting to a point where my models are so large that they are causing issues at run-time. I am wondering if there is a more efficient way to do what I am doing (and from analyzing the generated code, it appears that there should be).
Here is a simplified notion of what I am doing: Basically, I have a bunch of very large arrays of boolean random variables. My arrays are something on the order of 80,000 variables large. Then I take sub-arrays from the large arrays, and say that certain sub-arrays both must be true (logical AND), and importantly, that they both must be true with some high probability. So my code looks something like this:
let main_array:VariableArray<bool> = ... // comes from earlier in the program
let likely = new Bernoulli(0.89) in // both sub-arrays must be true with this prob.
let ar_1_ndxs:int[] = getArray1Ndxs() in
let ar_2_ndxs:int[] = getArray2Ndxs() in // size is equal to ar_1_ndxs
let range = new Range(Array.length ar_1_ndxs) in
let ar_1 = Variable.GetItems(main_array, Variable.Constant<int>(ar_1_ndxs,range)) in
let ar_2 = Variable.GetItems(main_array, Variable.Constant<int>(ar_2_ndxs,range)) in
let AND_array = Variable.Array<bool>(range) in
let () = AND_array <- (ar_1.[range] &&& ar_2.[range]) in // We will constrain AND_array to be likely true
let likely_constants' = Array.init (Array.length ar_1_ndxs) (fun _ -> likely) in
let likely_constants = Variable.Constant<Bernoulli>(likely_constants', range) in // an array of 0.89 Bern. distrs.
Variable.ConstrainEqualRandom( AND_array.[range], likely_constants.[range] )
So I guess the first question would be, does this code even accomplish what I want, which is to provide a constraint that the elements of ar_1 AND ar_2 both must be true with high (89%) probability?
But now the real problem is the code that this generates in Model_EP.cs. The call to ConstrainEqualRandom causes a very large array of Bernoullis to be created. In my case, the array is 15,000 elements large. But the problem is (I think) that each element of the array is a constructor call. Here is a snippet:
this.vBernoulli__23 = new Bernoulli[15521] {new Bernoulli(0.89),new Bernoulli(0.89),new Bernoulli(0.89),.........
In other words, even though I want the array likely_constants to be constant, Infer.NET is creating a new object for each element. That doesn't seem so bad per-say, but for some reason this array is so big that if I try to run the Model_EP.Reset() method that contains it, the program throws a StackoverflowException before the body of the Reset method even begins to be executed. If I remove just the field initialization line above, the error does not occur.
So what I'm wondering is, isn't there a better way of creating array constants? One perhaps in which the generated code would look more like this:
Bernoulli c = new Bernoulli(0.89);
this.vBernoulli__23 = new Bernoulli[15521] {c,c,c,c,c,c,c,c,c,c,c,c,c,c,.......
I know I don't have a great understanding of the code generation process, so this may not be possible. But I am confused as to what I can do at this point.
Thanks again,
Nels
Friday, June 3, 2011 5:54 PM
Answers
-
nbeckman replied on 07-05-2010 1:16 PM
Yes! Thank-you. That worked perfectly.
Nels
- Marked as answer by Microsoft Research Friday, June 3, 2011 5:55 PM
Friday, June 3, 2011 5:55 PM
All replies
-
minka replied on 07-04-2010 1:09 PM
The answer to your first question is yes, this code does accomplish what you want. For the second question, if you want to avoid creating a large array of Bernoullis, then don't create one in your code. Instead, do this:
Variable.ConstrainEqualRandom( AND_array.[range], likely)
You don't need to declare the likely_constants array at all.
Friday, June 3, 2011 5:55 PM -
nbeckman replied on 07-05-2010 1:16 PM
Yes! Thank-you. That worked perfectly.
Nels
- Marked as answer by Microsoft Research Friday, June 3, 2011 5:55 PM
Friday, June 3, 2011 5:55 PM