示例#1
0
        public void FloatPriorTest()
        {
            // edges


            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatPrior(double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatPrior(double.PositiveInfinity));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatPrior(double.NegativeInfinity));
            Assert.AreEqual(double.NegativeInfinity, Math2.FloatPrior(double.MinValue));
            Assert.AreEqual(-double.Epsilon, Math2.FloatPrior(-0.0), 1); // -0.0, double.Epsilon

            foreach (var item in _FloatData)
            {
                // swap result and x

                if (item.Distance != 1)
                {
                    continue;
                }

                double x        = item.Result;
                double expected = item.X;
                double actual   = Math2.FloatPrior(x);

                Assert2.AreNear(expected, actual, 0,
                                () => { return(string.Format("FloatPrior({0:E16}) = {1:E16}; got {2:E16}; ulps = {3}", x, expected, actual, 0)); });
            }
        }
示例#2
0
        public void EvalTestOneArray()
        {
            double[]   b0Values = { 0.0, 1.0 };
            double[][] bValues  =
            {
                new double[] {     },
                new double[] { 2.0 },
                new double[] {2.0, 2.0 },
                new double[] {2.0, 2.0, 2.0 },
                new double[] {2.0, 2.0, 2.0, 2.0 }
            };

            foreach (double b0 in b0Values)
            {
                for (int i = 0; i < b0Values.Length; i++)
                {
                    double[]      b        = bValues[i];
                    TestFraction1 f        = _Fractions1[i];
                    double        result   = ContinuedFraction.Eval(b0, 1.0, b);
                    double        expected = f.EquivalentFunction(b0, b);

                    Assert2.AreNear(expected, result, 2);
                }
            }
        }
示例#3
0
        public void EvaluatePolynomial2Test()
        {
            double[][] c = new double[][] {
                new double[] { 1.0 },
                new double[] { 0.0, 1.0 },
                new double[] { 0.0, 0.0, 1.0 },
                new double[] { 0.0, 0.0, 0.0, 1.0 },
                new double[] { 0.0, 0.0, 0.0, 0.0, 1.0 },
                new double[] { 1.0, 1.0, 1.0, 1.0, 1.0 },
            };

            Random rnd = new Random();

            for (int i = 0; i < 100; i++)
            {
                double x = rnd.NextDouble();
                double y = rnd.NextDouble();


                double a0 = 1;
                double a1 = x;
                double a2 = x * x;
                double a3 = x * x * x;
                double a4 = x * x * x * x;
                double a5 = 1.0 + x + x * x + x * x * x + x * x * x * x;

                double expected = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5))));
                double result   = Polynomial.Eval(c, x, y);
                Assert2.AreNear(expected, result, 2,
                                () => $"Polynomial.Eval(c, x, y) = {result}; Expected: {expected}");
            }
        }
示例#4
0
        public void EvalTestInfinite()
        {
            double expected, actual;

            expected = 1.0 / (Math.Sqrt(Math.E) - 1.0);
            // actual = ContinuedFraction.Eval(1.0, Series1(),tolerance,100);
            actual = ContinuedFraction.Eval(1.0, Series1());
            Assert2.AreNear(expected, actual, 10);

            expected = 1.0 / (Math.E - 1.0);
            // actual = ContinuedFraction.Eval(0.0, Series2(),tolerance,100);
            actual = ContinuedFraction.Eval(0.0, Series2());
            Assert2.AreNear(expected, actual, 10);
        }
示例#5
0
        public void EvalTestInfiniteF()
        {
            double expected, actual;

            Series1Function f1 = new Series1Function();

            expected = 1.0 / (Math.Sqrt(Math.E) - 1.0);
            // actual = ContinuedFraction.Eval(1.0, Series1(),tolerance,100);
            actual = ContinuedFraction.Eval(1.0, f1.Next);
            Assert2.AreNear(expected, actual, 10);

            Series2Function f2 = new Series2Function();

            expected = 1.0 / (Math.E - 1.0);
            // actual = ContinuedFraction.Eval(0.0, Series2(),tolerance,100);
            actual = ContinuedFraction.Eval(0.0, f2.Next);
            Assert2.AreNear(expected, actual, 10);
        }
