locked
How to perform sth like AllTrue or Sum Factor in Gibbs Sampling? RRS feed

  • Question

  • Hi, Infer.Net People,

              I know Factor "AllTrue" or "Sum" is not supported in Gibbs Sampling,  but I do want some way to summarize a VariableArray to a single value using Gibbs Sampling.  Because Gibbs sampling shows much better and robust performance in my model,  switching to EP or VMP is not a option.

    I tried to implement the Sum Operation using similar way as

    public Variable<double> Sum(VariableArray<double> array)
    {
      Range n = array.Range;
      var SumUpTo = Variable.Array<double>(n).Named("SumUpTo");
      using (var fb = Variable.ForEach(n))
      {
        var i = fb.Index;
        using (Variable.Case(i, 0))
        {
          SumUpTo[i] = Variable.Copy(array[i]);
        }
        using (Variable.If(i > 0))
        {
          SumUpTo[i] = SumUpTo[i - 1]+ array[i];
        }
      }
      var s= Variable.Copy(SumUpTo[((Variable<int>)n.Size) - 1]);
      return s;
    }

    But a error "Internal: schedule splits group 169 " pop out.

    Thank you for any help in advance!

     

    Sunday, February 1, 2015 4:11 PM

All replies


  •        I finally found a approximate way to implement a Fake AllTrue factor which can be used in Gibbs Sampling.

      public static Variable<bool> FakeAllTrue(VariableArray<bool> arr)
            {
                Variable<bool> ret = Variable.Bernoulli(0.5);
                var index = arr.Range;
                using (Variable.ForEach(index))
                {
                    using (Variable.If(arr[index]))
                    {
                        using (Variable.If(Variable.Bernoulli(1.0 / Variable.Double(index.Size))))
                        Variable.ConstrainTrue(ret);
                    }
                    using (Variable.IfNot(arr[index]))
                    {                    
                            Variable.ConstrainFalse(ret);
                    }
                }
                return ret;
            }
    
    
            public static void TestAllTrue()
            {
                int n = 4;
                var index = new Range(n);
                for (int i = 0; i < 9; i++)
                {
                    double probT = 0.1 * (i + 1);
                    VariableArray<bool> arr = Variable.Array<bool>(index);
                    arr[index] = Variable.Bernoulli(probT).ForEach(index);
                    var p1 = Variable.AllTrue(arr);
                    InferenceEngine engine = new InferenceEngine();
                    engine.ShowProgress = false;
                    Console.WriteLine("probT: " + probT);
                    Console.WriteLine("true: " + engine.Infer(p1));
                    var p2 = FakeAllTrue(arr);
                    Console.WriteLine("approx: " + engine.Infer(p2));
                }
                Console.ReadKey();
            }

    Although it is super accurate, it is better than none.

    Cheers!

    Sunday, February 8, 2015 3:36 AM