//[Fact]
        internal void GaussianTimesBetaTest2()
        {
            Variable<bool> evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock block = Variable.If(evidence);
            //Variable<double> x = Variable.GaussianFromMeanAndVariance(1.2, 3.4).Named("x");
            //var x = Variable.Constant<double>(1.2).Named("x"); 
            var s = Variable.Beta(5.6, 4.8).Named("s");
            //var s = Variable.GaussianFromMeanAndPrecision(0, 1).Named("s"); 
            Variable<double> y = 1.2*s;
            y.Name = "y";
            Variable.ConstrainEqualRandom(y, new Gaussian(2.7, 0.001));
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine(new VariationalMessagePassing());
            var ca = engine.GetCompiledInferenceAlgorithm(evidence, s);
            ca.Reset();

            double oldLogEvidence = double.NegativeInfinity;
            for (int i = 0; i < 1000; i++)
            {
                ca.Update(1);
                double logEvidence1 = ca.Marginal<Bernoulli>(evidence.NameInGeneratedCode).LogOdds;
                Console.WriteLine(logEvidence1);
                if (i > 20 && System.Math.Abs(logEvidence1 - oldLogEvidence) < 0.01)
                    break;
                oldLogEvidence = logEvidence1;
            }

            //Gaussian xActual = ca.Marginal<Gaussian>(x);
            Beta sActual = ca.Marginal<Beta>(s.NameInGeneratedCode);
            //Console.WriteLine("x = {0}", xActual);
            Console.WriteLine("s = {0}", sActual);
        }
예제 #2
0
        public void GPClassificationTest4()
        {
            bool[]   yData = new bool[] { false, false, true, false };
            double[] xData = new double[]
            {
                -1.555555555555556, -1.111111111111111, -0.2222222222222223, 1.555555555555555
            };
            Vector[]             xVec     = Array.ConvertAll(xData, v => Vector.Constant(1, v));
            Vector[]             basis    = new Vector[] { Vector.Zero(1) };
            IKernelFunction      kf       = new SquaredExponential(0.0);
            SparseGPFixed        sgpf     = new SparseGPFixed(kf, basis);
            Variable <bool>      evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock              block    = Variable.If(evidence);
            Variable <IFunction> f        = Variable.Random <IFunction>(new SparseGP(sgpf)).Named("f");
            Range item = new Range(xVec.Length).Named("item");
            VariableArray <Vector> x = Variable.Array <Vector>(item).Named("x");

            x.ObservedValue = xVec;
            VariableArray <bool> y = Variable.Array <bool>(item).Named("y");

            y.ObservedValue = yData;
            VariableArray <double> h = Variable.Array <double>(item).Named("h");

            h[item] = Variable.FunctionEvaluate(f, x[item]);
            y[item] = (h[item] > 0);
            block.CloseBlock();

            InferenceEngine engine        = new InferenceEngine();
            SparseGP        sgp           = engine.Infer <SparseGP>(f);
            Vector          alphaExpected = Vector.FromArray(new double[] { 0.409693797629808 });

            Console.WriteLine("alpha = {0} should be {1}", sgp.Alpha, alphaExpected);
        }
예제 #3
0
        /// <summary>
        /// Test modified EP updates
        /// </summary>
        internal void StudentIsPositiveTest()
        {
            double shape     = 1;
            Gamma  precPrior = Gamma.FromShapeAndRate(shape, shape);
            // mean=-1 causes improper messages
            double   mean = -1;
            double   evExpected;
            Gaussian xExpected = StudentIsPositiveExact(mean, precPrior, out evExpected);

            Variable <bool>   evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock           block    = Variable.If(evidence);
            Variable <double> prec     = Variable.Random(precPrior).Named("prec");
            Variable <double> x        = Variable.GaussianFromMeanAndPrecision(mean, prec).Named("x");

            Variable.ConstrainPositive(x);
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine();

            x.AddAttribute(new TraceMessages());
            //x.InitialiseTo(Gaussian.FromMeanAndVariance(-3.719, 4.836));
            //GaussianOp.ForceProper = false;
            //GaussianOp.modified = true;
            //engine.Compiler.GivePriorityTo(typeof(GaussianOp_Laplace));
            //engine.Compiler.GivePriorityTo(typeof(GaussianOp_Slow));
            GaussianOp_Laplace.modified  = true;
            GaussianOp_Laplace.modified2 = true;
            Console.WriteLine("x = {0} should be {1}", engine.Infer(x), xExpected);
            double evActual = System.Math.Exp(engine.Infer <Bernoulli>(evidence).LogOdds);

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
        }
예제 #4
0
        /// <summary>
        /// Constructs an LDA model
        /// </summary>
        /// <param name="sizeVocab">Size of vocabulary</param>
        /// <param name="numTopics">Number of topics</param>
        public LDAModel(int sizeVocab, int numTopics)
        {
            SizeVocab     = sizeVocab;
            NumTopics     = numTopics;
            ThetaSparsity = Sparsity.Dense;
            PhiSparsity   = Sparsity.ApproximateWithTolerance(0.00000000001); // Allow for round-off error
            NumDocuments  = Variable.New <int>().Named("NumDocuments");

            //---------------------------------------------
            // The model
            //---------------------------------------------
            Range D = new Range(NumDocuments).Named("D");
            Range W = new Range(SizeVocab).Named("W");
            Range T = new Range(NumTopics).Named("T");

            NumWordsInDoc = Variable.Array <int>(D).Named("NumWordsInDoc");
            Range WInD = new Range(NumWordsInDoc[D]).Named("WInD");

            // Surround model by a stochastic If block so that we can compute model evidence
            Evidence = Variable.Bernoulli(0.5).Named("Evidence");
            IfBlock evidenceBlock = Variable.If(Evidence);

            Theta = Variable.Array <Vector>(D);
            Theta.SetSparsity(ThetaSparsity);
            Theta.SetValueRange(T);
            ThetaPrior = Variable.Array <Dirichlet>(D).Named("ThetaPrior");
            Theta[D]   = Variable <Vector> .Random(ThetaPrior[D]);

            Phi = Variable.Array <Vector>(T);
            Phi.SetSparsity(PhiSparsity);
            Phi.SetValueRange(W);
            PhiPrior = Variable.Array <Dirichlet>(T).Named("PhiPrior");
            Phi[T]   = Variable <Vector> .Random(PhiPrior[T]);

            Words      = Variable.Array(Variable.Array <int>(WInD), D).Named("Words");
            WordCounts = Variable.Array(Variable.Array <double>(WInD), D).Named("WordCounts");
            using (Variable.ForEach(D))
            {
                using (Variable.ForEach(WInD))
                {
                    using (Variable.Repeat(WordCounts[D][WInD]))
                    {
                        Variable <int> topic = Variable.Discrete(Theta[D]).Named("topic");
                        using (Variable.Switch(topic))
                        {
                            Words[D][WInD] = Variable.Discrete(Phi[topic]);
                        }
                    }
                }
            }

            evidenceBlock.CloseBlock();

            ThetaInit = Variable.New <IDistribution <Vector[]> >().Named("ThetaInit");
            Theta.InitialiseTo(ThetaInit);
            Engine = new InferenceEngine(new VariationalMessagePassing());
            Engine.Compiler.ShowWarnings = false;
            Engine.ModelName             = "LDAModel";
        }
예제 #5
0
        public void GPClassificationTest2()
        {
            bool[]   yData = new bool[] { false, true, false };
            double[] xData = new double[]
            {
                -1.555555555555556, -0.2222222222222223, 1.555555555555555
            };
            Vector[]             xVec     = Array.ConvertAll(xData, v => Vector.Constant(1, v));
            Vector[]             basis    = new Vector[] { Vector.Zero(1) };
            IKernelFunction      kf       = new SquaredExponential(0.0);
            SparseGPFixed        sgpf     = new SparseGPFixed(kf, basis);
            Variable <bool>      evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock              block    = Variable.If(evidence);
            Variable <IFunction> f        = Variable.Random <IFunction>(new SparseGP(sgpf)).Named("f");
            Range item = new Range(xVec.Length).Named("item");
            VariableArray <Vector> x = Variable.Array <Vector>(item).Named("x");

            x.ObservedValue = xVec;
            VariableArray <bool> y = Variable.Array <bool>(item).Named("y");

            y.ObservedValue = yData;
            VariableArray <double> h = Variable.Array <double>(item).Named("h");

            h[item] = Variable.FunctionEvaluate(f, x[item]);
            y[item] = (h[item] > 0);
            block.CloseBlock();

            InferenceEngine engine        = new InferenceEngine();
            SparseGP        sgp           = engine.Infer <SparseGP>(f);
            Vector          alphaExpected = Vector.FromArray(new double[] { 0.573337393823702 });

            Console.WriteLine("alpha = {0} should be {1}", sgp.Alpha, alphaExpected);
            double[] xTest = new double[]
            {
                -2, -1, 0.0
            };
            Vector[] xTestVec  = Array.ConvertAll(xTest, v => Vector.Constant(1, v));
            double[] yMeanTest = new double[]
            {
                0.077592778583272, 0.347746707713812, 0.573337393823702
            };
            double[] yVarTest = new double[]
            {
                0.986784459962251, 0.734558782611933, 0.278455962249970
            };
            for (int i = 0; i < xTestVec.Length; i++)
            {
                Gaussian pred         = sgp.Marginal(xTestVec[i]);
                Gaussian predExpected = new Gaussian(yMeanTest[i], yVarTest[i]);
                Console.WriteLine("f({0}) = {1} should be {2}", xTest[i], pred, predExpected);
                Assert.True(predExpected.MaxDiff(pred) < 1e-4);
            }
            double evExpected = -2.463679892165236;
            double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
            Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-6) < 1e-4);
        }
