/// <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); } }
/// <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); } }
/// <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); } }