public void IndexOfMaximumFastTest()
        {
            int   n      = 5;
            Range item   = new Range(n).Named("item");
            var   priors = Variable <Gaussian> .Array(item);

            priors.ObservedValue = Util.ArrayInit(n, i => Gaussian.FromMeanAndVariance(i * 0.5, i));
            var x = Variable.Array <double>(item).Named("x");

            x[item] = Variable <double> .Random(priors[item]);

            var y = Variable <int> .Factor(MMath.IndexOfMaximumDouble, x);

            InferenceEngine engine = new InferenceEngine();

            engine.ShowProgress = false;
            string format  = "f4";
            var    yActual = engine.Infer <Discrete>(y);

            Console.WriteLine("Quadratic: {0}", yActual.ToString(format));

            // Monte Carlo estimate
            Rand.Restart(0);
            DiscreteEstimator est = new DiscreteEstimator(n);

            for (int iter = 0; iter < 100000; iter++)
            {
                double[] samples = Util.ArrayInit(n, i => priors.ObservedValue[i].Sample());
                int      argmax  = MMath.IndexOfMaximumDouble(samples);
                est.Add(argmax);
            }
            var yExpected = est.GetDistribution(Discrete.Uniform(n));

            Console.WriteLine("Sampling:  {0}", yExpected.ToString(format));
            Assert.True(yExpected.MaxDiff(yActual) < 1e-2);

            engine.Compiler.GivePriorityTo(typeof(IndexOfMaximumOp_Fast));
            yActual = engine.Infer <Discrete>(y);
            Console.WriteLine("Linear:    {0}", yActual.ToString(format));
            Assert.True(yExpected.MaxDiff(yActual) < 1e-2);

            bool compareApproximation = false;

            if (compareApproximation)
            {
                var yPost2 = IndexOfMaximumOp_Fast.IndexOfMaximumDoubleAverageConditional(priors.ObservedValue, Discrete.Uniform(n));
                Console.WriteLine(yPost2);
                var yPost3 = IndexOfMaximumOp_Fast.IndexOfMaximumDoubleAverageConditional2(priors.ObservedValue, Discrete.Uniform(n));
                Console.WriteLine(yPost3);
            }
        }