internal void BirdCounting3() { double noise = 0.2; int maxBirds = 8; Range numBirdRange = new Range(maxBirds + 1).Named("numBirdRange"); Variable <int> numBirds = Variable.DiscreteUniform(numBirdRange).Named("numBirds"); SwitchBlock block = Variable.Switch(numBirds); Range bird = new Range(maxBirds).Named("bird"); VariableArray <bool> isMale = Variable.Array <bool>(bird).Named("isMale"); isMale[bird] = Variable.Bernoulli(0.5).ForEach(bird); Variable <int> numObserved = Variable.New <int>().Named("numObserved"); Range observedBird = new Range(numObserved).Named("observedBird"); VariableArray <bool> observedMale = Variable.Array <bool>(observedBird).Named("observedMale"); //VariableArray<int> birdIndices = Variable.Array<int>(observedBird).Named("birdIndices"); using (Variable.ForEach(observedBird)) { //birdIndices[observedBird] = Variable.DiscreteUniform(numBirds); //Variable<int> birdIndex = birdIndices[observedBird]; Variable <int> birdIndex = Variable.DiscreteUniform(bird, numBirds).Named("birdIndex"); using (Variable.Switch(birdIndex)) { #if true //Variable.ConstrainEqual(observedMale[observedBird], isMale[birdIndex]); observedMale[observedBird] = (isMale[birdIndex] == Variable.Bernoulli(1 - noise)); #else using (Variable.If(isMale[birdIndex])) { observedMale[observedBird] = Variable.Bernoulli(0.8); } using (Variable.IfNot(isMale[birdIndex])) { observedMale[observedBird] = Variable.Bernoulli(0.2); } #endif } } block.CloseBlock(); InferenceEngine engine = new InferenceEngine(); for (int numObservedInt = 6; numObservedInt <= 10; numObservedInt++) { Console.WriteLine("numObserved = {0}", numObservedInt); // weird behavior with 1 different out of >=9 obs, no obs noise bool[] data = new bool[numObservedInt]; int numObservedMale = 0; for (int i = 0; i < data.Length; i++) { data[i] = (i < numObservedMale); } numObserved.ObservedValue = data.Length; observedMale.ObservedValue = data; //Console.WriteLine("birdIndices = {0}", engine.Infer(birdIndices)); Console.WriteLine("isMale = {0}", engine.Infer(isMale)); Console.WriteLine("numBirds = {0}", engine.Infer(numBirds)); Console.WriteLine(" exact = {0}", BallCountingExact(maxBirds, numObservedInt, numObservedMale, noise)); } }
public void BallCounting2() { double noise = 0.2; int maxBalls = 8; Range ball = new Range(maxBalls).Named("ball"); Variable <int> numBalls = Variable.DiscreteUniform(maxBalls + 1).Named("numBalls"); numBalls.SetValueRange(new Range(maxBalls + 1)); SwitchBlock block = Variable.Switch(numBalls); Variable <int> numTrue = Variable.Binomial(numBalls, 0.5).Named("numTrue"); Variable <int> numObserved = Variable.New <int>().Named("numObserved"); Range observedBall = new Range(numObserved).Named("observedBall"); VariableArray <bool> observedTrue = Variable.Array <bool>(observedBall).Named("observedTrue"); using (Variable.ForEach(observedBall)) { Variable <int> ballIndex = Variable.DiscreteUniform(ball, numBalls).Named("ballIndex"); observedTrue[observedBall] = ((ballIndex < numTrue) == Variable.Bernoulli(1 - noise)); } block.CloseBlock(); InferenceEngine engine = new InferenceEngine(); for (int numObservedInt = 10; numObservedInt <= 10; numObservedInt++) { Console.WriteLine("numObserved = {0}", numObservedInt); // weird behavior with 1 different out of >=9 obs, no obs noise bool[] data = new bool[numObservedInt]; int numObservedTrue = 0; for (int i = 0; i < data.Length; i++) { data[i] = (i < numObservedTrue); } numObserved.ObservedValue = data.Length; observedTrue.ObservedValue = data; //Console.WriteLine("numTrue = {0}", engine.Infer(numTrue)); Discrete numBallsActual = engine.Infer <Discrete>(numBalls); Console.WriteLine("numBalls = {0}", numBallsActual); Discrete numBallsExpected = BallCountingExact(maxBalls, numObservedInt, numObservedTrue, noise); Console.WriteLine(" exact = {0}", numBallsExpected); Assert.True(numBallsExpected.MaxDiff(numBallsActual) < 1e-10); } }