예제 #6
0
        public void GPClassificationTest1()
        {
            bool[]               yData    = new bool[] { true };
            double[]             xData    = new double[] { -0.2222222222222223 };
            Vector[]             xVec     = Array.ConvertAll(xData, v => Vector.Constant(1, v));
            Vector[]             basis    = new Vector[] { Vector.Zero(1) };
            IKernelFunction      kf       = new SquaredExponential(0.0);
            SparseGPFixed        sgpf     = new SparseGPFixed(kf, basis);
            Variable <bool>      evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock              block    = Variable.If(evidence);
            Variable <IFunction> f        = Variable.Random <IFunction>(new SparseGP(sgpf)).Named("f");
            Range item = new Range(xVec.Length).Named("item");
            VariableArray <Vector> x = Variable.Array <Vector>(item).Named("x");

            x.ObservedValue = xVec;
            VariableArray <bool> y = Variable.Array <bool>(item).Named("y");

            y.ObservedValue = yData;
            VariableArray <double> h = Variable.Array <double>(item).Named("h");

            h[item] = Variable.FunctionEvaluate(f, x[item]);
            y[item] = (h[item] > 0);
            block.CloseBlock();

            InferenceEngine engine        = new InferenceEngine();
            SparseGP        sgp           = engine.Infer <SparseGP>(f);
            Vector          alphaExpected = Vector.FromArray(new double[] { 0.778424938343491 });

            Console.WriteLine("alpha = {0} should be {1}", sgp.Alpha, alphaExpected);
            double[] xTest = new double[]
            {
                -2, -1, 0.0
            };
            Vector[] xTestVec  = Array.ConvertAll(xTest, v => Vector.Constant(1, v));
            double[] yMeanTest = new double[]
            {
                0.105348359509159, 0.472138591390244, 0.778424938343491
            };
            double[] yVarTest = new double[]
            {
                0.988901723148729, 0.777085150520037, 0.394054615364932
            };
            for (int i = 0; i < xTestVec.Length; i++)
            {
                Gaussian pred         = sgp.Marginal(xTestVec[i]);
                Gaussian predExpected = new Gaussian(yMeanTest[i], yVarTest[i]);
                Console.WriteLine("f({0}) = {1} should be {2}", xTest[i], pred, predExpected);
                Assert.True(predExpected.MaxDiff(pred) < 1e-4);
            }
            double evExpected = -0.693147180559945;
            double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
            Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-6) < 1e-4);
        }
예제 #7
0
        /// <inheritdoc />
        public override void CreateModel(int numTweets, int numClasses, int numVocab = 0, bool withEvidence = true, bool withGoldLabels = false)
        {
            IfBlock block = null;

            if (withEvidence)
            {
                this.Evidence = Variable.Bernoulli(0.5).Named("evidence");
                block         = Variable.If(this.Evidence);
            }

            // Biased community model
            base.CreateModel(numTweets, numClasses, numVocab, false, withGoldLabels);

            // Add in the word generation conditioned on true label variable.
            this.WordsInVocabulary = new Range(numVocab).Named("wordsInVocabulary");
            this.ProbWords         = Variable.Array <Vector>(this.Labels).Named("probWords");
            this.ProbWords.SetValueRange(this.WordsInVocabulary);
            this.ProbWords.SetSparsity(Sparsity.Sparse);
            this.WordCount = Variable.Array <int>(this.Tweets).Named("wordCount");
            this.Words     = new Range(this.WordCount[this.Tweets]).Named("words");
            this.Word      = Variable.Array(Variable.Array <int>(this.Words), this.Tweets).Named("word");

            this.ProbWordsPrior         = Variable.Array <Dirichlet>(this.Labels).Named("probWordsPrior");
            this.ProbWords[this.Labels] = Variable <Vector> .Random(this.ProbWordsPrior[this.Labels]);

            this.LikelihoodExponent = Variable.Array <double>(this.Tweets).Named(nameof(this.LikelihoodExponent));

            using (Variable.ForEach(this.Tweets))
            {
                RepeatBlock repeatBlock = null;
                if (UseRepeatFactor)
                {
                    repeatBlock = Variable.Repeat(this.LikelihoodExponent[this.Tweets]);
                }

                using (Variable.Switch(this.TrueLabel[this.Tweets]))
                {
                    this.Word[this.Tweets][this.Words] = Variable.Discrete(this.ProbWords[this.TrueLabel[this.Tweets]]).ForEach(this.Words);
                }

                if (UseRepeatFactor)
                {
                    repeatBlock?.CloseBlock();
                }
            }

            if (withEvidence)
            {
                block.CloseBlock();
            }

            this.HasEvidence = withEvidence;
        }
예제 #8
0
        public void GPRegressionTest1()
        {
            double[]             yData    = new double[] { 1.036659040456137 };
            double[]             xData    = new double[] { -0.2222222222222223 };
            Vector[]             xVec     = Array.ConvertAll(xData, v => Vector.Constant(1, v));
            Vector[]             basis    = new Vector[] { xVec[0] };
            IKernelFunction      kf       = new SquaredExponential(System.Math.Log(2.0));
            SparseGPFixed        sgpf     = new SparseGPFixed(kf, basis);
            Variable <bool>      evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock              block    = Variable.If(evidence);
            Variable <IFunction> f        = Variable.Random <IFunction>(new SparseGP(sgpf)).Named("f");
            Range item = new Range(xVec.Length).Named("item");
            VariableArray <Vector> x = Variable.Array <Vector>(item).Named("x");

            x.ObservedValue = xVec;
            VariableArray <double> y = Variable.Array <double>(item).Named("y");

            y.ObservedValue = yData;
            VariableArray <double> h = Variable.Array <double>(item).Named("h");

            h[item] = Variable.FunctionEvaluate(f, x[item]);
            y[item] = Variable.GaussianFromMeanAndVariance(h[item], 0.1);
            block.CloseBlock();

            InferenceEngine engine        = new InferenceEngine();
            SparseGP        sgp           = engine.Infer <SparseGP>(f);
            Vector          alphaExpected = Vector.FromArray(new double[] { 0.942417309505579 });

            Console.WriteLine("alpha = {0} should be {1}", sgp.Alpha, alphaExpected);
            double[] xTest = new double[]
            {
                -2, -1, 0.0
            };
            Vector[] xTestVec = Array.ConvertAll(xTest, v => Vector.Constant(1, v));
            // computed by matlab/MNT/GP/test_gpr.m
            double[] yTest = new double[]
            {
                0.634848540665472, 0.873781982196160, 0.936617836728720
            };
            for (int i = 0; i < xTestVec.Length; i++)
            {
                double pred = sgp.Mean(xTestVec[i]);
                Console.WriteLine("Ef({0}) = {1} should be {2}", xTest[i], pred, yTest[i]);
                Assert.True(MMath.AbsDiff(pred, yTest[i], 1e-6) < 1e-4);
            }
            double evExpected = -1.455076334997490;
            double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
            Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-6) < 1e-4);
        }
예제 #9
0
        internal void FitNegativeBinomial()
        {
            // generate data from the model
            double r = 2;
            double p = 0.3;

            int[] data = new int[] { 1, 4, 5, 14, 0, 3, 2, 18, 0, 1, 8, 1, 4, 3, 6, 4, 9, 5, 1, 10, 5, 9, 2, 3, 3, 9, 14, 3, 5, 12 };
            int   N    = data.Length;

            Variable <bool> evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock         block    = Variable.If(evidence);
            var             rate     = Variable.GammaFromShapeAndRate(1, 1).Named("rate");
            //var shape = Variable.GammaFromShapeAndRate(1,1).Named("shape");
            var   shape  = Variable.GammaFromShapeAndRate(1, 1).Named("shape");
            var   lambda = Variable.GammaFromShapeAndRate(shape, rate).Named("lambda");
            Range Nrange = new Range(N);
            var   y      = Variable.Array <int>(Nrange).Named("y");

            y[Nrange]       = Variable.Poisson(lambda).ForEach(Nrange);
            y.ObservedValue = data;
            block.CloseBlock();
            InferenceEngine ie = new InferenceEngine(new VariationalMessagePassing());

            ie.ShowFactorGraph = true;
            var ca = ie.GetCompiledInferenceAlgorithm(evidence, rate, shape);

            ca.Reset();
            double oldLogEvidence = double.NegativeInfinity;

            for (int i = 0; i < 1000; i++)
            {
                ca.Update(1);
                double logEvidence1 = ca.Marginal <Bernoulli>(evidence.NameInGeneratedCode).LogOdds;
                Console.WriteLine(logEvidence1);
                if (i > 20 && System.Math.Abs(logEvidence1 - oldLogEvidence) < 0.01)
                {
                    break;
                }
                oldLogEvidence = logEvidence1;
            }
            Gamma  shapePost = ca.Marginal <Gamma>(shape.NameInGeneratedCode);
            Gamma  ratePost = ca.Marginal <Gamma>(rate.NameInGeneratedCode);
            double mean, variance;

            shapePost.GetMeanAndVariance(out mean, out variance);
            Console.WriteLine("shape = " + mean + " +/- " + System.Math.Sqrt(variance) + " true= " + r);
            ratePost.GetMeanAndVariance(out mean, out variance);
            Console.WriteLine("rate = " + mean + " +/- " + System.Math.Sqrt(variance) + " true= " + p / (1 - p));
        }
