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));
                        }
                    }
                }
            }
        }
예제 #5
0
        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
                              ));
        }
예제 #9
0
    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