C#, Numerical Calculation - Source Code of Bessel Constants and Common Functions (02)

using System;

namespace Legalsoft.Truffer
{
    public class Bessjy
    {
        #region Constants
        const double xj00 = 5.783185962946785;
        const double xj10 = 3.047126234366209e1;
        const double xj01 = 1.468197064212389e1;
        const double xj11 = 4.921845632169460e1;
        const double twoopi = 0.6366197723675813;
        const double pio4 = 0.7853981633974483;
        private readonly double[] j0r = { 1.682397144220462e-4, 2.058861258868952e-5, 5.288947320067750e-7, 5.557173907680151e-9, 2.865540042042604e-11, 7.398972674152181e-14, 7.925088479679688e-17 };
        private readonly double[] j0s = { 1.0, 1.019685405805929e-2, 5.130296867064666e-5, 1.659702063950243e-7, 3.728997574317067e-10, 5.709292619977798e-13, 4.932979170744996e-16 };
        private readonly double[] j0pn = { 9.999999999999999e-1, 1.039698629715637, 2.576910172633398e-1, 1.504152485749669e-2, 1.052598413585270e-4 };
        private readonly double[] j0pd = { 1.0, 1.040797262528109, 2.588070904043728e-1, 1.529954477721284e-2, 1.168931211650012e-4 };
        private readonly double[] j0qn = { -1.562499999999992e-2, -1.920039317065641e-2, -5.827951791963418e-3, -4.372674978482726e-4, -3.895839560412374e-6 };
        private readonly double[] j0qd = { 1.0, 1.237980436358390, 3.838793938147116e-1, 3.100323481550864e-2, 4.165515825072393e-4 };
        private readonly double[] j1r = { 7.309637831891357e-5, 3.551248884746503e-6, 5.820673901730427e-8, 4.500650342170622e-10, 1.831596352149641e-12, 3.891583573305035e-15, 3.524978592527982e-18 };
        private readonly double[] j1s = { 1.0, 9.398354768446072e-3, 4.328946737100230e-5, 1.271526296341915e-7, 2.566305357932989e-10, 3.477378203574266e-13, 2.593535427519985e-16 };
        private readonly double[] j1pn = { 1.0, 1.014039111045313, 2.426762348629863e-1, 1.350308200342000e-2, 9.516522033988099e-5 };
        private readonly double[] j1pd = { 1.0, 1.012208056357845, 2.408580305488938e-1, 1.309511056184273e-2, 7.746422941504713e-5 };
        private readonly double[] j1qn = { 4.687499999999991e-2, 5.652407388406023e-2, 1.676531273460512e-2, 1.231216817715814e-3, 1.178364381441801e-5 };
        private readonly double[] j1qd = { 1.0, 1.210119370463693, 3.626494789275638e-1, 2.761695824829316e-2, 3.240517192670181e-4 };
        private readonly double[] y0r = { -7.653778457189104e-3, -5.854760129990403e-2, 3.720671300654721e-4, 3.313722284628089e-5, 4.247761237036536e-8, -4.134562661019613e-9, -3.382190331837473e-11, -1.017764126587862e-13, -1.107646382675456e-16 };
        private readonly double[] y0s = { 1.0, 1.125494540257841e-2, 6.427210537081400e-5, 2.462520624294959e-7, 7.029372432344291e-10, 1.560784108184928e-12, 2.702374957564761e-15, 3.468496737915257e-18, 2.716600180811817e-21 };
        private readonly double[] y0pn = { 9.999999999999999e-1, 1.039698629715637, 2.576910172633398e-1, 1.504152485749669e-2, 1.052598413585270e-4 };
        private readonly double[] y0pd = { 1.0, 1.040797262528109, 2.588070904043728e-1, 1.529954477721284e-2, 1.168931211650012e-4 };
        private readonly double[] y0qn = { -1.562499999999992e-2, -1.920039317065641e-2, -5.827951791963418e-3, -4.372674978482726e-4, -3.895839560412374e-6 };
        private readonly double[] y0qd = { 1.0, 1.237980436358390, 3.838793938147116e-1, 3.100323481550864e-2, 4.165515825072393e-4 };
        private readonly double[] y1r = { -1.041835425863234e-1, -1.135093963908952e-5, 2.212118520638132e-4, 1.270981874287763e-6, -3.982892100836748e-8, -4.820712110115943e-10, -1.929392690596969e-12, -2.725259514545605e-15 };
        private readonly double[] y1s = { 1.0, 1.186694184425838e-2, 7.121205411175519e-5, 2.847142454085055e-7, 8.364240962784899e-10, 1.858128283833724e-12, 3.018846060781846e-15, 3.015798735815980e-18 };
        private readonly double[] y1pn = { 1.0, 1.014039111045313, 2.426762348629863e-1, 1.350308200342000e-2, 9.516522033988099e-5 };
        private readonly double[] y1pd = { 1.0, 1.012208056357845, 2.408580305488938e-1, 1.309511056184273e-2, 7.746422941504713e-5 };
        private readonly double[] y1qn = { 4.687499999999991e-2, 5.652407388406023e-2, 1.676531273460512e-2, 1.231216817715814e-3, 1.178364381441801e-5 };
        private readonly double[] y1qd = { 1.0, 1.210119370463693, 3.626494789275638e-1, 2.761695824829316e-2, 3.240517192670181e-4 };
        #endregion