示例#6
0
        public void EvalTestTwoArray()
        {
            double[] b0Values = { 0.0, 1.0 };

            Tuple <double[], double[]>[] abValues =
            {
                new Tuple <double[],                                                 double[]>(new double[] {     },
                                                                                               new double[] { }),
                new Tuple <double[],                                                 double[]>(new double[] { 1.0 },
                                                                                               new double[] { 2.0 }),
                new Tuple <double[],                                                 double[]>(new double[] {1.0, 1.0 },
                                                                                               new double[] { 2.0,                                                 2.0 }),
                new Tuple <double[],                                                 double[]>(new double[] {1.0, 1.0, 1.0 },
                                                                                               new double[] { 2.0,                                                 2.0, 2.0 }),
                new Tuple <double[],                                                 double[]>(new double[] {1.0, 1.0, 1.0 },
                                                                                               new double[] { 2.0,                                                 2.0, 2.0 }),

                // infinite series would =1/(Sqrt(e)-1)
                // Source:http://mathworld.wolfram.com/ContinuedFraction.html
                new Tuple <double[],                                                 double[]>(new double[] {2.0, 4.0, 6.0, 8.0 },
                                                                                               new double[] { 3.0,                                                 5.0, 7.0, 9.0 }),

                // infinite series would =1/(e-1)
                // Source: http://mathworld.wolfram.com/ContinuedFraction.html
                new Tuple <double[],                                                 double[]>(new double[] {1.0, 2.0, 3.0, 4.0 },
                                                                                               new double[] { 1.0, 2.0, 3.0, 4.0 })
            };


            foreach (double b0 in b0Values)
            {
                foreach (var abValue in abValues)
                {
                    double[] a = abValue.Item1;
                    double[] b = abValue.Item2;
                    Debug.Assert(a.Length == b.Length);
                    TestFraction2 f        = _Fractions2[a.Length];
                    double        result   = ContinuedFraction.Eval(b0, a, b);
                    double        expected = f.EquivalentFunction(b0, a, b);

                    Assert2.AreNear(expected, result, 2);
                }
            }
        }
示例#7
0
        public void FloatAdvanceTest()
        {
            // test non-symettrical behaviors - NaN, -0.0, Infinity

            for (int i = 1; i < 255; i++)
            {
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatAdvance(double.NaN, i));
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatAdvance(double.NaN, -i));
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatAdvance(double.PositiveInfinity, i));
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatAdvance(double.PositiveInfinity, -i));
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatAdvance(double.NegativeInfinity, i));
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatAdvance(double.NegativeInfinity, -i));

                Assert.AreEqual(double.PositiveInfinity, Math2.FloatAdvance(double.MaxValue, i));
                Assert.AreEqual(double.NegativeInfinity, Math2.FloatAdvance(double.MinValue, -i));

                Assert.AreEqual(double.Epsilon * (double)i, Math2.FloatAdvance(-0.0, i));   // -0.0, double.Epsilon
                Assert.AreEqual(-double.Epsilon * (double)i, Math2.FloatAdvance(-0.0, -i)); // -0.0, -double.Epsilon
            }



            foreach (var item in _FloatData)
            {
                double x        = item.X;
                int    distance = item.Distance;
                double expected = item.Result;
                double actual   = Math2.FloatAdvance(x, distance);

                Assert2.AreNear(expected, actual, 0,
                                () => { return(string.Format("FloatAdvance({0:E16},{1}) = {2:E16}; got = {3:E16}; ulps = {4}", x, distance, expected, actual, 0)); });

                // check to see that the reverse is true

                x        = item.Result;
                distance = -item.Distance;
                expected = item.X;
                actual   = Math2.FloatAdvance(x, distance);

                Assert2.AreNear(expected, actual, 0,
                                () => { return(string.Format("FloatAdvance({0:E16},{1}) = {2:E16}; got = {3:E16}; ulps = {4}", x, distance, expected, actual, 0)); });
            }
        }
