Пример #1
0
        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));
            }
        }
Пример #2
0
        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);
            }
        }