private void GaussianProductOp_APointMass(double aMean, Gaussian Product, Gaussian B)
        {
            bool     isProper = Product.IsProper();
            Gaussian A        = Gaussian.PointMass(aMean);
            Gaussian result   = GaussianProductOp.AAverageConditional(Product, A, B);

            Console.WriteLine("{0}: {1}", A, result);
            Gaussian result2 = isProper ? GaussianProductOp_Slow.AAverageConditional(Product, A, B) : result;

            Console.WriteLine("{0}: {1}", A, result2);
            Assert.True(result.MaxDiff(result2) < 1e-6);
            var Amsg = InnerProductOp_PointB.BAverageConditional(Product, DenseVector.FromArray(B.GetMean()), new PositiveDefiniteMatrix(new double[, ] {
                { B.GetVariance() }
            }), VectorGaussian.PointMass(aMean), VectorGaussian.Uniform(1));

            //Console.WriteLine("{0}: {1}", A, Amsg);
            Assert.True(result.MaxDiff(Amsg.GetMarginal(0)) < 1e-6);
            double prevDiff = double.PositiveInfinity;

            for (int i = 3; i < 40; i++)
            {
                double v = System.Math.Pow(0.1, i);
                A       = Gaussian.FromMeanAndVariance(aMean, v);
                result2 = isProper ? GaussianProductOp.AAverageConditional(Product, A, B) : result;
                double diff = result.MaxDiff(result2);
                Console.WriteLine("{0}: {1} diff={2}", A, result2, diff.ToString("g4"));
                //Assert.True(diff <= prevDiff || diff < 1e-6);
                result2 = isProper ? GaussianProductOp_Slow.AAverageConditional(Product, A, B) : result;
                diff    = result.MaxDiff(result2);
                Console.WriteLine("{0}: {1} diff={2}", A, result2, diff.ToString("g4"));
                Assert.True(diff <= prevDiff || diff < 1e-6);
                prevDiff = diff;
            }
        }
        public void ProductOpTest()
        {
            Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
                            Gaussian.FromNatural(0.0019528178431691338, 3.25704676859826E-06),
                            Gaussian.FromNatural(-1.4311468676808659E-17, 5.4527745979495584E-21),
                            Gaussian.FromNatural(2157531.2967657731, 1830.6558666566498)).Precision > 0); // Gaussian.FromNatural()
            Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
                            Gaussian.FromNatural(6.2927332361739073E-13, 0.00099999696614431447),
                            Gaussian.FromNatural(-3.4418586572681724E-14, 4.2560312731693555E-12),
                            Gaussian.FromNatural(-2.58594546750577, 0.1)).Precision > 0); // Gaussian.FromNatural(1.262909232222487E-15, 6.6429067108186857E-15)
            Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
                            Gaussian.FromNatural(1.0947079898711334E-15, 0.00099999696759297),
                            Gaussian.FromNatural(-9.7432361496028023E-16, 2.630301623215118E-09),
                            Gaussian.FromNatural(-2.5848205615986561, 0.1)).Precision > 0); // Gaussian.FromNatural(7.0300069947451969E-17, 4.2701144269824409E-12)

            var testCases = new[]
        public void ProductOpTest3()
        {
            Gaussian Product = new Gaussian(3.207, 2.222e-06);
            Gaussian A       = new Gaussian(2.854e-06, 1.879e-05);
            Gaussian B       = new Gaussian(0, 1);
            Gaussian result  = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);

            Console.WriteLine(result);
            Assert.False(double.IsNaN(result.Precision));

            Product = Gaussian.FromNatural(2, 1);
            A       = Gaussian.FromNatural(0, 3);
            B       = Gaussian.FromNatural(0, 1);
            result  = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
            Console.WriteLine("{0}: {1}", Product, result);

            Product = Gaussian.FromNatural(129146.60457039363, 320623.20967711863);
            A       = Gaussian.FromNatural(-0.900376203577801, 0.00000001);
            B       = Gaussian.FromNatural(0, 1);
            result  = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
            Console.WriteLine("{0}: {1}", Product, result);

            Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
                            Gaussian.FromMeanAndVariance(0.0, 1000.0),
                            Gaussian.FromMeanAndVariance(2.0, 3.0),
                            Gaussian.FromMeanAndVariance(5.0, 1.0)).MaxDiff(
                            Gaussian.FromMeanAndVariance(9.911, 79.2)
                            // Gaussian.FromMeanAndVariance(12.110396063215639,3.191559311624262e+002)
                            ) < 1e-4);

            A       = new Gaussian(2, 3);
            B       = new Gaussian(4, 5);
            Product = Gaussian.PointMass(2);
            result  = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
            Console.WriteLine("{0}: {1}", Product, result);
            double prevDiff = double.PositiveInfinity;

            for (int i = 3; i < 40; i++)
            {
                double v = System.Math.Pow(0.1, i);
                Product = Gaussian.FromMeanAndVariance(2, v);
                Gaussian result2 = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
                double   diff    = result.MaxDiff(result2);
                Console.WriteLine("{0}: {1} diff={2}", Product, result2, diff.ToString("g4"));
                Assert.True(diff <= prevDiff || diff < 1e-6);
                prevDiff = diff;
            }

            Product = Gaussian.Uniform();
            result  = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
            Console.WriteLine("{0}: {1}", Product, result);
            prevDiff = double.PositiveInfinity;
            for (int i = 3; i < 40; i++)
            {
                double v = System.Math.Pow(10, i);
                Product = Gaussian.FromMeanAndVariance(2, v);
                Gaussian result2 = GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
                double   diff    = result.MaxDiff(result2);
                Console.WriteLine("{0}: {1} diff={2}", Product, result2, diff.ToString("g4"));
                Assert.True(diff <= prevDiff || diff < 1e-6);
                prevDiff = diff;
            }
        }