예제 #10
0
        public void PoissonExpTest2()
        {
            Variable <bool>   evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock           block    = Variable.If(evidence);
            Variable <double> x        = Variable.GaussianFromMeanAndVariance(1.2, 3.4).Named("x");

            Rand.Restart(12347);
            int n = 10;
            int N = 10;

            int[] data = new int[N];
            for (int i = 0; i < N; i++)
            {
                data[i] = Rand.Binomial(n, 1.0 / (double)n);
            }
            data = new int[] { 5, 6, 7 };
            Range item = new Range(data.Length).Named("item");
            VariableArray <double> ex = Variable.Array <double>(item).Named("ex");

            ex[item] = Variable.Exp(x).ForEach(item);
            VariableArray <int> y = Variable.Array <int>(item).Named("y");

            y[item] = Variable.Poisson(ex[item]);
            block.CloseBlock();
            y.ObservedValue = data;

            InferenceEngine ie = new InferenceEngine(new VariationalMessagePassing());

            var ca = ie.GetCompiledInferenceAlgorithm(evidence, x);

            double oldLogEvidence = double.NegativeInfinity;

            for (int i = 0; i < 1000; i++)
            {
                ca.Update(1);
                double logEvidence1 = ca.Marginal <Bernoulli>(evidence.NameInGeneratedCode).LogOdds;
                Console.WriteLine(logEvidence1);
                if (i > 20 && System.Math.Abs(logEvidence1 - oldLogEvidence) < 1e-10)
                {
                    break;
                }
                oldLogEvidence = logEvidence1;
            }
            Gaussian xExpected = new Gaussian(1.755071011884509, 0.055154577283323);
            Gaussian xActual   = ca.Marginal <Gaussian>(x.NameInGeneratedCode);

            Console.WriteLine("x = {0} should be {1}", xActual, xExpected);
            Assert.True(xExpected.MaxDiff(xActual) < 1e-3);
        }
예제 #11
0
        //Addition by Guy Templeton, get log evidence from learned mixing coeff.
        public double GetLogEvidence()
        {
            Variable <bool> evidence = Variable.Bernoulli(0.5).Named("evidence");
            Range           classes  = new Range(numOfClasses);
            IfBlock         block    = Variable.If(evidence);

            VectorGaussian[] wObserved = trainModel.wPrior.ObservedValue;
            VectorGaussian[] empty     = Util.ArrayInit(numOfClasses, c => (c == 0) ?
                                                        VectorGaussian.PointMass(Vector.Zero(numOfFeatures)) :
                                                        VectorGaussian.FromMeanAndPrecision(Vector.Zero(numOfFeatures), PositiveDefiniteMatrix.Identity(numOfFeatures)));
            block.CloseBlock();
            InferenceEngine engine = new InferenceEngine();

            return(engine.Infer <Bernoulli>(evidence).LogOdds);
        }
예제 #12
0
        /// <inheritdoc />
        public override void CreateModel(int numTweets, int numClasses, int numVocab = 0, bool withEvidence = true, bool withGoldLabels = false)
        {
            IfBlock block = null;

            if (withEvidence)
            {
                this.Evidence = Variable.Bernoulli(0.5).Named("evidence");
                block         = Variable.If(this.Evidence);
            }

            this.CreateModelStub(numTweets, numClasses, withGoldLabels);

            // Honest worker
            this.AbilityPrior          = Variable.Array <Beta>(this.Workers).Named("abilityPrior");
            this.Ability               = Variable.Array <double>(this.Workers).Named("ability");
            this.Ability[this.Workers] = Variable <double> .Random(this.AbilityPrior[this.Workers]);

            this.RandomGuessPrior       = Variable.New <Dirichlet>().Named("randomGuessPrior");
            this.RandomGuessProbability = Variable <Vector> .Random(this.RandomGuessPrior).Named("randomGuessProb");

            using (Variable.ForEach(this.Workers))
            {
                var trueLabels = Variable.Subarray(this.TrueLabel, this.WorkerJudgedTweetIndex[this.Workers]).Named("trueLabelSubarray");
                trueLabels.SetValueRange(this.Labels);
                using (Variable.ForEach(this.WorkerJudgment))
                {
                    var workerIsCorrect = Variable.Bernoulli(this.Ability[this.Workers]).Named("isCorrect");
                    using (Variable.If(workerIsCorrect))
                    {
                        var labelsEqual = (this.WorkerLabel[this.Workers][this.WorkerJudgment] == trueLabels[this.WorkerJudgment]).Named("labelsEqual");
                        Variable.ConstrainEqualRandom(labelsEqual, new Bernoulli(0.9999));  // Add a slight amount of noise due to Infer.NET compiler bug.
                    }

                    using (Variable.IfNot(workerIsCorrect))
                    {
                        this.WorkerLabel[this.Workers][this.WorkerJudgment] = Variable.Discrete(this.RandomGuessProbability);
                    }
                }
            }

            if (withEvidence)
            {
                block.CloseBlock();
            }

            this.HasEvidence = withEvidence;
        }
예제 #13
0
        /// <summary>
        /// Helper class to instantiate Gaussian Process regressor
        /// </summary>
        public GaussianProcessRegressor(Vector[] trainingInputs, bool closeBlock = true)
        {
            // Modelling code
            Evidence = Variable.Bernoulli(0.5).Named("evidence");
            Block    = Variable.If(Evidence);
            Prior    = Variable.New <SparseGP>().Named("prior");
            F        = Variable <IFunction> .Random(Prior).Named("f");

            X = Variable.Observed(trainingInputs).Named("x");
            J = X.Range.Named("j");

            // If generating data, we can close block here
            if (closeBlock)
            {
                Block.CloseBlock();
            }
        }
예제 #14
0
        public GaussianProcessRegressor(Vector[] trainingInputs, bool useStudentTLikelihood, double[] trainingOutputs) : this(trainingInputs, closeBlock : false)
        {
            VariableArray <double> y = Variable.Observed(trainingOutputs, J).Named("y");

            if (!useStudentTLikelihood)
            {
                // Standard Gaussian Process
                Console.WriteLine("Training a Gaussian Process regressor");
                var score = GetScore(X, F, J);
                y[J] = Variable.GaussianFromMeanAndVariance(score, 0.0);
            }
            else
            {
                // Gaussian Process with Student-t likelihood
                Console.WriteLine("Training a Gaussian Process regressor with Student-t likelihood");
                var noisyScore = GetNoisyScore(X, F, J, trainingOutputs);
                y[J] = Variable.GaussianFromMeanAndVariance(noisyScore[J], 0.0);
            }
            Block.CloseBlock();
        }
예제 #15
0
        /// <inheritdoc />
        public override void CreateModel(int numTweets, int numClasses, int numVocab = 0, bool withEvidence = true, bool withGoldLabels = false)
        {
            IfBlock block = null;

            if (withEvidence)
            {
                this.Evidence = Variable.Bernoulli(0.5).Named("evidence");
                block         = Variable.If(this.Evidence);
            }

            this.CreateModelStub(numTweets, numClasses, withGoldLabels);

            // Worker biases
            this.ProbWorkerLabelPrior = Variable.Array(Variable.Array <Dirichlet>(this.Labels), this.Workers).Named("probWorkerLabelPrior");
            this.ProbWorkerLabel      = Variable.Array(Variable.Array <Vector>(this.Labels), this.Workers).Named("probWorkerLabel");
            this.ProbWorkerLabel[this.Workers][this.Labels] = Variable <Vector> .Random(this.ProbWorkerLabelPrior[this.Workers][this.Labels]);

            this.ProbWorkerLabel.SetValueRange(this.Labels);

            // Condition on latent truth
            using (Variable.ForEach(this.Workers))
            {
                var trueLabels = Variable.Subarray(this.TrueLabel, this.WorkerJudgedTweetIndex[this.Workers]).Named("trueLabelSubarray");
                trueLabels.SetValueRange(this.Labels);
                using (Variable.ForEach(this.WorkerJudgment))
                {
                    var trueLabel = trueLabels[this.WorkerJudgment];
                    using (Variable.Switch(trueLabel))
                    {
                        this.WorkerLabel[this.Workers][this.WorkerJudgment] = Variable.Discrete(this.ProbWorkerLabel[this.Workers][trueLabel]);
                    }
                }
            }

            if (withEvidence)
            {
                block.CloseBlock();
            }

            this.HasEvidence = withEvidence;
        }
