locked
Conditionally assign one Discrete variable to another (Migrated from community.research.microsoft.com) RRS feed

  • Question

  • kuangc posted on 12-30-2008 9:31 PM

     Hello,

    Thanks for making this toolkit available, it has been really helpful.

    We are trying to conditionally assign one Discrete variable to another, but not finding an easy way to do so. For example:

    Variable<bool> varA = Variable.Bernoulli(...);
    Variable<int> varB = Variable.New<int>();
    Variable<int> varC = ...; // Initialized based on previous model variables

    using (Variable.If(varA))
    {
        // we want the mixture to take the value of varB when true
        varB.SetTo(varC); // ERROR ON THIS LINE
    }
    using (Variable.IfNot(varA))
    {
    ...
    }

    When we do this, we get a runtime InvalidOperationException on the noted line saying that "varC was not defined in this condition block." However, without this bit we can compile and find the marginal of varC without a problem. Alternatively, we tried implementing the assignment using ConstrainEqual, but then we find that varB.IsDefined remains false.

    Thanks,
    Kuang and Harr

    Friday, June 3, 2011 4:41 PM

Answers

  • John Guiver replied on 01-01-2009 9:00 AM

    Hi Kuang and Harr

    If you want to use SetTo(varC), varC must be defined within the if block. For example, the following is valid

    Variable < bool > varA = Variable .Bernoulli(0.3);
    Variable < int > varB = Variable .New< int >().Named( "B" );
    using ( Variable .If(varA))
    {
      Variable < int > varC = Variable .Discrete(0.1, 0.2, 0.7).Named( "C" );
     
    varB.SetTo(varC);
    }
    using ( Variable .IfNot(varA))
    {
     
    Variable < int > varD = Variable .Discrete(0.7, 0.2, 0.1).Named( "D" );
      varB.SetTo(varD);
    }
    InferenceEngine ie = new InferenceEngine ();
    Console .WriteLine(ie.Infer(varB));

    If the model code for varC is complex, just encapsulate it in a method call.

    If you want to use ConstrainEqual, then you must define varB, for example by giving it a uniform prior. For example:

    Variable < bool > varA = Variable .Bernoulli(0.3);
    Variable < int > varB = Variable .DiscreteUniform(3).Named( "B" );
    Variable < int > varC = Variable .Discrete(0.1, 0.2, 0.7).Named( "C" );
    Variable < int > varD = Variable .Discrete(0.7, 0.2, 0.1).Named( "D" );
    using ( Variable .If(varA))
    {
     
    Variable .ConstrainEqual< int >(varB, varC);
    }
    using ( Variable .IfNot(varA))
    {
     
    Variable .ConstrainEqual< int >(varB, varD);
    }
    InferenceEngine ie = new InferenceEngine ();
    Console .WriteLine(ie.Infer(varB));

    John G.

    Friday, June 3, 2011 4:41 PM