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));
        }
Exemple #9
0
 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
         }
     }
 }
Exemple #10
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)));
                }
            }
        }
Exemple #11
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 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
                              ));
        }
Exemple #16
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