예제 #16
0
        /// <summary>
        /// Test a difficult case
        /// </summary>
        internal void StudentIsPositiveTest5()
        {
            // depending on the exact setting of priors, the messages will alternate between proper and improper
            Gamma precPrior = new Gamma(5, 0.2);
            // mean=-1 causes improper messages
            var               mean     = Variable.Random(new Gaussian(-0.9, 0.25)).Named("mean");
            Variable <bool>   evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock           block    = Variable.If(evidence);
            Variable <double> prec     = Variable.Random(precPrior).Named("prec");
            Variable <double> x        = Variable.GaussianFromMeanAndPrecision(mean, prec).Named("x");
            Variable <bool>   y        = Variable.IsPositive(x);

            Variable.ConstrainEqualRandom(y, new Bernoulli(0.8889));
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine();

            x.AddAttribute(new TraceMessages());
            Console.WriteLine(engine.Infer(x));
            //Console.WriteLine("x = {0} should be {1}", engine.Infer(x), xExpected);
            double evActual = System.Math.Exp(engine.Infer <Bernoulli>(evidence).LogOdds);
            //Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
        }
예제 #17
0
        internal void NevenaRunArrayIntervention()
        {
            int S1 = 0, S2 = 1, Y1 = 2, Y2 = 3;
            int numVar = 4;

            int[] dimVar = Enumerable.Range(0, numVar).Select(o => 2).ToArray();

            // Data
            int numData = 100;

            int[][]  dataX    = new int[numVar][];
            bool[][] dataI    = new bool[numVar][];
            int[]    observed = new int[] { Y1, Y2 };
            int[][]  parents  = new int[numVar][];
            parents[S1] = new int[0] {
            };
            parents[S2] = new int[0] {
            };
            parents[Y1] = new int[] { S2 };
            parents[Y2] = new int[] { S1, S2 };

            // here data iid (not sampled from dag)
            var coin = new Discrete(new double[2] {
                0, 1
            });

            for (int j = 0; j < numVar; j++)
            {
                dataX[j] = new int[numData];
                dataI[j] = new bool[numData];
                for (int i = 0; i < numData; i++)
                {
                    dataX[j][i] = coin.Sample();
                    dataI[j][i] = false;
                }
            }

            // Model
            Variable <bool> evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock         H1       = Variable.If(evidence);

            Range N = new Range(numData).Named("N");

            Range[] rVariables = new Range[numVar];
            for (int d = 0; d < numVar; d++)
            {
                rVariables[d] = new Range(dimVar[d]);
            }

            // Six different priors, depending on #parents and intervention
            var priorX0 = new Variable <Vector> [numVar];
            var priorX1 = new VariableArray <Vector> [numVar];
            var priorX2 = new VariableArray <VariableArray <Vector>, Vector[][]> [numVar];

            var priorXI0 = new Variable <Vector> [numVar];
            var priorXI1 = new VariableArray <Vector> [numVar];
            var priorXI2 = new VariableArray <VariableArray <Vector>, Vector[][]> [numVar];

            for (int d = 0; d < numVar; d++)
            {
                int numPar = parents[d].Length;
                if (numPar == 0)
                {
                    priorX0[d]  = Variable.DirichletSymmetric(rVariables[d], 1 / (double)dimVar[d]).Named("priorX0" + d);
                    priorXI0[d] = Variable.DirichletSymmetric(rVariables[d], 1 / (double)dimVar[d]).Named("priorXI0" + d);
                }
                if (numPar == 1)
                {
                    priorX1[d]  = CPT1(rVariables[d], rVariables[parents[d][0]]).Named("priorX1" + d);
                    priorXI1[d] = CPT1(rVariables[d], rVariables[parents[d][0]]).Named("priorXI1" + d);
                }
                if (numPar == 2)
                {
                    priorX2[d]  = CPT2(rVariables[d], rVariables[parents[d][0]], rVariables[parents[d][1]]).Named("cptX2" + d);
                    priorXI2[d] = CPT2(rVariables[d], rVariables[parents[d][0]], rVariables[parents[d][1]]).Named("cptXI2" + d);
                }
            }

            // Variable arrays
            VariableArray <int>[]  X = new VariableArray <int> [numVar];
            VariableArray <bool>[] I = new VariableArray <bool> [numVar];
            for (int d = 0; d < numVar; d++)
            {
                I[d] = Variable.Array <bool>(N).Named("I" + d);
                I[d].ObservedValue = dataI[d];

                X[d] = Variable.Array <int>(N).Named("X" + d);
                X[d].SetValueRange(rVariables[d]);

                int ind = Array.IndexOf(observed, d);
                if (ind > -1)
                {
                    X[d].ObservedValue = dataX[d];
                }
            }

            for (int d = 0; d < numVar; d++)
            {
                int numPar = parents[d].Length;

                if (numPar == 0)
                {
                    using (Variable.ForEach(N))
                    {
                        using (Variable.IfNot(I[d][N]))
                            X[d][N] = Variable.Discrete(priorX0[d]);
                        using (Variable.If(I[d][N]))
                            X[d][N] = Variable.Discrete(priorXI0[d]);
                    }
                }

                if (numPar == 1)
                {
                    int par = parents[d][0];
                    using (Variable.ForEach(N))
                    {
                        using (Variable.Switch(X[par][N]))
                        {
                            using (Variable.IfNot(I[d][N]))
                                X[d][N] = Variable.Discrete(priorX1[d][X[par][N]]);
                            using (Variable.If(I[d][N]))
                                X[d][N] = Variable.Discrete(priorXI1[d][X[par][N]]);
                        }
                    }
                }

                if (numPar == 2)
                {
                    using (Variable.ForEach(N))
                    {
                        using (Variable.Switch(X[parents[d][0]][N]))
                            using (Variable.Switch(X[parents[d][1]][N]))
                            {
                                using (Variable.IfNot(I[d][N]))
                                    X[d][N] = Variable.Discrete(priorX2[d][X[parents[d][0]][N]][X[parents[d][1]][N]]);
                                using (Variable.If(I[d][N]))
                                    X[d][N] = Variable.Discrete(priorXI2[d][X[parents[d][0]][N]][X[parents[d][1]][N]]);
                            }
                    }
                }
            }
            H1.CloseBlock();

            // Inference engine
            var ieVMP = new InferenceEngine(new VariationalMessagePassing());

            ieVMP.NumberOfIterations = 100;
            double eviVMP = ieVMP.Infer <Bernoulli>(evidence).LogOdds;

            var ieEP = new InferenceEngine(new ExpectationPropagation());

            ieEP.NumberOfIterations = 100;
            double eviEP = ieEP.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine(eviVMP + " " + eviEP);
        }
예제 #18
0
        private void GaussianFromMeanAndVarianceTest(double mm, double vm, double mx, double vx, double a, double b)
        {
            Variable <bool>   evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock           block    = Variable.If(evidence);
            Variable <double> mean     = Variable.GaussianFromMeanAndVariance(mm, vm).Named("mean");
            Variable <double> variance = Variable.GammaFromShapeAndRate(a, b).Named("variance");
            Variable <double> x        = Variable.GaussianFromMeanAndVariance(mean, variance).Named("x");

            Variable.ConstrainEqualRandom(x, new Gaussian(mx, vx));
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine();

            engine.Compiler.RecommendedQuality = QualityBand.Experimental;
            double   evExpected;
            Gaussian xExpected;
            Gamma    vExpected;

            if (a == 1 || a == 2)
            {
                double c = System.Math.Sqrt(2 * b);
                double m = c * (mx - mm);
                double v = c * c * (vx + vm);
                double Z, mu, m2u;
                VarianceGammaTimesGaussianMoments(a, m, v, out Z, out mu, out m2u);
                evExpected = System.Math.Log(Z * c);
                double vu = m2u - mu * mu;
                double r  = Double.IsPositiveInfinity(vx) ? 1.0 : vx / (vx + vm);
                double mp = r * (mu / c + mm) + (1 - r) * mx;
                double vp = r * r * vu / (c * c) + r * vm;
                xExpected = new Gaussian(mp, vp);
                double Zplus1, Zplus2;
                VarianceGammaTimesGaussianMoments(a + 1, m, v, out Zplus1, out mu, out m2u);
                VarianceGammaTimesGaussianMoments(a + 2, m, v, out Zplus2, out mu, out m2u);
                double vmp  = a / b * Zplus1 / Z;
                double vm2p = a * (a + 1) / (b * b) * Zplus2 / Z;
                double vvp  = vm2p - vmp * vmp;
                vExpected = Gamma.FromMeanAndVariance(vmp, vvp);
            }
            else
            {
                int n = 1000000;
                GaussianEstimator est   = new GaussianEstimator();
                GammaEstimator    vEst  = new GammaEstimator();
                Gaussian          xLike = new Gaussian(mx, vx);
                for (int i = 0; i < n; i++)
                {
                    double m       = Gaussian.Sample(mm, 1 / vm);
                    double v       = Rand.Gamma(a) / b;
                    double xSample = Gaussian.Sample(m, 1 / v);
                    double weight  = System.Math.Exp(xLike.GetLogProb(xSample));
                    est.Add(xSample, weight);
                    vEst.Add(v, weight);
                }
                evExpected = System.Math.Log(est.mva.Count / n);
                xExpected  = est.GetDistribution(new Gaussian());
                vExpected  = vEst.GetDistribution(new Gamma());
            }
            double evActual = engine.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
            Gaussian xActual = engine.Infer <Gaussian>(x);

            Console.WriteLine("x = {0} should be {1}", xActual, xExpected);
            Gamma vActual = engine.Infer <Gamma>(variance);

            Console.WriteLine("variance = {0} should be {1}", vActual, vExpected);
            Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-10) < 1e-4);
            Assert.True(xExpected.MaxDiff(xActual) < 1e-4);
            Assert.True(vExpected.MaxDiff(vActual) < 1e-4);
        }
