예제 #1
0
        public static Complex modifiedBesselFunction_i_impl <T, I>(double nu, Complex x)
            where T : Weight <Complex>, new()
            where I : baseValue <Complex>, new()
        {
            if (Complex.Abs(x) < 13.0)
            {
                Complex alpha = Complex.Pow(0.5 * x, nu) / GammaFunction.value(1.0 + nu);
                Complex Y = 0.25 * x * x;
                int     k = 1;
                Complex sum = alpha, B_k = alpha;

                while (Complex.Abs(B_k *= Y / (k * (k + nu))) > Complex.Abs(sum) * Const.QL_EPSILON)
                {
                    sum += B_k;
                    Utils.QL_REQUIRE(++k < 1000, () => "max iterations exceeded");
                }
                return(sum * FastActivator <T> .Create().weightSmallX(x));
            }
            else
            {
                double  na_k = 1.0, sign = 1.0;
                Complex da_k = new Complex(1.0, 0.0);

                Complex s1 = new Complex(1.0, 0.0), s2 = new Complex(1.0, 0.0);
                for (int k = 1; k < 30; ++k)
                {
                    sign *= -1;
                    na_k *= (4.0 * nu * nu -
                             (2.0 * (double)k - 1.0) *
                             (2.0 * (double)k - 1.0));
                    da_k *= (8.0 * k) * x;
                    Complex a_k = na_k / da_k;

                    s2 += a_k;
                    s1 += sign * a_k;
                }

                Complex i = FastActivator <I> .Create().value();

                return(1.0 / Complex.Sqrt(2 * Const.M_PI * x) *
                       (FastActivator <T> .Create().weight1LargeX(x) * s1 +
                        i * Complex.Exp(i * nu * Const.M_PI) * FastActivator <T> .Create().weight2LargeX(x) * s2));
            }
        }
예제 #2
0
        public static double modifiedBesselFunction_i_impl <T, I>(double nu, double x)
            where T : Weight <double>, new()
            where I : baseValue <double>, new()
        {
            if (Math.Abs(x) < 13.0)
            {
                double alpha = Math.Pow(0.5 * x, nu) / GammaFunction.value(1.0 + nu);
                double Y = 0.25 * x * x;
                int    k = 1;
                double sum = alpha, B_k = alpha;

                while (Math.Abs(B_k *= Y / (k * (k + nu))) > Math.Abs(sum) * Const.QL_EPSILON)
                {
                    sum += B_k;
                    Utils.QL_REQUIRE(++k < 1000, () => "max iterations exceeded");
                }
                return(sum * FastActivator <T> .Create().weightSmallX(x));
            }
            else
            {
                double na_k = 1.0, sign = 1.0;
                double da_k = 1.0;

                double s1 = 1.0, s2 = 1.0;
                for (int k = 1; k < 30; ++k)
                {
                    sign *= -1;
                    na_k *= (4.0 * nu * nu -
                             (2.0 * k - 1.0) *
                             (2.0 * k - 1.0));
                    da_k *= (8.0 * k) * x;
                    double a_k = na_k / da_k;

                    s2 += a_k;
                    s1 += sign * a_k;
                }

                double i = FastActivator <I> .Create().value();

                return(1.0 / Math.Sqrt(2 * Const.M_PI * x) *
                       (FastActivator <T> .Create().weight1LargeX(x) * s1 +
                        i * Math.Exp(i * nu * Const.M_PI) * FastActivator <T> .Create().weight2LargeX(x) * s2));
            }
        }