        private double nump { get; set; }
        private double denp { get; set; }
        private double numq { get; set; }
        private double denq { get; set; }
        private double y { get; set; }
        private double z { get; set; }
        private double ax { get; set; }
        private double xx { get; set; }

        public double j0(double x)
        {
            if ((ax = Math.Abs(x)) < 8.0)
            {
                rat(x, j0r, j0s, 6);
                return nump * (y - xj00) * (y - xj10) / denp;
            }
            else
            {
                asp(j0pn, j0pd, j0qn, j0qd, 1.0);
                return Math.Sqrt(twoopi / ax) * (Math.Cos(xx) * nump / denp - z * Math.Sin(xx) * numq / denq);
            }
        }

        public double j1(double x)
        {
            if ((ax = Math.Abs(x)) < 8.0)
            {
                rat(x, j1r, j1s, 6);
                return x * nump * (y - xj01) * (y - xj11) / denp;
            }
            else
            {
                asp(j1pn, j1pd, j1qn, j1qd, 3.0);
                double ans = Math.Sqrt(twoopi / ax) * (Math.Cos(xx) * nump / denp - z * Math.Sin(xx) * numq / denq);
                return x > 0.0 ? ans : -ans;
            }
        }

        public double y0(double x)
        {
            if (x < 8.0)
            {
                double j0x = j0(x);
                rat(x, y0r, y0s, 8);
                return nump / denp + twoopi * j0x * Math.Log(x);
            }
            else
            {
                ax = x;
                asp(y0pn, y0pd, y0qn, y0qd, 1.0);
                return Math.Sqrt(twoopi / x) * (Math.Sin(xx) * nump / denp + z * Math.Cos(xx) * numq / denq);
            }
        }

        public double y1(double x)
        {
            if (x < 8.0)
            {
                double j1x = j1(x);
                rat(x, y1r, y1s, 7);
                return x * nump / denp + twoopi * (j1x * Math.Log(x) - 1.0 / x);
            }
            else
            {
                ax = x;
                asp(y1pn, y1pd, y1qn, y1qd, 3.0);
                return Math.Sqrt(twoopi / x) * (Math.Sin(xx) * nump / denp + z * Math.Cos(xx) * numq / denq);
            }
        }

        public void rat(double x, double[] r, double[] s, int n)
        {
            y = x * x;
            z = 64.0 - y;
            nump = r[n];
            denp = s[n];
            for (int i = n - 1; i >= 0; i--)
            {
                nump = nump * z + r[i];
                denp = denp * y + s[i];
            }
        }

        public void asp(double[] pn, double[] pd, double[] qn, double[] qd, double fac)
        {
            z = 8.0 / ax;
            y = z * z;
            xx = ax - fac * pio4;
            nump = pn[4];
            denp = pd[4];
            numq = qn[4];
            denq = qd[4];
            for (int i = 3; i >= 0; i--)
            {
                nump = nump * y + pn[i];
                denp = denp * y + pd[i];
                numq = numq * y + qn[i];
                denq = denq * y + qd[i];
            }
        }

        public double jn(int n, double x)
        {
            const double ACC = 160.0;
            const int IEXP = int.MaxValue / 2;//  numeric_limits<double>.max_exponent / 2;
            if (n == 0)
            {
                return j0(x);
            }
            if (n == 1)
            {
                return j1(x);
            }
            ax = Math.Abs(x);
            double ans;
            if (ax * ax <= 8.0 * float.Epsilon)
            {
                return 0.0;
            }
            else if (ax > (double)n)
            {
                double tox = 2.0 / ax;
                double bjm = j0(ax);
                double bj = j1(ax);
                for (int j = 1; j < n; j++)
                {
                    double bjp = j * tox * bj - bjm;
                    bjm = bj;
                    bj = bjp;
                }
                ans = bj;
            }
            else
            {
                double tox = 2.0 / ax;
                int m = 2 * ((n + (int)Math.Sqrt(ACC * n)) / 2);
                bool jsum = false;
                double bjp = ans = 0.0;
                double sum = 0.0;
                double bj = 1.0;
                for (int j = m; j > 0; j--)
                {
                    double bjm = j * tox * bj - bjp;
                    bjp = bj;
                    bj = bjm;
                    double dum = Globals.frexp(bj, out int k);
                    if (k > IEXP)
                    {
                        bj = Globals.ldexp(bj, -IEXP);
                        bjp = Globals.ldexp(bjp, -IEXP);
                        ans = Globals.ldexp(ans, -IEXP);
                        sum = Globals.ldexp(sum, -IEXP);
                    }
                    if (jsum)
                    {
                        sum += bj;
                    }
                    jsum = !jsum;
                    if (j == n)
                    {                         ans = bjp;                     }                 }                 sum = 2.0 * sum - bj;                 ans /= sum;             }             return x < 0.0 && (n & 1) != 0 ? -ans : ans;         }







        public double yn(int n, double x)
        {
            if (n == 0)
            {
                return y0(x);
            }
            if (n == 1)
            {
                return y1(x);
            }
            double tox = 2.0 / x;
            double by = y1(x);
            double bym = y0(x);
            for (int j = 1; j < n; j++)
            {
                double byp = j * tox * by - bym;
                bym = by;
                by = byp;
            }
            return by;
        }
    }
}
 

Guess you like

Origin blog.csdn.net/beijinghorn/article/details/131605591