예제 #19
0
        /// <summary>
        /// Constructs an LDA model
        /// </summary>
        /// <param name="sizeVocab">Size of vocabulary</param>
        /// <param name="numTopics">Number of topics</param>
        public LDAShared(int numBatches, int sizeVocab, int numTopics)
        {
            SizeVocab         = sizeVocab;
            NumTopics         = numTopics;
            ThetaSparsity     = Sparsity.Dense;
            PhiSparsity       = Sparsity.ApproximateWithTolerance(0.00000000001); // Allow for round-off error
            NumDocuments      = Variable.New <int>().Named("NumDocuments");
            NumBatches        = numBatches;
            IterationsPerPass = new int[] { 1, 3, 5, 7, 9 };

            //---------------------------------------------
            // The model
            //---------------------------------------------
            Range D = new Range(NumDocuments).Named("D");
            Range W = new Range(SizeVocab).Named("W");
            Range T = new Range(NumTopics).Named("T");

            NumWordsInDoc = Variable.Array <int>(D).Named("NumWordsInDoc");
            Range WInD = new Range(NumWordsInDoc[D]).Named("WInD");

            Evidence = SharedVariable <bool> .Random(new Bernoulli(0.5)).Named("Evidence");

            Evidence.IsEvidenceVariable = true;

            Phi = SharedVariable <Vector> .Random(T, CreateUniformDirichletArray(numTopics, sizeVocab, PhiSparsity)).Named("Phi");

            // Phi definition sub-model - just one copy
            PhiDefModel = new Model(1).Named("PhiDefModel");

            IfBlock evidencePhiDefBlock = null;

            EvidencePhiDef      = Evidence.GetCopyFor(PhiDefModel).Named("EvidencePhiDef");
            evidencePhiDefBlock = Variable.If(EvidencePhiDef);
            PhiDef = Variable.Array <Vector>(T).Named("PhiDef");
            PhiDef.SetSparsity(PhiSparsity);
            PhiDef.SetValueRange(W);
            PhiPrior  = Variable.Array <Dirichlet>(T).Named("PhiPrior");
            PhiDef[T] = Variable <Vector> .Random(PhiPrior[T]);

            Phi.SetDefinitionTo(PhiDefModel, PhiDef);
            evidencePhiDefBlock.CloseBlock();

            // Document sub-model - many copies
            DocModel = new Model(numBatches).Named("DocModel");

            IfBlock evidenceDocBlock = null;

            EvidenceDoc      = Evidence.GetCopyFor(DocModel).Named("EvidenceDoc");
            evidenceDocBlock = Variable.If(EvidenceDoc);
            Theta            = Variable.Array <Vector>(D).Named("Theta");
            Theta.SetSparsity(ThetaSparsity);
            Theta.SetValueRange(T);
            ThetaPrior = Variable.Array <Dirichlet>(D).Named("ThetaPrior");
            Theta[D]   = Variable <Vector> .Random(ThetaPrior[D]);

            PhiDoc = Phi.GetCopyFor(DocModel);
            PhiDoc.AddAttribute(new MarginalPrototype(Dirichlet.Uniform(sizeVocab, PhiSparsity)));
            Words      = Variable.Array(Variable.Array <int>(WInD), D).Named("Words");
            WordCounts = Variable.Array(Variable.Array <double>(WInD), D).Named("WordCounts");
            using (Variable.ForEach(D))
            {
                using (Variable.ForEach(WInD))
                {
                    using (Variable.Repeat(WordCounts[D][WInD]))
                    {
                        Variable <int> topic = Variable.Discrete(Theta[D]).Named("topic");
                        using (Variable.Switch(topic))
                        {
                            Words[D][WInD] = Variable.Discrete(PhiDoc[topic]);
                        }
                    }
                }
            }

            evidenceDocBlock.CloseBlock();

            // Initialization to break symmetry
            ThetaInit = Variable.Array <Dirichlet>(D).Named("ThetaInit");
            Theta[D].InitialiseTo(ThetaInit[D]);
            EnginePhiDef = new InferenceEngine(new VariationalMessagePassing());
            EnginePhiDef.Compiler.ShowWarnings = false;
            EnginePhiDef.ModelName             = "LDASharedPhiDef";

            Engine = new InferenceEngine(new VariationalMessagePassing());
            Engine.OptimiseForVariables = new IVariable[] { Theta, PhiDoc, EvidenceDoc };

            Engine.Compiler.ShowWarnings = false;
            Engine.ModelName             = "LDAShared";
            Engine.Compiler.ReturnCopies = false;
            Engine.Compiler.FreeMemory   = true;
        }
예제 #20
0
        public void CreateModel(int NumTasks, int NumClasses, int VocabSize, int numBatches = 3)
        {
            WorkerCount = Variable.New <int>().Named("WorkerCount");

            // Set up inference engine
            Engine = new InferenceEngine(new VariationalMessagePassing());

            // Set engine flags
            Engine.Compiler.WriteSourceFiles    = true;
            Engine.Compiler.UseParallelForLoops = true;

            evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock block = Variable.If(evidence);

            // Set up ranges
            n = new Range(NumTasks).Named("N");
            c = new Range(NumClasses).Named("C");
            k = new Range(WorkerCount).Named("K");
            WorkerTaskCount = Variable.Array <int>(k).Named("WorkerTaskCount");
            kn = new Range(WorkerTaskCount[k]).Named("KN");
            WorkerTaskIndex = Variable.Array(Variable.Array <int>(kn), k).Named("Task");
            WorkerTaskIndex.SetValueRange(n);

            // Initialise truth
            BackgroundLabelProbPrior = Variable.New <Dirichlet>().Named("TruthProbPrior");
            BackgroundLabelProb      = Variable <Vector> .Random(BackgroundLabelProbPrior).Named("TruthProb");

            BackgroundLabelProb.SetValueRange(c);

            // Truth distributions
            TrueLabel    = Variable.Array <int>(n).Named("Truth");
            TrueLabel[n] = Variable.Discrete(BackgroundLabelProb).ForEach(n);

            //VocabSize = Variable.New<int>();
            w        = new Range(VocabSize).Named("W");
            ProbWord = Variable.Array <Vector>(c).Named("ProbWord");
            ProbWord.SetValueRange(w);
            WordCount     = Variable.Array <int>(n).Named("WordCount");
            nw            = new Range(WordCount[n]).Named("WN");
            Words         = Variable.Array(Variable.Array <int>(nw), n).Named("Word");
            ProbWordPrior = Variable.New <Dirichlet>().Named("ProbWordPrior");
            ProbWord[c]   = Variable <Vector> .Random(ProbWordPrior).ForEach(c);

            // Initialise user profiles
            ConfusionMatrixPrior        = Variable.Array(Variable.Array <Dirichlet>(c), k).Named("WorkerConfusionMatrixPrior");
            WorkerConfusionMatrix       = Variable.Array(Variable.Array <Vector>(c), k).Named("WorkerConfusionMatrix");
            WorkerConfusionMatrix[k][c] = Variable <Vector> .Random(ConfusionMatrixPrior[k][c]);

            WorkerConfusionMatrix.SetValueRange(c);

            // Vote distributions
            WorkerLabel = Variable.Array(Variable.Array <int>(kn), k).Named("WorkerLabel");

            using (Variable.ForEach(k))
            {
                var trueLabel = Variable.Subarray(TrueLabel, WorkerTaskIndex[k]).Named("TrueLabelSubarray");
                trueLabel.SetValueRange(c);
                using (Variable.ForEach(kn))
                {
                    using (Variable.Switch(trueLabel[kn]))
                    {
                        WorkerLabel[k][kn] = Variable.Discrete(WorkerConfusionMatrix[k][trueLabel[kn]]);
                    }
                }
            }

            // Words inference
            using (Variable.ForEach(n))
            {
                using (Variable.Switch(TrueLabel[n]))
                {
                    Words[n][nw] = Variable.Discrete(ProbWord[TrueLabel[n]]).ForEach(nw);
                }
            }
            block.CloseBlock();
        }
        public void Run()
        {
            InferenceEngine engine = new InferenceEngine();

            if (!(engine.Algorithm is Algorithms.ExpectationPropagation))
            {
                Console.WriteLine("This example only runs with Expectation Propagation");
                return;
            }

            // The data
            Vector[] inputs = new Vector[]
            {
                Vector.FromArray(new double[2] {
                    0, 0
                }),
                Vector.FromArray(new double[2] {
                    0, 1
                }),
                Vector.FromArray(new double[2] {
                    1, 0
                }),
                Vector.FromArray(new double[2] {
                    0, 0.5
                }),
                Vector.FromArray(new double[2] {
                    1.5, 0
                }),
                Vector.FromArray(new double[2] {
                    0.5, 1.0
                })
            };

            bool[] outputs = { true, true, false, true, false, false };

            // Open an evidence block to allow model scoring
            Variable <bool> evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock         block    = Variable.If(evidence);

            // Set up the GP prior, a distribution over functions, which will be filled in later
            Variable <SparseGP> prior = Variable.New <SparseGP>().Named("prior");

            // The sparse GP variable - a random function
            Variable <IFunction> f = Variable <IFunction> .Random(prior).Named("f");

            // The locations to evaluate the function
            VariableArray <Vector> x = Variable.Observed(inputs).Named("x");
            Range j = x.Range.Named("j");

            // The observation model
            VariableArray <bool> y     = Variable.Observed(outputs, j).Named("y");
            Variable <double>    score = Variable.FunctionEvaluate(f, x[j]).Named("score");

            y[j] = (Variable.GaussianFromMeanAndVariance(score, 0.1) > 0);

            // Close the evidence block
            block.CloseBlock();

            // The basis
            Vector[] basis = new Vector[]
            {
                Vector.FromArray(new double[2] {
                    0.2, 0.2
                }),
                Vector.FromArray(new double[2] {
                    0.2, 0.8
                }),
                Vector.FromArray(new double[2] {
                    0.8, 0.2
                }),
                Vector.FromArray(new double[2] {
                    0.8, 0.8
                })
            };

            for (int trial = 0; trial < 3; trial++)
            {
                // The kernel
                IKernelFunction kf;
                if (trial == 0)
                {
                    kf = new SquaredExponential(-0.0);
                }
                else if (trial == 1)
                {
                    kf = new SquaredExponential(-0.5);
                }
                else
                {
                    kf = new NNKernel(new double[] { 0.0, 0.0 }, -1.0);
                }

                // Fill in the sparse GP prior
                GaussianProcess gp = new GaussianProcess(new ConstantFunction(0), kf);
                prior.ObservedValue = new SparseGP(new SparseGPFixed(gp, basis));

                // Model score
                double NNscore = engine.Infer <Bernoulli>(evidence).LogOdds;
                Console.WriteLine("{0} evidence = {1}", kf, NNscore.ToString("g4"));
            }

            // Infer the posterior Sparse GP
            SparseGP sgp = engine.Infer <SparseGP>(f);

            // Check that training set is classified correctly
            Console.WriteLine("");
            Console.WriteLine("Predictions on training set:");
            for (int i = 0; i < outputs.Length; i++)
            {
                Gaussian post     = sgp.Marginal(inputs[i]);
                double   postMean = post.GetMean();
                string   comment  = (outputs[i] == (postMean > 0.0)) ? "correct" : "incorrect";
                Console.WriteLine("f({0}) = {1} ({2})", inputs[i], post, comment);
            }
        }
