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)); }); } }
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); } } }
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}"); } }
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); }
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); }
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); } } }
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)); }); } }
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)); }); } }
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); } }
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); } }