public void JacobiIntegrals() { foreach (double k in TestUtilities.GenerateRealValues(1.0E-1, 1.0, 4)) { // DLMF 22.14.18 says // \int_{0}^{K(k)} \ln(\dn(t, k)) \, dt = \frac{1}{2} K(k) \ln k' double K = AdvancedMath.EllipticK(k); double k1 = Math.Sqrt(1.0 - k * k); double I1 = FunctionMath.Integrate( x => Math.Log(AdvancedMath.JacobiDn(x, k)), Interval.FromEndpoints(0.0, K) ); Assert.IsTrue(TestUtilities.IsNearlyEqual(I1, K / 2.0 * Math.Log(k1))); // If k is small, log(k1) is subject to cancellation error, so don't pick k too small. // It also gives values for the analogous integrals with \sn and \cn, // but their values involve K'(k), for which we don't have a method. // Mathworld (http://mathworld.wolfram.com/CompleteEllipticIntegraloftheSecondKind.html) says // \int_{0}^{K(k)} \dn^2(t, k) = E(k) double I2 = FunctionMath.Integrate( u => MoreMath.Sqr(AdvancedMath.JacobiDn(u, k)), Interval.FromEndpoints(0.0, K) ); Assert.IsTrue(TestUtilities.IsNearlyEqual(I2, AdvancedMath.EllipticE(k))); } }
public void EllipticLandenTransform() { foreach (double k in TestUtilities.GenerateUniformRealValues(0.0, 1.0, 8)) { double kp = Math.Sqrt(1.0 - k * k); double k1 = (1.0 - kp) / (1.0 + kp); // For complete 1st kind Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticK(k), (1.0 + k1) * AdvancedMath.EllipticK(k1) )); // For complete 2nd kind Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticE(k) + kp * AdvancedMath.EllipticK(k), (1.0 + kp) * AdvancedMath.EllipticE(k1) )); /* * foreach (double t in TestUtilities.GenerateUniformRealValues(0.0, Math.PI / 2.0, 4)) { * * double s = Math.Sin(t); * double t1 = Math.Asin((1.0 + kp) * s * Math.Sqrt(1.0 - s * s) / Math.Sqrt(1.0 - k * k * s * s)); * * // Since t1 can be > pi/2, we need to handle a larger range of angles before we can test the incomplete cases * * * } * */ } }
public void EllipticECompleteAgreement() { foreach (double k in TestUtilities.GenerateRealValues(0.01, 1.0, 8)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticE(Math.PI / 2.0, k), AdvancedMath.EllipticE(k) )); } }
public void EllipticLegendreRelation() { foreach (double k in TestUtilities.GenerateRealValues(0.01, 1.0, 8)) { double kp = Math.Sqrt(1.0 - k * k); double E = AdvancedMath.EllipticE(k); double EP = AdvancedMath.EllipticE(kp); double K = AdvancedMath.EllipticK(k); double KP = AdvancedMath.EllipticK(kp); Assert.IsTrue(TestUtilities.IsNearlyEqual(K * EP + KP * E, Math.PI / 2.0 + K * KP)); } }
public void EllipticESPecialCases() { Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(0.0), Math.PI / 2.0)); Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(1.0), 1.0)); double g2 = Math.Pow(AdvancedMath.Gamma(1.0 / 4.0), 2.0); Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticE(1.0 / Math.Sqrt(2.0)), Math.Pow(Math.PI, 3.0 / 2.0) / g2 + g2 / 8.0 / Math.Sqrt(Math.PI) )); }
public void CompleteEllipticHypergeometricAgreement() { foreach (double k in TestUtilities.GenerateRealValues(1.0E-4, 1.0, 4)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticK(k), Math.PI / 2.0 * AdvancedMath.Hypergeometric2F1(0.5, 0.5, 1.0, k * k) )); Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticE(k), Math.PI / 2.0 * AdvancedMath.Hypergeometric2F1(0.5, -0.5, 1.0, k * k) )); } }
public void EllipticEDisplacement() { foreach (int m in TestUtilities.GenerateUniformIntegerValues(-100, 100, 4)) { foreach (double phi in TestUtilities.GenerateUniformRealValues(-Math.PI / 2.0, +Math.PI / 2.0, 4)) { foreach (double k in TestUtilities.GenerateRealValues(1.0E-4, 1.0, 4)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.EllipticE(m * Math.PI + phi, k), 2 * m * AdvancedMath.EllipticE(k) + AdvancedMath.EllipticE(phi, k) )); } } } }
public void EllipticEIntegration() { foreach (double k in TestUtilities.GenerateRealValues(1.0E-2, 1.0, 8)) { // define the integrand Func <double, double> f = delegate(double t) { double z = k * Math.Sin(t); return(Math.Sqrt(1.0 - z * z)); }; // test complete integral double C = FunctionMath.Integrate(f, Interval.FromEndpoints(0.0, Math.PI / 2.0)); Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(k), C)); // test incomplete integral foreach (double phi in TestUtilities.GenerateUniformRealValues(0.0, Math.PI / 2.0, 8)) { double I = FunctionMath.Integrate(f, Interval.FromEndpoints(0.0, phi)); Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(phi, k), I)); } } }
public void HypergeometricBasicFunctions() { foreach (double x in xs) { // A&S 15.1.3 if (x < 1.0 && (x != 0.0)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.Hypergeometric2F1(1.0, 1.0, 2.0, x), -Math.Log(1.0 - x) / x )); } // A&S 15.1.5 if (x != 0.0) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.Hypergeometric2F1(0.5, 1.0, 1.5, -x * x), Math.Atan(x) / x )); } // A&S 15.1.6 if ((-1.0 <= x) && (x <= 1.0) && (x != 0.0)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( AdvancedMath.Hypergeometric2F1(0.5, 0.5, 1.5, x * x), Math.Asin(x) / x )); } // Complete elliptic integrals if ((0.0 <= x) && (x < 1.0)) { Assert.IsTrue(TestUtilities.IsNearlyEqual( Math.PI / 2.0 * AdvancedMath.Hypergeometric2F1(0.5, 0.5, 1.0, x * x), AdvancedMath.EllipticK(x) )); Assert.IsTrue(TestUtilities.IsNearlyEqual( Math.PI / 2.0 * AdvancedMath.Hypergeometric2F1(-0.5, 0.5, 1.0, x * x), AdvancedMath.EllipticE(x) )); } } }
public void EllipticPiSpecialCharacteristic() { foreach (double k in TestUtilities.GenerateRealValues(1.0E-4, 1.0, 4)) { // DLMF 19.6.1 Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticPi(k * k, k), AdvancedMath.EllipticE(k) / (1.0 - k * k))); // DLMF 19.6.2 Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticPi(-k, k), Math.PI / 4.0 / (1.0 + k) + AdvancedMath.EllipticK(k) / 2.0)); // DLMF 19.6.3 Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticPi(0.0, k), AdvancedMath.EllipticK(k))); Assert.IsTrue(Double.IsPositiveInfinity(AdvancedMath.EllipticPi(1.0, k))); } }
public void EllipticEExtremeValues() { Assert.IsTrue(TestUtilities.IsNearlyEqual(AdvancedMath.EllipticE(Double.Epsilon), Math.PI / 2.0)); Assert.IsTrue(Double.IsNaN(AdvancedMath.EllipticE(Double.NaN))); }