示例#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);
            }
        }
示例#2
0
        /// <summary>
        /// Returns the value of the Airy Bi function at <paramref name="x"/>
        /// </summary>
        /// <param name="x">The function argument</param>
        /// <returns></returns>
        public static double AiryBi(double x)
        {
            if (double.IsNaN(x))
            {
                Policies.ReportDomainError("AiryBi(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/AiryBi/26/01/01/
                // http://dlmf.nist.gov/9.4

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

                return(s1 + s2);
            }


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

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

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

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

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

                var(I, K) = _Bessel.IK(v, zeta, true, true);
                double s  = (2 / Constants.Sqrt3 * I + K / Math.PI);
                var    bi = Math.Sqrt(x) * s;

                return(bi);
            }
        }