示例#8
0
        public void FloatDistanceTest()
        {
            // test non-symettrical behaviors - NaN, -0.0, Infinity

            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.PositiveInfinity, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NegativeInfinity, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.MaxValue, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.MinValue, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(0.0, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(-0.0, double.NaN));

            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, double.NaN));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, double.PositiveInfinity));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, double.NegativeInfinity));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, double.MaxValue));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, double.MinValue));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, 0.0));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NaN, -0.0));

            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.PositiveInfinity, double.MaxValue));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.MaxValue, double.PositiveInfinity));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.NegativeInfinity, double.MinValue));
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.FloatDistance(double.MinValue, double.NegativeInfinity));

            Assert.AreEqual(1.0, Math2.FloatDistance(double.Epsilon, -0.0));
            Assert.AreEqual(-1.0, Math2.FloatDistance(-double.Epsilon, -0.0));
            Assert.AreEqual(-1.0, Math2.FloatDistance(-0.0, double.Epsilon));
            Assert.AreEqual(1.0, Math2.FloatDistance(-0.0, -double.Epsilon));

            // large distance

            double ZeroToMax = (double)BitConverter.DoubleToInt64Bits(double.MaxValue);
            double ZeroToMin = ZeroToMax + 1.0;
            double MaxToMin  = ZeroToMax + ZeroToMin;

            Assert.AreEqual(ZeroToMax, Math2.FloatDistance(double.MaxValue, 0));
            Assert.AreEqual(-ZeroToMax, Math2.FloatDistance(0, double.MaxValue));
            Assert.AreEqual(-ZeroToMin, Math2.FloatDistance(double.MinValue, 0));
            Assert.AreEqual(ZeroToMin, Math2.FloatDistance(0, double.MinValue));
            Assert.AreEqual(MaxToMin, Math2.FloatDistance(double.MaxValue, double.MinValue));
            Assert.AreEqual(-MaxToMin, Math2.FloatDistance(double.MinValue, double.MaxValue));


            // now test symmetrical behavior

            foreach (var item in _FloatData)
            {
                double x = item.X;
                double y = item.Result;

                double expected = item.Distance;
                double actual   = Math2.FloatDistance(y, x);

                Assert2.AreNear(expected, actual, 0,
                                () => { return(string.Format("FloatDistance({0:E16},{1:E16}) = {2:E16}; got = {3:E16}; ulps = {4}", y, x, expected, actual, 0)); });

                // Reverse parameters should yield negative answer

                expected = -item.Distance;
                actual   = Math2.FloatDistance(x, y);

                Assert2.AreNear(expected, actual, 0,
                                () => { return(string.Format("FloatDistance({0:E16},{1:E16}) = {2:E16}; got = {3:E16}; ulps = {4}", x, y, expected, actual, 0)); });
            }
        }
示例#9
0
        public void LdexpTest()
        {
            Assert.AreEqual(0.75 * Math.Pow(2, -1073), Math2.Ldexp(0.75, -1073));

            const int MaxNormalExponent = 1023;
            const int MinNormalExponent = -1022;
            const int MinDenormExponent = -1074;

            // NaN
            int[] nValues = { -1, 0, 1, 2 };
            foreach (int n in nValues)
            {
                Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.Ldexp(double.NaN, n));
            }

            // edge values
            double[] xValues = { double.PositiveInfinity, double.NegativeInfinity, 0 };
            nValues = new int[] { -1, 0, 1, 2 };
            foreach (double x in xValues)
            {
                foreach (int n in nValues)
                {
                    Assert.AreEqual(Math2.Ldexp(x, n), x);
                }
            }

            // overflow and underflow
            Assert.AreEqual(0.0, Math2.Ldexp(1, MinDenormExponent - 1));
            Assert.AreEqual(-0.0, Math2.Ldexp(-1, MinDenormExponent - 1));
            Assert.AreEqual(double.PositiveInfinity, Math2.Ldexp(1, MaxNormalExponent + 1));
            Assert.AreEqual(double.NegativeInfinity, Math2.Ldexp(-1, MaxNormalExponent + 1));


            // normal powers of 2
            for (int i = MinNormalExponent; i < MaxNormalExponent; i++)
            {
                double expected   = Math.Pow(2, i);
                double calculated = Math2.Ldexp(1, i);
                Assert2.AreNear(expected, calculated, 2,
                                () => string.Format("Ldexp(1, {0}) = {1:E16}; got {2:E16}", i, expected, calculated));

                expected   = -expected;
                calculated = Math2.Ldexp(-1, i);
                Assert2.AreNear(expected, calculated, 2,
                                () => string.Format("Ldexp(-1, {0}) = {1:E16}; got {2:E16}", i, expected, calculated));
            }

            // denorm
            for (int i = 0; i < 52; i++)
            {
                double expected = double.Epsilon * (1UL << i);
                Assert.IsTrue(expected > 0);

                int n = MinDenormExponent + i;

                double calculated = Math2.Ldexp(1, n);
                Assert2.AreNear(expected, calculated, 0,
                                () => string.Format("Ldexp(1, {0}) = {1:E16}; got {2:E16}", n, expected, calculated));


                expected   = -expected;
                calculated = Math2.Ldexp(-1, n);
                Assert2.AreNear(expected, calculated, 0,
                                () => string.Format("Ldexp(-1, {0}) = {1:E16}; got {2:E16}", n, expected, calculated));
            }


            // denorm
            for (int i = 0; i < 52; i++)
            {
                double expected = double.Epsilon * (1UL << i);
                Assert.IsTrue(expected > 0);

                double calculated = Math2.Ldexp(double.Epsilon, i);
                Assert2.AreNear(expected, calculated, 0,
                                () => string.Format("Ldexp(double.Epsilon, {0}) = {1:E16}; got {2:E16}", i, expected, calculated));

                expected   = -expected;
                calculated = Math2.Ldexp(-double.Epsilon, i);
                Assert2.AreNear(expected, calculated, 0,
                                () => string.Format("Ldexp(-double.Epsilon, {0}) = {1:E16}; got {2:E16}", i, expected, calculated));
            }


            foreach (var item in _LdexpData)
            {
                double x        = item.X;
                int    n        = item.N;
                double expected = item.Result;

                double computed = Math2.Ldexp(x, n);
                Assert2.AreNear(expected, computed, 1);
            }
        }
