Пример #1
0
        /// <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;
        }