public void CoulombAgreement() { // The individual CoulombF and CoulombG functions should agree with the Coulomb // function that computes both. foreach (int L in TestUtilities.GenerateIntegerValues(1, 100, 4)) { foreach (double eta in TestUtilities.GenerateRealValues(1.0E-1, 1.0E2, 8)) { foreach (double rho in TestUtilities.GenerateRealValues(1.0E-2, 1.0E4, 16)) { double F = AdvancedMath.CoulombF(L, eta, rho); double G = AdvancedMath.CoulombG(L, eta, rho); SolutionPair s = AdvancedMath.Coulomb(L, eta, rho); Assert.IsTrue(TestUtilities.IsNearlyEqual(F, s.FirstSolutionValue)); // We are producing NaNs for divergent G rathar than infinities if (F == 0.0) { continue; } Assert.IsTrue(TestUtilities.IsNearlyEqual(G, s.SecondSolutionValue)); } } } }
public void CoulombRhoZero() { // L = 0 foreach (double eta in TestUtilities.GenerateRealValues(1.0E-2, 1.0E3, 4)) { foreach (int sign in new int[] { 1, -1 }) { // F is zero Assert.IsTrue(AdvancedMath.CoulombF(0, sign * eta, 0.0) == 0.0); // G is 1/C_{\ell}(\eta), F' = C_{\ell}(eta), so product is 1 SolutionPair s = AdvancedMath.Coulomb(0, sign * eta, 0.0); Assert.IsTrue(TestUtilities.IsNearlyEqual(s.FirstSolutionDerivative * s.SecondSolutionValue, 1.0)); Assert.IsTrue(Double.IsNegativeInfinity(s.SecondSolutionDerivative)); } } // L > 0 foreach (int L in TestUtilities.GenerateIntegerValues(1, 100, 4)) { foreach (int sign in new int[] { +1, -1 }) { foreach (double eta in TestUtilities.GenerateRealValues(1.0E-2, 1.0E3, 8)) { // F is zero, G is infinite Assert.IsTrue(AdvancedMath.CoulombF(L, sign * eta, 0.0) == 0.0); Assert.IsTrue(Double.IsInfinity(AdvancedMath.CoulombG(L, sign * eta, 0.0))); } } } }
public void CoulombWronskianWithDerivatives() { foreach (int L in TestUtilities.GenerateIntegerValues(1, 100, 8)) { foreach (int sign in new int[] { +1, -1 }) { foreach (double eta in TestUtilities.GenerateRealValues(1.0E-1, 1.0E2, 16)) { foreach (double rho in TestUtilities.GenerateRealValues(1.0E-2, 1.0E4, 32)) { SolutionPair s = AdvancedMath.Coulomb(L, eta, rho); // If F and G underflow and overflow, skip check if (s.FirstSolutionValue == 0.0) { continue; } Assert.IsTrue(TestUtilities.IsSumNearlyEqual( s.FirstSolutionDerivative * s.SecondSolutionValue, -s.FirstSolutionValue * s.SecondSolutionDerivative, 1.0, TestUtilities.TargetPrecision * 10.0 )); } } } } }
public void CoulombAgreement() { // The individual CoulombF and CoulombG functions should agree with the Coulomb // function that computes both. foreach (int L in TestUtilities.GenerateIntegerValues(1, 100, 8)) { foreach (int sign in new int[] { +1, -1 }) { foreach (double eta in TestUtilities.GenerateRealValues(1.0E-1, 1.0E2, 16)) { foreach (double rho in TestUtilities.GenerateRealValues(1.0E-2, 1.0E4, 32)) { double F = AdvancedMath.CoulombF(L, sign * eta, rho); double G = AdvancedMath.CoulombG(L, sign * eta, rho); SolutionPair s = AdvancedMath.Coulomb(L, sign * eta, rho); // Deep in transition region, there are cases where we integrate for full solution pair in order to get G, // then use Wronskian from that G to get F. But if we are just computing F, we use series to get a different // (and more accurate) answer. So we relax agreement criteria a bit. Eventually, would be great to do // series for G everywhere we can do series for F. if (!TestUtilities.IsNearlyEqual(F, s.FirstSolutionValue, 4.0 * TestUtilities.TargetPrecision)) { Console.WriteLine($"L={L} eta={eta} rho={rho} F={F} s.F={s.FirstSolutionValue} b={Double.IsNaN(s.SecondSolutionDerivative)}"); } Assert.IsTrue(TestUtilities.IsNearlyEqual(F, s.FirstSolutionValue, 4.0 * TestUtilities.TargetPrecision)); Assert.IsTrue(TestUtilities.IsNearlyEqual(G, s.SecondSolutionValue)); } } } } }
public static void ComputeSpecialFunctions() { // Compute the value x at which erf(x) is just 10^{-15} from 1. double x = AdvancedMath.InverseErfc(1.0E-15); // The Gamma function at 1/2 is sqrt(pi) double y = AdvancedMath.Gamma(0.5); // Compute a Coulomb Wave Function in the quantum tunneling region SolutionPair s = AdvancedMath.Coulomb(2, 4.5, 3.0); // Compute the Reimann Zeta function at a complex value Complex z = AdvancedComplexMath.RiemannZeta(new Complex(0.75, 6.0)); // Compute the 100th central binomial coefficient double c = AdvancedIntegerMath.BinomialCoefficient(100, 50); }
public void CoulombAtOrigin() { // F is zero at origin for all L and eta Assert.IsTrue(AdvancedMath.CoulombF(0, -1.2, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.CoulombF(5, 4.3, 0.0) == 0.0); // For L = 0, F' and G are finite, non-zero, and related SolutionPair s = AdvancedMath.Coulomb(0, 5.6, 0.0); Assert.IsTrue(s.FirstSolutionValue == 0.0); Assert.IsTrue(TestUtilities.IsNearlyEqual( s.FirstSolutionDerivative * s.SecondSolutionValue, 1.0 )); Assert.IsTrue(s.SecondSolutionDerivative == Double.NegativeInfinity); }
public void CoulombWronskian() { foreach (int L in TestUtilities.GenerateIntegerValues(1, 100, 8)) { foreach (double eta in TestUtilities.GenerateRealValues(1.0E-1, 1.0E2, 16)) { foreach (double rho in TestUtilities.GenerateRealValues(1.0E-2, 1.0E4, 32)) { SolutionPair rp = AdvancedMath.Coulomb(L, eta, rho); Debug.WriteLine("{0} {1} {2} : {3} {4} {5} {6} : {7}", L, eta, rho, rp.FirstSolutionValue, rp.FirstSolutionDerivative, rp.SecondSolutionValue, rp.SecondSolutionDerivative, rp.FirstSolutionDerivative * rp.SecondSolutionValue - rp.FirstSolutionValue * rp.SecondSolutionDerivative ); // if F and G underflow and overflow, skip check if (rp.FirstSolutionValue == 0.0) { continue; } Assert.IsTrue(TestUtilities.IsSumNearlyEqual( rp.FirstSolutionDerivative * rp.SecondSolutionValue, -rp.FirstSolutionValue * rp.SecondSolutionDerivative, 1.0, TestUtilities.TargetPrecision * 10.0 )); SolutionPair rm = AdvancedMath.Coulomb(L, -eta, rho); Debug.WriteLine("{0} {1} {2} : {3} {4} {5} {6} : {7}", L, -eta, rho, rm.FirstSolutionValue, rm.FirstSolutionDerivative, rm.SecondSolutionValue, rm.SecondSolutionDerivative, rm.FirstSolutionDerivative * rm.SecondSolutionValue - rm.FirstSolutionValue * rm.SecondSolutionDerivative ); Assert.IsTrue(TestUtilities.IsSumNearlyEqual( rm.FirstSolutionDerivative * rm.SecondSolutionValue, -rm.FirstSolutionValue * rm.SecondSolutionDerivative, 1.0, TestUtilities.TargetPrecision * 10.0 )); } } } }
private void CoulombRecursionTest(int L, double eta, double rho) { SolutionPair sm = AdvancedMath.Coulomb(L - 1, eta, rho); SolutionPair s0 = AdvancedMath.Coulomb(L, eta, rho); SolutionPair sp = AdvancedMath.Coulomb(L + 1, eta, rho); double eps = 8.0 * TestUtilities.TargetPrecision; // Relating u_{L}' to u_{L-1} and u_{L} Assert.IsTrue(TestUtilities.IsSumNearlyEqual( MoreMath.Hypot(L, eta) * sm.FirstSolutionValue, -(L * L / rho + eta) * s0.FirstSolutionValue, L * s0.FirstSolutionDerivative, eps )); Assert.IsTrue(TestUtilities.IsSumNearlyEqual( MoreMath.Hypot(L, eta) * sm.SecondSolutionValue, -(L * L / rho + eta) * s0.SecondSolutionValue, L * s0.SecondSolutionDerivative, eps )); // Relating u_{L}' to u_{L} and u_{L+1} // Relating u_{L+1}, u_{L}, u_{L-1} Assert.IsTrue(TestUtilities.IsSumNearlyEqual( (2 * L + 1) * (eta + L * (L + 1) / rho) * s0.FirstSolutionValue, -(L + 1) * MoreMath.Hypot(L, eta) * sm.FirstSolutionValue, L * MoreMath.Hypot(L + 1, eta) * sp.FirstSolutionValue, eps )); Assert.IsTrue(TestUtilities.IsSumNearlyEqual( (2 * L + 1) * (eta + L * (L + 1) / rho) * s0.SecondSolutionValue, -(L + 1) * MoreMath.Hypot(L, eta) * sm.SecondSolutionValue, L * MoreMath.Hypot(L + 1, eta) * sp.SecondSolutionValue, eps )); }
public static void Main(string[] args) { // calculate the factorials of 0 through 10 for (long counter = 0; counter <= 10; ++counter) { Console.WriteLine("{0}! = {1}", counter, Factorial(counter)); } // Compute the value x at which erf(x) is just 10^{-15} from 1. double x = AdvancedMath.InverseErfc(1.0E-15); Console.WriteLine("\n{0}", x); // The Gamma function at 1/2 is sqrt(pi) double y = AdvancedMath.Gamma(0.5); Console.WriteLine("\nThe Gamma function at 1/2 is sqrt(pi) = {0}", y); // Compute a Coulomb Wave Function in the quantum tunneling region SolutionPair s = AdvancedMath.Coulomb(2, 4.5, 3.0); Console.WriteLine("\nCompute a Coulomb Wave Function in the quantum tunneling region = {0}", s); // Compute the Reimann Zeta function at a complex value Complex z = AdvancedComplexMath.RiemannZeta(new Complex(0.75, 6.0)); Console.WriteLine("\nCompute the Reimann Zeta function at a complex value = {0}", z); // Compute the 100th central binomial coefficient double c = AdvancedIntegerMath.BinomialCoefficient(5, 2); Console.WriteLine("\n{0}", c); Console.WriteLine("\nTecle qualquer tecla para finalizar..."); Console.ReadKey(); } // end Main