示例#10
0
        public void FrexpTest()
        {
            const int MaxNormalExponent = 1023;
            const int MinNormalExponent = -1022;
            const int MinDenormExponent = -1074;


            int    exponent;
            double mantissa;

            // Zero
            mantissa = Math2.Frexp(0.0, out exponent);
            Assert.AreEqual(0, mantissa);
            Assert.AreEqual(0, exponent);

            // NaN
            Assert2.AreEqual <Exceptions.DomainException>(double.NaN, () => Math2.Frexp(double.NaN, out exponent));

            mantissa = Math2.Frexp(double.PositiveInfinity, out exponent);
            Assert.AreEqual(double.PositiveInfinity, mantissa);

            mantissa = Math2.Frexp(double.NegativeInfinity, out exponent);
            Assert.AreEqual(double.NegativeInfinity, mantissa);

            mantissa = Math2.Frexp(double.Epsilon, out exponent);
            Assert.AreEqual(0.5, mantissa);
            Assert.AreEqual(MinDenormExponent + 1, exponent);

            mantissa = Math2.Frexp(double.MaxValue, out exponent);
            // Assert.AreEqual(0.5, mantissa);
            Assert.AreEqual(1024, exponent);

            // check normal numbers -- powers of 2
            for (int i = MinNormalExponent; i < MaxNormalExponent; i++)
            {
                double x = Math.Pow(2, i);
                mantissa = Math2.Frexp(x, out exponent);
                Assert2.AreNear(0.5, mantissa, 1);
                Assert.AreEqual(i + 1, exponent);

                x        = -x;
                mantissa = Math2.Frexp(x, out exponent);
                Assert2.AreNear(-0.5, mantissa, 1);
                Assert.AreEqual(i + 1, exponent);
            }

            // denorm
            for (int i = 0; i < 52; i++)
            {
                double x = double.Epsilon * (double)(1UL << i);
                Assert.IsTrue(x > 0);

                mantissa = Math2.Frexp(x, out exponent);
                Assert2.AreNear(0.5, mantissa, 0);
                Assert.AreEqual(MinDenormExponent + 1 + i, exponent);

                x        = -x;
                mantissa = Math2.Frexp(x, out exponent);
                Assert2.AreNear(-0.5, mantissa, 0);
                Assert.AreEqual(MinDenormExponent + 1 + i, exponent);
            }

            foreach (var item in _FrexpData)
            {
                double x        = item.X;
                double fraction = item.Fraction;
                int    exp      = item.Exponent;

                int    computed_exponent;
                double computed_fraction = Math2.Frexp(x, out computed_exponent);
                Assert2.AreNear(fraction, computed_fraction, 1);
                Assert.AreEqual(exp, computed_exponent);
            }
        }