예제 #22
0
        internal void BetaRegression()
        {
            int P = 8;

            double[] b = new double[P];
            for (int p = 0; p < P; p++)
            {
                b[p] = Rand.Beta(1, 1);
            }
            int N = 100;

            double[][] X = new double[N][];
            //Gaussian[][] softX = new Gaussian[N][];
            double[] Y = new double[N];
            for (int n = 0; n < N; n++)
            {
                X[n] = new double[P];
                //softX[n] = new Gaussian[P];
                Y[n] = 0;
                for (int p = 0; p < P; p++)
                {
                    X[n][p] = Rand.Normal();
                    //softX[n][p] = new Gaussian(X[n][p], 1e-4);
                    Y[n] += X[n][p] * b[p];
                }
            }

            Variable <bool>        evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock                block    = Variable.If(evidence);
            Range                  dim      = new Range(P).Named("P");
            Range                  item     = new Range(N).Named("N");
            VariableArray <double> w        = Variable.Array <double>(dim).Named("w");

            w[dim] = Variable.Beta(1, 1).ForEach(dim);
            var x        = Variable.Array(Variable.Array <double>(dim), item).Named("x");
            var softXvar = Variable.Array(Variable.Array <double>(dim), item).Named("softx");

            softXvar.ObservedValue = X;
            x[item][dim]           = Variable.GaussianFromMeanAndPrecision(softXvar[item][dim], 1e4);
            var wx = Variable.Array(Variable.Array <double>(dim), item).Named("wx");

            wx[item][dim] = x[item][dim] * w[dim];
            var sum = Variable.Array <double>(item).Named("sum");

            sum[item] = Variable.Sum(wx[item]);
            var prec = Variable.GammaFromShapeAndRate(.1, .1).Named("Noise");
            var y    = Variable.Array <double>(item).Named("y");

            y[item] = Variable.GaussianFromMeanAndPrecision(sum[item], prec);
            block.CloseBlock();
            y.ObservedValue = Y;

            InferenceEngine engine = new InferenceEngine(new VariationalMessagePassing());
            var             ca     = engine.GetCompiledInferenceAlgorithm(evidence, w);

            ca.Reset();

            double oldLogEvidence = double.NegativeInfinity;

            for (int i = 0; i < 1000; i++)
            {
                ca.Update(1);
                double logEvidence1 = ca.Marginal <Bernoulli>(evidence.NameInGeneratedCode).LogOdds;
                Console.WriteLine(logEvidence1);
                if (i > 20 && System.Math.Abs(logEvidence1 - oldLogEvidence) < 0.01)
                {
                    break;
                }
                oldLogEvidence = logEvidence1;
            }

            DistributionArray <Beta> wInferred = ca.Marginal <DistributionArray <Beta> >(w.NameInGeneratedCode);

            for (int p = 0; p < P; p++)
            {
                Console.WriteLine("w[{0}] = {1} +/- {2} should be {3}",
                                  p, wInferred[p].GetMean(), System.Math.Sqrt(wInferred[p].GetVariance()), b[p]);
            }
        }
예제 #23
0
        public void GatedOutcomeAreEqualTest()
        {
            foreach (var algorithm in new Models.Attributes.IAlgorithm[] { new ExpectationPropagation(), new VariationalMessagePassing() })
            {
                Variable <bool>    evidence = Variable.Bernoulli(0.5).Named("evidence");
                IfBlock            block    = Variable.If(evidence);
                Vector             priorA   = Vector.FromArray(0.1, 0.9);
                Vector             priorB   = Vector.FromArray(0.2, 0.8);
                Variable <Outcome> a        = Variable.EnumDiscrete <Outcome>(priorA).Named("a");
                Variable <Outcome> b        = Variable.EnumDiscrete <Outcome>(priorB).Named("b");
                Variable <bool>    c        = (a == b).Named("c");
                double             priorC   = 0.3;
                Variable.ConstrainEqualRandom(c, new Bernoulli(priorC));
                block.CloseBlock();

                InferenceEngine engine = new InferenceEngine(algorithm);

                double probEqual = priorA.Inner(priorB);
                double evPrior   = 0;
                for (int atrial = 0; atrial < 2; atrial++)
                {
                    if (atrial == 1)
                    {
                        a.ObservedValue = Outcome.Bad;
                        probEqual       = priorB[1];
                        c.ClearObservedValue();
                        evPrior   = System.Math.Log(priorA[1]);
                        priorA[0] = 0.0;
                        priorA[1] = 1.0;
                    }
                    double evExpected = System.Math.Log(probEqual * priorC + (1 - probEqual) * (1 - priorC)) + evPrior;
                    double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;
                    Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
                    if (algorithm is ExpectationPropagation || atrial == 1)
                    {
                        Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-5) < 1e-5);
                    }

                    Bernoulli cExpected = new Bernoulli(probEqual * priorC / (probEqual * priorC + (1 - probEqual) * (1 - priorC)));
                    Bernoulli cActual   = engine.Infer <Bernoulli>(c);
                    Console.WriteLine("c = {0} should be {1}", cActual, cExpected);
                    if (algorithm is ExpectationPropagation || atrial == 1)
                    {
                        Assert.True(cExpected.MaxDiff(cActual) < 1e-10);
                    }

                    Vector postB = Vector.Zero(2);
                    postB[0] = priorB[0] * (priorA[0] * priorC + priorA[1] * (1 - priorC));
                    postB[1] = priorB[1] * (priorA[1] * priorC + priorA[0] * (1 - priorC));
                    postB.Scale(1.0 / postB.Sum());
                    DiscreteEnum <Outcome> bExpected = new DiscreteEnum <Outcome>(postB);
                    DiscreteEnum <Outcome> bActual   = engine.Infer <DiscreteEnum <Outcome> >(b);
                    Console.WriteLine("b = {0} should be {1}", bActual, bExpected);
                    if (algorithm is ExpectationPropagation || atrial == 1)
                    {
                        Assert.True(bExpected.MaxDiff(bActual) < 1e-10);
                    }

                    if (atrial == 0 && algorithm is VariationalMessagePassing)
                    {
                        continue;
                    }

                    for (int trial = 0; trial < 2; trial++)
                    {
                        if (trial == 0)
                        {
                            c.ObservedValue = true;
                            evExpected      = System.Math.Log(probEqual * priorC) + evPrior;
                        }
                        else
                        {
                            c.ObservedValue = false;
                            evExpected      = System.Math.Log((1 - probEqual) * (1 - priorC)) + evPrior;
                        }
                        evActual = engine.Infer <Bernoulli>(evidence).LogOdds;
                        Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
                        Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-5) < 1e-5);

                        if (a.IsObserved)
                        {
                            Outcome flip(Outcome x) => (x == Outcome.Good ? Outcome.Bad : Outcome.Good);

                            bExpected = DiscreteEnum <Outcome> .PointMass(c.ObservedValue?a.ObservedValue : flip(a.ObservedValue));
                        }
                        else
                        {
                            postB[0] = priorB[0] * (c.ObservedValue ? priorA[0] : priorA[1]);
                            postB[1] = priorB[1] * (c.ObservedValue ? priorA[1] : priorA[0]);
                            postB.Scale(1.0 / postB.Sum());
                            bExpected = new DiscreteEnum <Outcome>(postB);
                        }
                        bActual = engine.Infer <DiscreteEnum <Outcome> >(b);
                        Console.WriteLine("b = {0} should be {1}", bActual, bExpected);
                        Assert.True(bExpected.MaxDiff(bActual) < 1e-10);
                    }
                }
            }
        }
