/// <summary> /// Returns the Cylindrical Bessel I function: I<sub>v</sub>(x) /// </summary> /// <param name="v">Order</param> /// <param name="x">Argument</param> /// <returns></returns> public static double BesselI(double v, double x) { // // This handles all the bessel I functions, note that we don't optimise // for integer v, other than the v = 0 or 1 special cases, as Millers // algorithm is at least as inefficient as the general case (the general // case has better error handling too). // if (double.IsNaN(v) || double.IsInfinity(v) || double.IsNaN(x)) { Policies.ReportDomainError("BesselI(v: {0}, x: {1}): NaNs not allowed; Requres v != Infinity", v, x); return double.NaN; } if (x < 0) { // better have integer v: if (!IsInteger(v)) { Policies.ReportDomainError("BesselI(v: {0}, x: {1}): Requires integer v when x < 0", v, x); return double.NaN; } double r = Math2.BesselI(v, -x); if (IsOdd(v)) r = -r; return r; } if (x == 0) return (v == 0) ? 1 : 0; // at this point x > 0 if (double.IsInfinity(x)) return double.PositiveInfinity; if (v == 0) return _Bessel.I0(x); if (v == 1) return _Bessel.I1(x); if (v == 0.5) return _Bessel.I0_5(x); if (v > 0 && (x < 2 || 3*(v + 1) > x * x)) return _Bessel.I_SmallArg(v, x); double Iv = _Bessel.IK(v, x, true, false).I; return Iv; }