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 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 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 BesselAtZero() { // Normal Bessel \nu = 0 Assert.IsTrue(AdvancedMath.BesselJ(0, 0.0) == 1.0); Assert.IsTrue(AdvancedMath.BesselJ(0.0, 0.0) == 1.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(0, 0.0))); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(0.0, 0.0))); SolutionPair jy0 = AdvancedMath.Bessel(0.0, 0.0); Assert.IsTrue(jy0.FirstSolutionValue == 1.0); Assert.IsTrue(jy0.FirstSolutionDerivative == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(jy0.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jy0.SecondSolutionDerivative)); // Normal Bessel 0 < \nu < 1 Assert.IsTrue(AdvancedMath.BesselJ(0.1, 0.0) == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(0.1, 0.0))); SolutionPair jyf = AdvancedMath.Bessel(0.9, 0.0); Assert.IsTrue(jyf.FirstSolutionValue == 0.0); Assert.IsTrue(jyf.FirstSolutionDerivative == Double.PositiveInfinity); Assert.IsTrue(Double.IsNegativeInfinity(jyf.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jyf.SecondSolutionDerivative)); // Normal Bessel \nu = 1 Assert.IsTrue(AdvancedMath.BesselJ(1, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.BesselJ(1.0, 0.0) == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(1, 0.0))); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(1.0, 0.0))); SolutionPair jy1 = AdvancedMath.Bessel(1.0, 0.0); Assert.IsTrue(jy1.FirstSolutionValue == 0.0); Assert.IsTrue(jy1.FirstSolutionDerivative == 0.5); Assert.IsTrue(Double.IsNegativeInfinity(jy1.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jy1.SecondSolutionDerivative)); // Normal Bessel \nu > 1 Assert.IsTrue(AdvancedMath.BesselJ(2, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.BesselJ(1.2, 0.0) == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(2, 0.0))); Assert.IsTrue(Double.IsNegativeInfinity(AdvancedMath.BesselY(1.2, 0.0))); SolutionPair jy2 = AdvancedMath.Bessel(1.7, 0.0); Assert.IsTrue(jy2.FirstSolutionValue == 0.0); Assert.IsTrue(jy2.FirstSolutionDerivative == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(jy2.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(jy2.SecondSolutionDerivative)); }
public void AiryAgreement() { foreach (double x in TestUtilities.GenerateRealValues(1.0E-2, 1.0E2, 4)) { SolutionPair s = AdvancedMath.Airy(-x); Assert.IsTrue(TestUtilities.IsNearlyEqual(s.FirstSolutionValue, AdvancedMath.AiryAi(-x))); Assert.IsTrue(TestUtilities.IsNearlyEqual(s.SecondSolutionValue, AdvancedMath.AiryBi(-x))); } }
private ISolution GenerateneRandomSolution() { ISolutionPair[] solutionPairs = new SolutionPair[this.workToDos.Length]; for (int i = 0; i < this.workToDos.Length; i++) { solutionPairs[i] = new SolutionPair() { WorkToDo = workToDos[i], WorkerMan = this.workerMens[random.Next(this.workerMens.Length)] }; } return new Solution() { SolutionPairs = solutionPairs.ToList() }; }
public void AiryWronskian() { foreach (double x in TestUtilities.GenerateRealValues(1.0E-2, 1.0E2, 8)) { SolutionPair p = AdvancedMath.Airy(x); Assert.IsTrue(TestUtilities.IsSumNearlyEqual(p.FirstSolutionValue * p.SecondSolutionDerivative, -p.SecondSolutionValue * p.FirstSolutionDerivative, 1.0 / Math.PI)); SolutionPair q = AdvancedMath.Airy(-x); Assert.IsTrue(TestUtilities.IsSumNearlyEqual(q.FirstSolutionValue * q.SecondSolutionDerivative, -q.SecondSolutionValue * q.FirstSolutionDerivative, 1.0 / Math.PI)); } }
public void ModifiedBesselAtZero() { // Modified Bessel \nu = 0 Assert.IsTrue(AdvancedMath.ModifiedBesselI(0.0, 0.0) == 1.0); Assert.IsTrue(AdvancedMath.ModifiedBesselK(0.0, 0.0) == Double.NegativeInfinity); SolutionPair ik0 = AdvancedMath.ModifiedBessel(0.0, 0.0); Assert.IsTrue(ik0.FirstSolutionValue == 1.0); Assert.IsTrue(ik0.FirstSolutionDerivative == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(ik0.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(ik0.SecondSolutionDerivative)); // Modified Bessel 0 < \nu < 1 Assert.IsTrue(AdvancedMath.ModifiedBesselI(0.1, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.ModifiedBesselK(0.1, 0.0) == Double.NegativeInfinity); SolutionPair ikf = AdvancedMath.ModifiedBessel(0.9, 0.0); Assert.IsTrue(ikf.FirstSolutionValue == 0.0); Assert.IsTrue(ikf.FirstSolutionDerivative == Double.PositiveInfinity); Assert.IsTrue(Double.IsNegativeInfinity(ikf.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(ikf.SecondSolutionDerivative)); // Modified Bessel \nu = 1 Assert.IsTrue(AdvancedMath.ModifiedBesselI(1.0, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.ModifiedBesselK(1.0, 0.0) == Double.NegativeInfinity); SolutionPair ik1 = AdvancedMath.ModifiedBessel(1.0, 0.0); Assert.IsTrue(ik1.FirstSolutionValue == 0.0); Assert.IsTrue(ik1.FirstSolutionDerivative == 0.5); Assert.IsTrue(Double.IsNegativeInfinity(ik1.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(ik1.SecondSolutionDerivative)); // Modified Bessel \nu > 1 Assert.IsTrue(AdvancedMath.ModifiedBesselI(1.2, 0.0) == 0.0); Assert.IsTrue(AdvancedMath.ModifiedBesselK(1.2, 0.0) == Double.NegativeInfinity); SolutionPair ik2 = AdvancedMath.ModifiedBessel(1.7, 0.0); Assert.IsTrue(ik2.FirstSolutionValue == 0.0); Assert.IsTrue(ik2.FirstSolutionDerivative == 0.0); Assert.IsTrue(Double.IsNegativeInfinity(ik2.SecondSolutionValue)); Assert.IsTrue(Double.IsPositiveInfinity(ik2.SecondSolutionDerivative)); }
public void ModifiedBesselDerivativeWronskian() { foreach (double nu in TestUtilities.GenerateRealValues(1.0E-1, 1.0E2, 8)) { foreach (double x in TestUtilities.GenerateRealValues(1.0E-2, 1.0E2, 16)) { SolutionPair s = AdvancedMath.ModifiedBessel(nu, x); Assert.IsTrue(TestUtilities.IsNearlyEqual( s.SecondSolutionValue * s.FirstSolutionDerivative - s.FirstSolutionValue * s.SecondSolutionDerivative, 1.0 / x )); // there is no cancelation, because I, I', K > 0 and K' < 0 } } }
public void ModifiedBesselAgreement() { foreach (double nu in TestUtilities.GenerateRealValues(1.0E-1, 1.0E2, 8)) { foreach (double x in TestUtilities.GenerateRealValues(1.0E-2, 1.0E2, 16)) { SolutionPair s = AdvancedMath.ModifiedBessel(nu, x); double I = AdvancedMath.ModifiedBesselI(nu, x); double K = AdvancedMath.ModifiedBesselK(nu, x); Assert.IsTrue(TestUtilities.IsNearlyEqual(s.FirstSolutionValue, AdvancedMath.ModifiedBesselI(nu, x))); Assert.IsTrue(TestUtilities.IsNearlyEqual(s.SecondSolutionValue, AdvancedMath.ModifiedBesselK(nu, x))); } } }
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 AiryModulusMomentIntegrals() { // https://math.stackexchange.com/questions/507425/an-integral-involving-airy-functions-int-0-infty-fracxp-operatornameai double I0 = FunctionMath.Integrate(t => { SolutionPair s = AdvancedMath.Airy(t); return(1.0 / (MoreMath.Sqr(s.FirstSolutionValue) + MoreMath.Sqr(s.SecondSolutionValue))); }, 0.0, Double.PositiveInfinity); Assert.IsTrue(TestUtilities.IsNearlyEqual(I0, Math.PI * Math.PI / 6.0)); double I3 = FunctionMath.Integrate(t => { SolutionPair s = AdvancedMath.Airy(t); return(MoreMath.Pow(t, 3) / (MoreMath.Sqr(s.FirstSolutionValue) + MoreMath.Sqr(s.SecondSolutionValue))); }, 0.0, Double.PositiveInfinity); Assert.IsTrue(TestUtilities.IsNearlyEqual(I3, 5.0 * Math.PI * Math.PI / 32.0)); }
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