예제 #24
0
        public void GPClassificationTest()
        {
            bool[]   yData = new bool[] { false, false, false, true, true, true, true, false, false, false };
            double[] xData = new double[]
            {
                -2, -1.555555555555556, -1.111111111111111, -0.6666666666666667, -0.2222222222222223, 0.2222222222222223, 0.6666666666666665, 1.111111111111111,
                1.555555555555555, 2
            };
            Vector[] xVec  = Array.ConvertAll(xData, v => Vector.Constant(1, v));
            Vector[] basis = new Vector[] { xVec[1], xVec[4], xVec[8] };
            //basis = xVec;
            IKernelFunction      kf       = new SquaredExponential(0.0);
            SparseGPFixed        sgpf     = new SparseGPFixed(kf, basis);
            Variable <bool>      evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock              block    = Variable.If(evidence);
            Variable <IFunction> f        = Variable.Random <IFunction>(new SparseGP(sgpf)).Named("f");
            Range item = new Range(xVec.Length).Named("item");
            VariableArray <Vector> x = Variable.Array <Vector>(item).Named("x");

            x.ObservedValue = xVec;
            VariableArray <bool> y = Variable.Array <bool>(item).Named("y");

            y.ObservedValue = yData;
            VariableArray <double> h = Variable.Array <double>(item).Named("h");

            h[item] = Variable.FunctionEvaluate(f, x[item]);
            y[item] = (h[item] > 0);
            block.CloseBlock();

            InferenceEngine engine        = new InferenceEngine();
            SparseGP        sgp           = engine.Infer <SparseGP>(f);
            Vector          alphaExpected = Vector.FromArray(new double[] { -1.410457563120709, 1.521306076273262, -1.008600221619413 });

            Console.WriteLine("alpha = {0} should be {1}", sgp.Alpha, alphaExpected);
            double[] xTest = new double[]
            {
                -2, -1, 0.0
            };
            Vector[] xTestVec = Array.ConvertAll(xTest, v => Vector.Constant(1, v));
            // computed by matlab/MNT/GP/test_gpc.m
            double[] yMeanTest = new double[]
            {
                -0.966351175090184, -0.123034591744284, 0.762757400008960
            };
            double[] yVarTest = new double[]
            {
                0.323871157983366, 0.164009511251333, 0.162068482365962
            };
            for (int i = 0; i < xTestVec.Length; i++)
            {
                Gaussian pred         = sgp.Marginal(xTestVec[i]);
                Gaussian predExpected = new Gaussian(yMeanTest[i], yVarTest[i]);
                Console.WriteLine("f({0}) = {1} should be {2}", xTest[i], pred, predExpected);
                Assert.True(predExpected.MaxDiff(pred) < 1e-4);
            }
            double evExpected = -4.907121241357144;
            double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
            Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-6) < 1e-4);
        }
예제 #25
0
        public void GPClassificationExample()
        {
            // The data
            bool[]   ydata = { true, true, false, true, false, false };
            Vector[] xdata = new Vector[]
            {
                Vector.FromArray(new double[2] {
                    0, 0
                }),
                Vector.FromArray(new double[2] {
                    0, 1
                }),
                Vector.FromArray(new double[2] {
                    1, 0
                }),
                Vector.FromArray(new double[2] {
                    0, 0.5
                }),
                Vector.FromArray(new double[2] {
                    1.5, 0
                }),
                Vector.FromArray(new double[2] {
                    0.5, 1.0
                })
            };

            // Open an evidence block to allow model scoring
            Variable <bool> evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock         block    = Variable.If(evidence);

            // Set up the GP prior, which will be filled in later
            Variable <SparseGP> prior = Variable.New <SparseGP>().Named("prior");

            // The sparse GP variable - a distribution over functions
            Variable <IFunction> f = Variable <IFunction> .Random(prior).Named("f");

            // The locations to evaluate the function
            VariableArray <Vector> x = Variable.Constant(xdata).Named("x");
            Range j = x.Range.Named("j");

            // The observation model
            VariableArray <bool> y = Variable.Array <bool>(j).Named("y");

            y[j] = (Variable.GaussianFromMeanAndVariance(Variable.FunctionEvaluate(f, x[j]), 0.1) > 0);

            // Attach the observations
            y.ObservedValue = ydata;

            // Close the evidence block
            block.CloseBlock();

            InferenceEngine engine = new InferenceEngine();

            // The basis
            Vector[] basis = new Vector[]
            {
                Vector.FromArray(new double[2] {
                    0.2, 0.2
                }),
                Vector.FromArray(new double[2] {
                    0.2, 0.8
                }),
                Vector.FromArray(new double[2] {
                    0.8, 0.2
                }),
                Vector.FromArray(new double[2] {
                    0.8, 0.8
                })
            };

            for (int trial = 0; trial < 3; trial++)
            {
                // The kernel
                IKernelFunction kf;
                if (trial == 0)
                {
                    kf = new SquaredExponential(-0.0);
                    //kf = new LinearKernel(new double[] { 0.0, 0.0 });
                }
                else if (trial == 1)
                {
                    kf = new SquaredExponential(-0.5);
                }
                else
                {
                    kf = new NNKernel(new double[] { 0.0, 0.0 }, -1.0);
                }

                // Fill in the sparse GP prior
                prior.ObservedValue = new SparseGP(new SparseGPFixed(kf, basis));

                // Model score
                double NNscore = engine.Infer <Bernoulli>(evidence).LogOdds;
                Console.WriteLine("{0} evidence = {1}", kf, NNscore.ToString("g4"));
            }

            // Infer the posterior Sparse GP
            SparseGP sgp = engine.Infer <SparseGP>(f);

            // Check that training set is classified correctly
            Console.WriteLine();
            Console.WriteLine("Predictions on training set:");
            for (int i = 0; i < ydata.Length; i++)
            {
                Gaussian post     = sgp.Marginal(xdata[i]);
                double   postMean = post.GetMean();
                string   comment  = (ydata[i] == (postMean > 0.0)) ? "correct" : "incorrect";
                Console.WriteLine("f({0}) = {1} ({2})", xdata[i], post, comment);
                Assert.True(ydata[i] == (postMean > 0.0));
            }
        }
        public int MulticlassRegression(Vector[] xObs, int[] yObs, int C, out VectorGaussian[] bPost, out Gaussian[] meanPost, out double lowerBound, object softmaxOperator,
                                        bool trackLowerBound = false)
        {
            int             N     = xObs.Length;
            int             K     = xObs[0].Count;
            var             c     = new Range(C).Named("c");
            var             n     = new Range(N).Named("n");
            Variable <bool> ev    = null;
            IfBlock         model = null;

            if (trackLowerBound)
            {
                ev    = Variable.Bernoulli(0.5).Named("evidence");
                model = Variable.If(ev);
            }
            // model
            var B = Variable.Array <Vector>(c).Named("coefficients");

            B[c] = Variable.VectorGaussianFromMeanAndPrecision(Vector.Zero(K), PositiveDefiniteMatrix.Identity(K)).ForEach(c);
            var m = Variable.Array <double>(c).Named("mean");

            m[c] = Variable.GaussianFromMeanAndPrecision(0, 1).ForEach(c);
            Variable.ConstrainEqualRandom(B[C - 1], VectorGaussian.PointMass(Vector.Zero(K)));
            Variable.ConstrainEqualRandom(m[C - 1], Gaussian.PointMass(0));
            var x = Variable.Array <Vector>(n);

            x.ObservedValue = xObs;
            var yData = Variable.Array <int>(n);

            yData.ObservedValue = yObs;
            var g = Variable.Array(Variable.Array <double>(c), n);

            g[n][c] = Variable.InnerProduct(B[c], x[n]) + m[c];
            var p = Variable.Array <Vector>(n);

            p[n] = Variable.Softmax(g[n]);
            using (Variable.ForEach(n))
                yData[n] = Variable.Discrete(p[n]);
            if (trackLowerBound)
            {
                model.CloseBlock();
            }
            // inference
            var ie = new InferenceEngine(new VariationalMessagePassing());

            ie.Compiler.GivePriorityTo(softmaxOperator);
            var ca        = ie.GetCompiledInferenceAlgorithm(ev, B, m);
            var start     = DateTime.Now;
            var initBound = double.NegativeInfinity;
            int i         = 0;

            lowerBound = 0;
            for (i = 1; i <= 50; i++)
            {
                ca.Update(1);
                lowerBound = ca.Marginal <Bernoulli>(ev.NameInGeneratedCode).LogOdds;
                Console.WriteLine(i + "," + lowerBound + "," + (DateTime.Now - start).TotalMilliseconds);
                if (System.Math.Abs(initBound - lowerBound) < 1e-2)
                {
                    break;
                }
                initBound = lowerBound;
                start     = DateTime.Now;
            }

            bPost    = ca.Marginal <VectorGaussian[]>(B.NameInGeneratedCode);
            meanPost = ca.Marginal <Gaussian[]>(m.NameInGeneratedCode);
            return(i);
        }
