BesselJ.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. /*
  18.  * This is not the original file distributed by the Apache Software Foundation
  19.  * It has been modified by the Hipparchus project
  20.  */

  21. package org.hipparchus.special;

  22. import org.hipparchus.analysis.UnivariateFunction;
  23. import org.hipparchus.exception.LocalizedCoreFormats;
  24. import org.hipparchus.exception.MathIllegalArgumentException;
  25. import org.hipparchus.exception.MathIllegalStateException;
  26. import org.hipparchus.util.FastMath;
  27. import org.hipparchus.util.SinCos;

  28. /**
  29.  * This class provides computation methods related to Bessel
  30.  * functions of the first kind. Detailed descriptions of these functions are
  31.  * available in <a
  32.  * href="http://en.wikipedia.org/wiki/Bessel_function">Wikipedia</a>, <a
  33.  * href="http://en.wikipedia.org/wiki/Abramowitz_and_Stegun">Abramowitz and
  34.  * Stegun</a> (Ch. 9-11), and <a href="http://dlmf.nist.gov/">DLMF</a> (Ch. 10).
  35.  * <p>
  36.  * This implementation is based on the rjbesl Fortran routine at
  37.  * <a href="http://www.netlib.org/specfun/rjbesl">Netlib</a>.
  38.  * </p>
  39.  * <p>
  40.  * From the Fortran code: </p>
  41.  * <p>
  42.  * This program is based on a program written by David J. Sookne (2) that
  43.  * computes values of the Bessel functions J or I of real argument and integer
  44.  * order. Modifications include the restriction of the computation to the J
  45.  * Bessel function of non-negative real argument, the extension of the
  46.  * computation to arbitrary positive order, and the elimination of most
  47.  * underflow.</p>
  48.  * <p>
  49.  * References:</p>
  50.  * <ul>
  51.  * <li>"A Note on Backward Recurrence Algorithms," Olver, F. W. J., and Sookne,
  52.  * D. J., Math. Comp. 26, 1972, pp 941-947.</li>
  53.  * <li>"Bessel Functions of Real Argument and Integer Order," Sookne, D. J., NBS
  54.  * Jour. of Res. B. 77B, 1973, pp 125-132.</li>
  55.  * </ul>
  56.  */
  57. public class BesselJ
  58.     implements UnivariateFunction {

  59.     // ---------------------------------------------------------------------
  60.     // Mathematical constants
  61.     // ---------------------------------------------------------------------

  62.     /** -2 / pi */
  63.     private static final double PI2 = 0.636619772367581343075535;

  64.     /** first few significant digits of 2pi */
  65.     private static final double TOWPI1 = 6.28125;

  66.     /** 2pi - TWOPI1 to working precision */
  67.     private static final double TWOPI2 = 1.935307179586476925286767e-3;

  68.     /** TOWPI1 + TWOPI2 */
  69.     private static final double TWOPI = TOWPI1 + TWOPI2;

  70.     // ---------------------------------------------------------------------
  71.     // Machine-dependent parameters
  72.     // ---------------------------------------------------------------------

  73.     /**
  74.      * 10.0^K, where K is the largest integer such that ENTEN is
  75.      * machine-representable in working precision
  76.      */
  77.     private static final double ENTEN = 1.0e308;

  78.     /**
  79.      * Decimal significance desired. Should be set to (INT(log_{10}(2) * (it)+1)).
  80.      * Setting NSIG lower will result in decreased accuracy while setting
  81.      * NSIG higher will increase CPU time without increasing accuracy.
  82.      * The truncation error is limited to a relative error of
  83.      * T=.5(10^(-NSIG)).
  84.      */
  85.     private static final double ENSIG = 1.0e16;

  86.     /** 10.0 ** (-K) for the smallest integer K such that K >= NSIG/4 */
  87.     private static final double RTNSIG = 1.0e-4;

  88.     /** Smallest ABS(X) such that X/4 does not underflow */
  89.     private static final double ENMTEN = 8.90e-308;

  90.     /** Minimum acceptable value for x */
  91.     private static final double X_MIN = 0.0;

  92.     /**
  93.      * Upper limit on the magnitude of x. If abs(x) = n, then at least
  94.      * n iterations of the backward recursion will be executed. The value of
  95.      * 10.0 ** 4 is used on every machine.
  96.      */
  97.     private static final double X_MAX = 1.0e4;

  98.     /** First 25 factorials as doubles */
  99.     private static final double[] FACT = {
  100.         1.0, 1.0, 2.0, 6.0, 24.0, 120.0, 720.0, 5040.0, 40320.0, 362880.0,
  101.         3628800.0, 39916800.0, 479001600.0, 6227020800.0, 87178291200.0,
  102.         1.307674368e12, 2.0922789888e13, 3.55687428096e14, 6.402373705728e15,
  103.         1.21645100408832e17, 2.43290200817664e18, 5.109094217170944e19,
  104.         1.12400072777760768e21, 2.585201673888497664e22,
  105.         6.2044840173323943936e23
  106.     };

  107.     /** Order of the function computed when {@link #value(double)} is used */
  108.     private final double order;

  109.     /**
  110.      * Create a new BesselJ with the given order.
  111.      *
  112.      * @param order order of the function computed when using {@link #value(double)}.
  113.      */
  114.     public BesselJ(double order) {
  115.         this.order = order;
  116.     }

  117.     /**
  118.      * Returns the value of the constructed Bessel function of the first kind,
  119.      * for the passed argument.
  120.      *
  121.      * @param x Argument
  122.      * @return Value of the Bessel function at x
  123.      * @throws MathIllegalArgumentException if {@code x} is too large relative to {@code order}
  124.      * @throws MathIllegalStateException if the algorithm fails to converge
  125.      */
  126.     @Override
  127.     public double value(double x)
  128.         throws MathIllegalArgumentException, MathIllegalStateException {
  129.         return value(order, x);
  130.     }

  131.     /**
  132.      * Returns the first Bessel function, \(J_{order}(x)\).
  133.      *
  134.      * @param order Order of the Bessel function
  135.      * @param x Argument
  136.      * @return Value of the Bessel function of the first kind, \(J_{order}(x)\)
  137.      * @throws MathIllegalArgumentException if {@code x} is too large relative to {@code order}
  138.      * @throws MathIllegalStateException if the algorithm fails to converge
  139.      */
  140.     public static double value(double order, double x)
  141.         throws MathIllegalArgumentException, MathIllegalStateException {
  142.         final int n = (int) order;
  143.         final double alpha = order - n;
  144.         final int nb = n + 1;
  145.         final BesselJResult res = rjBesl(x, alpha, nb);

  146.         if (res.nVals >= nb) {
  147.             return res.vals[n];
  148.         } else if (res.nVals < 0) {
  149.             throw new MathIllegalArgumentException(LocalizedCoreFormats.BESSEL_FUNCTION_BAD_ARGUMENT,order, x);
  150.         } else if (FastMath.abs(res.vals[res.nVals - 1]) < 1e-100) {
  151.             return res.vals[n]; // underflow; return value (will be zero)
  152.         }
  153.         throw new MathIllegalStateException(LocalizedCoreFormats.BESSEL_FUNCTION_FAILED_CONVERGENCE, order, x);
  154.     }

  155.     /**
  156.      * Encapsulates the results returned by {@link BesselJ#rjBesl(double, double, int)}.
  157.      * <p>
  158.      * {@link #getVals()} returns the computed function values.
  159.      * {@link #getnVals()} is the number of values among those returned by {@link #getnVals()}
  160.      * that can be considered accurate.
  161.      * </p>
  162.      * <ul>
  163.      * <li>nVals &lt; 0: An argument is out of range. For example, nb &lt;= 0, alpha
  164.      * &lt; 0 or &gt; 1, or x is too large. In this case, b(0) is set to zero, the
  165.      * remainder of the b-vector is not calculated, and nVals is set to
  166.      * MIN(nb,0) - 1 so that nVals != nb.</li>
  167.      * <li>nb &gt; nVals &gt; 0: Not all requested function values could be calculated
  168.      * accurately. This usually occurs because nb is much larger than abs(x). In
  169.      * this case, b(n) is calculated to the desired accuracy for n &lt; nVals, but
  170.      * precision is lost for nVals &lt; n &lt;= nb. If b(n) does not vanish for n &gt;
  171.      * nVals (because it is too small to be represented), and b(n)/b(nVals) =
  172.      * \(10^{-k}\), then only the first NSIG-k significant figures of b(n) can be
  173.      * trusted.</li></ul>
  174.      */
  175.     public static class BesselJResult {

  176.         /** Bessel function values */
  177.         private final double[] vals;

  178.         /** Valid value count */
  179.         private final int nVals;

  180.         /**
  181.          * Create a new BesselJResult with the given values and valid value count.
  182.          *
  183.          * @param b values
  184.          * @param n count of valid values
  185.          */
  186.         public BesselJResult(double[] b, int n) {
  187.             vals = b.clone();
  188.             nVals = n;
  189.         }

  190.         /** Get computed function values.
  191.          * @return the computed function values
  192.          */
  193.         public double[] getVals() {
  194.             return vals.clone();
  195.         }

  196.         /** Get number of valid function values.
  197.          * @return the number of valid function values (normally the same as the
  198.          *         length of the array returned by {@link #getnVals()})
  199.          */
  200.         public int getnVals() {
  201.             return nVals;
  202.         }
  203.     }

  204.     /**
  205.      * Calculates Bessel functions \(J_{n+alpha}(x)\) for
  206.      * non-negative argument x, and non-negative order n + alpha.
  207.      * <p>
  208.      * Before using the output vector, the user should check that
  209.      * nVals = nb, i.e., all orders have been calculated to the desired accuracy.
  210.      * See BesselResult class javadoc for details on return values.
  211.      * </p>
  212.      * @param x non-negative real argument for which J's are to be calculated
  213.      * @param alpha fractional part of order for which J's or exponentially
  214.      * scaled J's (\(J\cdot e^{x}\)) are to be calculated. 0 &lt;= alpha &lt; 1.0.
  215.      * @param nb integer number of functions to be calculated, nb &gt; 0. The first
  216.      * function calculated is of order alpha, and the last is of order
  217.      * nb - 1 + alpha.
  218.      * @return BesselJResult a vector of the functions
  219.      * \(J_{alpha}(x)\) through \(J_{nb-1+alpha}(x)\), or the corresponding exponentially
  220.      * scaled functions and an integer output variable indicating possible errors
  221.      */
  222.     public static BesselJResult rjBesl(double x, double alpha, int nb) {
  223.         final double[] b = new double[nb];

  224.         int ncalc;
  225.         double alpem;
  226.         double alp2em;

  227.         // ---------------------------------------------------------------------
  228.         // Check for out of range arguments.
  229.         // ---------------------------------------------------------------------
  230.         final int magx = (int) x;
  231.         if ((nb > 0) && (x >= X_MIN) && (x <= X_MAX) && (alpha >= 0) &&
  232.             (alpha < 1)) {
  233.             // ---------------------------------------------------------------------
  234.             // Initialize result array to zero.
  235.             // ---------------------------------------------------------------------
  236.             ncalc = nb;
  237.             for (int i = 0; i < nb; ++i) {
  238.                 b[i] = 0;
  239.             }

  240.             // ---------------------------------------------------------------------
  241.             // Branch to use 2-term ascending series for small X and asymptotic
  242.             // form for large X when NB is not too large.
  243.             // ---------------------------------------------------------------------
  244.             double tempa;
  245.             double tempb;
  246.             double tempc;
  247.             double tover;
  248.             if (x < RTNSIG) {
  249.                 // ---------------------------------------------------------------------
  250.                 // Two-term ascending series for small X.
  251.                 // ---------------------------------------------------------------------
  252.                 tempa = 1;
  253.                 alpem = 1 + alpha;
  254.                 double halfx = 0;
  255.                 if (x > ENMTEN) {
  256.                     halfx = 0.5 * x;
  257.                 }
  258.                 if (alpha != 0) {
  259.                     tempa = FastMath.pow(halfx, alpha) /
  260.                             (alpha * Gamma.gamma(alpha));
  261.                 }
  262.                 tempb = 0;
  263.                 if (x + 1 > 1) {
  264.                     tempb = -halfx * halfx;
  265.                 }
  266.                 b[0] = tempa + (tempa * tempb / alpem);
  267.                 if ((x != 0) && (b[0] == 0)) {
  268.                     ncalc = 0;
  269.                 }
  270.                 if (nb != 1) {
  271.                     if (x <= 0) {
  272.                         for (int n = 1; n < nb; ++n) {
  273.                             b[n] = 0;
  274.                         }
  275.                     } else {
  276.                         // ---------------------------------------------------------------------
  277.                         // Calculate higher order functions.
  278.                         // ---------------------------------------------------------------------
  279.                         tempc = halfx;
  280.                         tover = tempb != 0 ? ENMTEN / tempb :  2 * ENMTEN / x;
  281.                         for (int n = 1; n < nb; ++n) {
  282.                             tempa /= alpem;
  283.                             alpem += 1;
  284.                             tempa *= tempc;
  285.                             if (tempa <= tover * alpem) {
  286.                                 tempa = 0;
  287.                             }
  288.                             b[n] = tempa + (tempa * tempb / alpem);
  289.                             if ((b[n] == 0) && (ncalc > n)) {
  290.                                 ncalc = n;
  291.                             }
  292.                         }
  293.                     }
  294.                 }
  295.             } else if ((x > 25.0) && (nb <= magx + 1)) {
  296.                 // ---------------------------------------------------------------------
  297.                 // Asymptotic series for X > 25
  298.                 // ---------------------------------------------------------------------
  299.                 final double xc = FastMath.sqrt(PI2 / x);
  300.                 final double mul = 0.125 / x;
  301.                 final double xin = mul * mul;
  302.                 final int m;
  303.                 if (x >= 130.0) {
  304.                     m = 4;
  305.                 } else if (x >= 35.0) {
  306.                     m = 8;
  307.                 } else {
  308.                     m = 11;
  309.                 }

  310.                 final double xm = 4.0 * m;
  311.                 // ---------------------------------------------------------------------
  312.                 // Argument reduction for SIN and COS routines.
  313.                 // ---------------------------------------------------------------------
  314.                 double t = ((int) ((x / TWOPI) + 0.5));
  315.                 final double z = x - t * TOWPI1 - t * TWOPI2 - (alpha + 0.5) / PI2;
  316.                 final SinCos vsc = FastMath.sinCos(z);
  317.                 double vsin = vsc.sin();
  318.                 double vcos = vsc.cos();
  319.                 double gnu = 2 * alpha;
  320.                 double capq;
  321.                 double capp;
  322.                 double s;
  323.                 double t1;
  324.                 double xk;
  325.                 for (int i = 1; i <= 2; i++) {
  326.                     s = (xm - 1 - gnu) * (xm - 1 + gnu) * xin * 0.5;
  327.                     t = (gnu - (xm - 3.0)) * (gnu + (xm - 3.0));
  328.                     capp = (s * t) / FACT[2 * m];
  329.                     t1 = (gnu - (xm + 1)) * (gnu + (xm + 1));
  330.                     capq = (s * t1) / FACT[2 * m + 1];
  331.                     xk = xm;
  332.                     int k = 2 * m;
  333.                     t1 = t;

  334.                     for (int j = 2; j <= m; j++) {
  335.                         xk -= 4.0;
  336.                         s = (xk - 1 - gnu) * (xk - 1 + gnu);
  337.                         t = (gnu - (xk - 3.0)) * (gnu + (xk - 3.0));
  338.                         capp = (capp + 1 / FACT[k - 2]) * s * t * xin;
  339.                         capq = (capq + 1 / FACT[k - 1]) * s * t1 * xin;
  340.                         k -= 2;
  341.                         t1 = t;
  342.                     }

  343.                     capp += 1;
  344.                     capq = (capq + 1) * ((gnu * gnu) - 1) * (0.125 / x);
  345.                     b[i - 1] = xc * (capp * vcos - capq * vsin);
  346.                     if (nb == 1) {
  347.                         return new BesselJResult(b.clone(), ncalc);
  348.                     }
  349.                     t = vsin;
  350.                     vsin = -vcos;
  351.                     vcos = t;
  352.                     gnu += 2.0;
  353.                 }

  354.                 // ---------------------------------------------------------------------
  355.                 // If NB > 2, compute J(X,ORDER+I) I = 2, NB-1
  356.                 // ---------------------------------------------------------------------
  357.                 if (nb > 2) {
  358.                     gnu = 2 * alpha + 2.0;
  359.                     for (int j = 2; j < nb; ++j) {
  360.                         b[j] = gnu * b[j - 1] / x - b[j - 2];
  361.                         gnu += 2.0;
  362.                     }
  363.                 }
  364.             } else {
  365.                 // ---------------------------------------------------------------------
  366.                 // Use recurrence to generate results. First initialize the
  367.                 // calculation of P*S.
  368.                 // ---------------------------------------------------------------------
  369.                 final int nbmx = nb - magx;
  370.                 int n = magx + 1;
  371.                 int nstart;
  372.                 int nend;
  373.                 double en = 2 * (n + alpha);
  374.                 double plast = 1;
  375.                 double p = en / x;
  376.                 double pold;
  377.                 // ---------------------------------------------------------------------
  378.                 // Calculate general significance test.
  379.                 // ---------------------------------------------------------------------
  380.                 double test = 2 * ENSIG;
  381.                 boolean readyToInitialize = false;
  382.                 if (nbmx >= 3) {
  383.                     // ---------------------------------------------------------------------
  384.                     // Calculate P*S until N = NB-1. Check for possible
  385.                     // overflow.
  386.                     // ---------------------------------------------------------------------
  387.                     tover = ENTEN / ENSIG;
  388.                     nstart = magx + 2;
  389.                     nend = nb - 1;
  390.                     en = 2 * (nstart - 1 + alpha);
  391.                     double psave;
  392.                     double psavel;
  393.                     for (int k = nstart; k <= nend; k++) {
  394.                         n = k;
  395.                         en += 2.0;
  396.                         pold = plast;
  397.                         plast = p;
  398.                         p = (en * plast / x) - pold;
  399.                         if (p > tover) {
  400.                             // ---------------------------------------------------------------------
  401.                             // To avoid overflow, divide P*S by TOVER. Calculate
  402.                             // P*S until
  403.                             // ABS(P) > 1.
  404.                             // ---------------------------------------------------------------------
  405.                             tover = ENTEN;
  406.                             p /= tover;
  407.                             plast /= tover;
  408.                             psave = p;
  409.                             psavel = plast;
  410.                             nstart = n + 1;
  411.                             do {
  412.                                 n += 1;
  413.                                 en += 2.0;
  414.                                 pold = plast;
  415.                                 plast = p;
  416.                                 p = (en * plast / x) - pold;
  417.                             } while (p <= 1);
  418.                             tempb = en / x;
  419.                             // ---------------------------------------------------------------------
  420.                             // Calculate backward test and find NCALC, the
  421.                             // highest N such that
  422.                             // the test is passed.
  423.                             // ---------------------------------------------------------------------
  424.                             test = pold * plast * (0.5 - 0.5 / (tempb * tempb));
  425.                             test /= ENSIG;
  426.                             p = plast * tover;
  427.                             n -= 1;
  428.                             en -= 2.0;
  429.                             nend = FastMath.min(nb, n);
  430.                             for (int l = nstart; l <= nend; l++) {
  431.                                 pold = psavel;
  432.                                 psavel = psave;
  433.                                 psave = (en * psavel / x) - pold;
  434.                                 if (psave * psavel > test) {
  435.                                     break;
  436.                                 }
  437.                             }
  438.                             ncalc = nend;
  439.                             readyToInitialize = true;
  440.                             break;
  441.                         }
  442.                     }
  443.                     if (!readyToInitialize) {
  444.                         n = nend;
  445.                         en = 2 * (n + alpha);
  446.                         // ---------------------------------------------------------------------
  447.                         // Calculate special significance test for NBMX > 2.
  448.                         // ---------------------------------------------------------------------
  449.                         test = FastMath.max(test, FastMath.sqrt(plast * ENSIG) *
  450.                                                   FastMath.sqrt(2 * p));
  451.                     }
  452.                 }
  453.                 // ---------------------------------------------------------------------
  454.                 // Calculate P*S until significance test passes.
  455.                 // ---------------------------------------------------------------------
  456.                 if (!readyToInitialize) {
  457.                     do {
  458.                         n += 1;
  459.                         en += 2.0;
  460.                         pold = plast;
  461.                         plast = p;
  462.                         p = (en * plast / x) - pold;
  463.                     } while (p < test);
  464.                 }
  465.                 // ---------------------------------------------------------------------
  466.                 // Initialize the backward recursion and the normalization sum.
  467.                 // ---------------------------------------------------------------------
  468.                 n += 1;
  469.                 en += 2.0;
  470.                 tempb = 0;
  471.                 tempa = 1 / p;
  472.                 int m = (2 * n) - 4 * (n / 2);
  473.                 double sum = 0;
  474.                 int em = n / 2;
  475.                 alpem = em - 1 + alpha;
  476.                 alp2em = 2 * em + alpha;
  477.                 if (m != 0) {
  478.                     sum = tempa * alpem * alp2em / em;
  479.                 }
  480.                 nend = n - nb;

  481.                 boolean readyToNormalize = false;
  482.                 boolean calculatedB0 = false;

  483.                 // ---------------------------------------------------------------------
  484.                 // Recur backward via difference equation, calculating (but not
  485.                 // storing) B(N), until N = NB.
  486.                 // ---------------------------------------------------------------------
  487.                 for (int l = 1; l <= nend; l++) {
  488.                     n -= 1;
  489.                     en -= 2.0;
  490.                     tempc = tempb;
  491.                     tempb = tempa;
  492.                     tempa = (en * tempb / x) - tempc;
  493.                     m = 2 - m;
  494.                     if (m != 0) {
  495.                         em -= 1;
  496.                         alp2em = 2 * em + alpha;
  497.                         if (n == 1) {
  498.                             break;
  499.                         }
  500.                         alpem = em - 1 + alpha;
  501.                         if (alpem == 0) {
  502.                             alpem = 1;
  503.                         }
  504.                         sum = (sum + tempa * alp2em) * alpem / em;
  505.                     }
  506.                 }

  507.                 // ---------------------------------------------------------------------
  508.                 // Store B(NB).
  509.                 // ---------------------------------------------------------------------
  510.                 b[n - 1] = tempa;
  511.                 if (nend >= 0) {
  512.                     if (nb <= 1) {
  513.                         alp2em = alpha;
  514.                         if (alpha + 1 == 1) {
  515.                             alp2em = 1;
  516.                         }
  517.                         sum += b[0] * alp2em;
  518.                         readyToNormalize = true;
  519.                     } else {
  520.                         // ---------------------------------------------------------------------
  521.                         // Calculate and store B(NB-1).
  522.                         // ---------------------------------------------------------------------
  523.                         n -= 1;
  524.                         en -= 2.0;
  525.                         b[n - 1] = (en * tempa / x) - tempb;
  526.                         if (n == 1) {
  527.                             calculatedB0 = true;
  528.                         } else {
  529.                             m = 2 - m;
  530.                             if (m != 0) {
  531.                                 em -= 1;
  532.                                 alp2em = 2 * em + alpha;
  533.                                 alpem = em - 1 + alpha;
  534.                                 if (alpem == 0) {
  535.                                     alpem = 1;
  536.                                 }

  537.                                 sum = (sum + (b[n - 1] * alp2em)) * alpem / em;
  538.                             }
  539.                         }
  540.                     }
  541.                 }
  542.                 if (!readyToNormalize && !calculatedB0) {
  543.                     nend = n - 2;
  544.                     if (nend != 0) {
  545.                         // ---------------------------------------------------------------------
  546.                         // Calculate via difference equation and store B(N),
  547.                         // until N = 2.
  548.                         // ---------------------------------------------------------------------

  549.                         for (int l = 1; l <= nend; l++) {
  550.                             n -= 1;
  551.                             en -= 2.0;
  552.                             b[n - 1] = (en * b[n] / x) - b[n + 1];
  553.                             m = 2 - m;
  554.                             if (m != 0) {
  555.                                 em -= 1;
  556.                                 alp2em = 2 * em + alpha;
  557.                                 alpem = em - 1 + alpha;
  558.                                 if (alpem == 0) {
  559.                                     alpem = 1;
  560.                                 }

  561.                                 sum = (sum + b[n - 1] * alp2em) * alpem / em;
  562.                             }
  563.                         }
  564.                     }
  565.                 }
  566.                 // ---------------------------------------------------------------------
  567.                 // Calculate b[0]
  568.                 // ---------------------------------------------------------------------
  569.                 if (!readyToNormalize) {
  570.                     if (!calculatedB0) {
  571.                         b[0] = 2.0 * (alpha + 1) * b[1] / x - b[2];
  572.                     }
  573.                     em -= 1;
  574.                     alp2em = 2 * em + alpha;
  575.                     if (alp2em == 0) {
  576.                         alp2em = 1;
  577.                     }
  578.                     sum += b[0] * alp2em;
  579.                 }
  580.                 // ---------------------------------------------------------------------
  581.                 // Normalize. Divide all B(N) by sum.
  582.                 // ---------------------------------------------------------------------

  583.                 if (FastMath.abs(alpha) > 1e-16) {
  584.                     sum *= Gamma.gamma(alpha) * FastMath.pow(x * 0.5, -alpha);
  585.                 }
  586.                 tempa = ENMTEN;
  587.                 if (sum > 1) {
  588.                     tempa *= sum;
  589.                 }

  590.                 for (n = 0; n < nb; n++) {
  591.                     if (FastMath.abs(b[n]) < tempa) {
  592.                         b[n] = 0;
  593.                     }
  594.                     b[n] /= sum;
  595.                 }
  596.             }
  597.             // ---------------------------------------------------------------------
  598.             // Error return -- X, NB, or ALPHA is out of range.
  599.             // ---------------------------------------------------------------------
  600.         } else {
  601.             if (b.length > 0) {
  602.                 b[0] = 0;
  603.             }
  604.             ncalc = FastMath.min(nb, 0) - 1;
  605.         }
  606.         return new BesselJResult(b.clone(), ncalc);
  607.     }
  608. }