Ejemplo n.º 1
0
        /// <summary>
        /// Returns the value of the Airy Ai function at <paramref name="x"/>
        /// </summary>
        /// <param name="x">The function argument</param>
        /// <returns></returns>
        public static double AiryAi(double x)
        {
            if (double.IsNaN(x))
            {
                Policies.ReportDomainError("AiryAi(x: {0}): NaN not allowed", x);
                return(double.NaN);
            }
            if (double.IsInfinity(x))
            {
                return(0);
            }

            double absX = Math.Abs(x);

            if (x >= -3 && x <= 2)
            {
                // Use small series. See:
                // http://functions.wolfram.com/Bessel-TypeFunctions/AiryAi/06/01/02/01/0004/
                // http://dlmf.nist.gov/9.4

                double z  = x * x * x / 9;
                double s1 = Constants.AiryAi0 * HypergeometricSeries.Sum0F1(2 / 3.0, z);
                double s2 = x * Constants.AiryAiPrime0 * HypergeometricSeries.Sum0F1(4 / 3.0, z);
                return(s1 + s2);
            }

            const double v    = 1.0 / 3;
            double       zeta = 2 * absX * Math.Sqrt(absX) / 3;

            if (x < 0)
            {
                if (x < -32)
                {
                    return(AiryAsym.AiBiNeg(x).Ai);
                }

                // The following is
                //double j1 = Math2.BesselJ(v, zeta);
                //double j2 = Math2.BesselJ(-v, zeta);
                //double ai = Math.Sqrt(-x) * (j1 + j2) / 3;

                var(J, Y) = _Bessel.JY(v, zeta, true, true);
                double s  = 0.5 * (J - ((double)Y) / Constants.Sqrt3);
                double ai = Math.Sqrt(-x) * s;

                return(ai);
            }
            else
            {
                // Use the K relationship: http://dlmf.nist.gov/9.6

                if (x >= 16)
                {
                    return(AiryAsym.Ai(x));
                }

                double ai = Math2.BesselK(v, zeta) * Math.Sqrt(x / 3) / Math.PI;
                return(ai);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns the value of first derivative to the Airy Bi function at <paramref name="x"/>
        /// </summary>
        /// <param name="x">AiryBiPrime function argument</param>
        /// <returns></returns>
        public static double AiryBiPrime(double x)
        {
            if (double.IsNaN(x))
            {
                Policies.ReportDomainError("AiryBiPrime(x: {0}): NaN not allowed", x);
                return(double.NaN);
            }
            if (double.IsInfinity(x))
            {
                if (x < 0)
                {
                    return(0);
                }
                return(double.PositiveInfinity);
            }

            double absX = Math.Abs(x);

            if (x >= -3 && x <= 3)
            {
                // Use small series. See:
                // http://functions.wolfram.com/Bessel-TypeFunctions/AiryBiPrime/26/01/01/
                // http://dlmf.nist.gov/9.4

                double z  = x * x * x / 9;
                double s1 = x * x * (Constants.AiryBi0 / 2) * HypergeometricSeries.Sum0F1(5 / 3.0, z);
                double s2 = Constants.AiryBiPrime0 * HypergeometricSeries.Sum0F1(1 / 3.0, z);

                return(s1 + s2);
            }


            const double v    = 2.0 / 3;
            double       zeta = 2 * absX * Math.Sqrt(absX) / 3;

            if (x < 0)
            {
                if (x < -32)
                {
                    return(AiryAsym.AiBiPrimeNeg(x).Bi);
                }

                // The following is
                //double j1 = Math2.BesselJ(v, zeta);
                //double j2 = Math2.BesselJ(-v, zeta);
                //double bip = -x * (j1 + j2) / Constants.Sqrt3;
                //return bip;

                var(J, Y) = _Bessel.JY(v, zeta, true, true);
                double s   = 0.5 * (J / Constants.Sqrt3 - ((double)Y));
                double bip = -x * s;
                return(bip);
            }
            else
            {
                if (x >= 16)
                {
                    return(AiryAsym.BiPrime(x));
                }

                // The following is
                //double j1 = Math2.BesselI(v, zeta);
                //double j2 = Math2.BesselI(-v, zeta);
                //double bip = (x / Constants.Sqrt3) * (j1 + j2);

                var(I, K) = _Bessel.IK(v, zeta, true, true);
                double s   = (2 / Constants.Sqrt3 * I + K / Math.PI);
                var    bip = x * s;
                return(bip);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns the value of the first derivative to the Airy Ai function at <paramref name="x"/>
        /// </summary>
        /// <param name="x">The function argument</param>
        /// <returns></returns>
        public static double AiryAiPrime(double x)
        {
            if (double.IsNaN(x))
            {
                Policies.ReportDomainError("AiryAiPrime(x: {0}): NaN not allowed", x);
                return(double.NaN);
            }
            if (double.IsInfinity(x))
            {
                if (x > 0)
                {
                    return(0);
                }

                Policies.ReportDomainError("AiryAiPrime(x: {0}): Requires x != -Infinity", x);
                return(double.NaN);
            }

            double absX = Math.Abs(x);

            if (x >= -3 && x <= 2)
            {
                // Use small series. See:
                // http://functions.wolfram.com/Bessel-TypeFunctions/AiryAiPrime/26/01/01/
                // http://dlmf.nist.gov/9.4

                double z  = x * x * x / 9;
                double s1 = x * x * (Constants.AiryAi0 / 2) * HypergeometricSeries.Sum0F1(5 / 3.0, z);
                double s2 = Constants.AiryAiPrime0 * HypergeometricSeries.Sum0F1(1 / 3.0, z);

                return(s1 + s2);
            }

            const double v    = 2.0 / 3;
            double       zeta = 2 * absX * Math.Sqrt(absX) / 3;

            if (x < 0)
            {
                if (x < -32)
                {
                    return(AiryAsym.AiBiPrimeNeg(x).Ai);
                }

                // The following is
                //double j1 = Math2.BesselJ(v, zeta);
                //double j2 = Math2.BesselJ(-v, zeta);
                //double aip = -x * (j1 - j2) / 3;

                var(J, Y) = _Bessel.JY(v, zeta, true, true);
                double s   = 0.5 * (J + ((double)Y) / Constants.Sqrt3);
                double aip = -x * s;
                return(aip);
            }
            else
            {
                if (x >= 16)
                {
                    return(AiryAsym.AiPrime(x));
                }

                double aip = -Math2.BesselK(v, zeta) * x / (Constants.Sqrt3 * Math.PI);
                return(aip);
            }
        }