예제 #27
0
        /// <summary>
        /// Build and run a multinomial regression model.
        /// </summary>
        /// <param name="xObs">An array of vectors of observed inputs.
        /// The length of the array is the number of samples, and the
        /// length of the vectors is the number of input features. </param>
        /// <param name="yObs">An array of array of counts, where the first index is the sample,
        /// and the second index is the class. </param>
        /// <param name="weightsPost">The returned posterior over the coefficients.</param>
        /// <param name="biasPost">The returned posterior over the means.</param>
        public double MultinomialRegression(Vector[] xObs, int[][] yObs, out IList <VectorGaussian> weightsPost, out IList <Gaussian> biasPost, bool trackLowerBound = true)
        {
            int             nClasses  = yObs[0].Length;
            int             nPoints   = xObs.Length;
            int             dimension = xObs[0].Count;
            var             c         = new Range(nClasses).Named("c");
            var             n         = new Range(nPoints).Named("n");
            Variable <bool> ev        = null;
            IfBlock         model     = null;

            if (trackLowerBound)
            {
                ev    = Variable.Bernoulli(0.5).Named("evidence");
                model = Variable.If(ev);
            }
            // model
            var weights = Variable.Array <Vector>(c).Named("weights");

            weights[c] = Variable.VectorGaussianFromMeanAndPrecision(Vector.Zero(dimension), PositiveDefiniteMatrix.Identity(dimension)).ForEach(c);
            var bias = Variable.Array <double>(c).Named("bias");

            bias[c] = Variable.GaussianFromMeanAndPrecision(0, 1).ForEach(c);
            Variable.ConstrainEqualRandom(weights[nClasses - 1], VectorGaussian.PointMass(Vector.Zero(dimension)));
            Variable.ConstrainEqualRandom(bias[nClasses - 1], Gaussian.PointMass(0));
            var x = Variable.Array <Vector>(n).Named("x");

            x.ObservedValue = xObs;
            var yData = Variable.Array(Variable.Array <int>(c), n).Named("y");

            yData.ObservedValue = yObs;
            var trialCounts = Variable.Array <int>(n).Named("trialCounts");

            trialCounts.ObservedValue = yObs.Select(o => o.Sum()).ToArray();
            var g = Variable.Array(Variable.Array <double>(c), n).Named("g");

            g[n][c] = Variable.InnerProduct(weights[c], x[n]) + bias[c];
            var p = Variable.Array <Vector>(n).Named("p");

            p[n] = Variable.Softmax(g[n]);
            using (Variable.ForEach(n))
                yData[n] = Variable.Multinomial(trialCounts[n], p[n]);
            if (trackLowerBound)
            {
                model.CloseBlock();
            }
            // inference
            var ie = new InferenceEngine(new VariationalMessagePassing());

            //ie.Compiler.GivePriorityTo(typeof(SaulJordanSoftmaxOp_LBFGS));
            //ie.Compiler.GivePriorityTo(typeof(ProductOfLogisticsSoftmaxOp));
            //ie.Compiler.GivePriorityTo(typeof(SaulJordanSoftmaxOp_NCVMP));
            //ie.Compiler.GivePriorityTo(typeof(SoftmaxOp_Bouchard));
            //ie.Compiler.GivePriorityTo(typeof(Blei06SoftmaxOp_NCVMP));
            ie.OptimiseForVariables = (trackLowerBound ? new IVariable[] { weights, bias, ev } : new IVariable[] { weights, bias });
            if (trackLowerBound)
            {
                ie.ShowProgress = false;
            }
            for (int iter = 1; iter <= 50; iter++)
            {
                ie.NumberOfIterations = iter;
                if (trackLowerBound)
                {
                    Console.WriteLine(ie.Infer <Bernoulli>(ev).LogOdds);
                }
            }
            weightsPost = ie.Infer <IList <VectorGaussian> >(weights);
            biasPost    = ie.Infer <IList <Gaussian> >(bias);
            return(trackLowerBound ? ie.Infer <Bernoulli>(ev).LogOdds : 0.0);
        }
예제 #28
0
        public void GPRegressionTest()
        {
            double[] yData = new double[]
            {
                -0.06416828853982412, -0.6799959810206935, -0.4541652863622044, 0.155770359928991, 1.036659040456137, 0.7353821980830825, 0.8996680933259047,
                -0.05368704705684217, -0.7905775695015919, -0.1436284683992815
            };
            double[] xData = new double[]
            {
                -2, -1.555555555555556, -1.111111111111111, -0.6666666666666667, -0.2222222222222223, 0.2222222222222223, 0.6666666666666665, 1.111111111111111,
                1.555555555555555, 2
            };
            Vector[]             xVec     = Array.ConvertAll(xData, v => Vector.Constant(1, v));
            Vector[]             basis    = new Vector[] { xVec[1], xVec[4], xVec[8] };
            IKernelFunction      kf       = new SquaredExponential(System.Math.Log(2.0));
            SparseGPFixed        sgpf     = new SparseGPFixed(kf, basis);
            Variable <bool>      evidence = Variable.Bernoulli(0.5).Named("evidence");
            IfBlock              block    = Variable.If(evidence);
            Variable <IFunction> f        = Variable.Random <IFunction>(new SparseGP(sgpf)).Named("f");
            Range item = new Range(xVec.Length).Named("item");
            VariableArray <Vector> x = Variable.Array <Vector>(item).Named("x");

            x.ObservedValue = xVec;
            VariableArray <double> y = Variable.Array <double>(item).Named("y");

            y.ObservedValue = yData;
            VariableArray <double> h = Variable.Array <double>(item).Named("h");

            h[item] = Variable.FunctionEvaluate(f, x[item]);
            y[item] = Variable.GaussianFromMeanAndVariance(h[item], 0.1);
            block.CloseBlock();

            InferenceEngine        engine        = new InferenceEngine();
            SparseGP               sgp           = engine.Infer <SparseGP>(f);
            Vector                 alphaExpected = Vector.FromArray(new double[] { -3.250044160725389, 4.579296091435270, -2.227005562666341 });
            PositiveDefiniteMatrix betaExpected  = new PositiveDefiniteMatrix(new double[, ]
            {
                { 3.187555652658986, -3.301824438047169, 1.227566907279797 },
                { -3.30182443804717, 5.115027119603418, -2.373085083966294 },
                { 1.227566907279797, -2.373085083966294, 2.156308696222915 }
            });

            Console.WriteLine("alpha = {0} should be {1}", sgp.Alpha, alphaExpected);
            Console.WriteLine(StringUtil.JoinColumns("beta = ", sgp.Beta, " should be ", betaExpected));
            double[] xTest = new double[]
            {
                -2, -1, 0.0
            };
            Vector[] xTestVec = Array.ConvertAll(xTest, v => Vector.Constant(1, v));
            // computed by matlab/MNT/GP/test_gpr.m
            double[] yMeanTest = new double[]
            {
                -0.544583265595561, 0.134323399801302, 0.503623822120711
            };
            double[] yVarTest = new double[]
            {
                0.058569682375201, 0.022695532903985, 0.024439582002951
            };
            for (int i = 0; i < xTestVec.Length; i++)
            {
                Gaussian pred         = sgp.Marginal(xTestVec[i]);
                Gaussian predExpected = new Gaussian(yMeanTest[i], yVarTest[i]);
                Console.WriteLine("f({0}) = {1} should be {2}", xTest[i], pred, predExpected);
                Assert.True(predExpected.MaxDiff(pred) < 1e-4);
            }
            double evExpected = -13.201173794945003;
            double evActual   = engine.Infer <Bernoulli>(evidence).LogOdds;

            Console.WriteLine("evidence = {0} should be {1}", evActual, evExpected);
            Assert.True(MMath.AbsDiff(evExpected, evActual, 1e-6) < 1e-4);
        }