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.  *      http://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. package org.apache.commons.math4.legacy.special;

  18. import java.util.Arrays;
  19. import org.apache.commons.numbers.gamma.Gamma;
  20. import org.apache.commons.math4.legacy.analysis.UnivariateFunction;
  21. import org.apache.commons.math4.legacy.exception.ConvergenceException;
  22. import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
  23. import org.apache.commons.math4.legacy.exception.util.LocalizedFormats;
  24. import org.apache.commons.math4.core.jdkmath.JdkMath;

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

  56.     // ---------------------------------------------------------------------
  57.     // Mathematical constants
  58.     // ---------------------------------------------------------------------

  59.     /** -2 / pi. */
  60.     private static final double PI2 = 0.636619772367581343075535;

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

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

  65.     /** TOWPI1 + TWOPI2. */
  66.     private static final double TWOPI = TOWPI1 + TWOPI2;

  67.     // ---------------------------------------------------------------------
  68.     // Machine-dependent parameters
  69.     // ---------------------------------------------------------------------

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

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

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

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

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

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

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

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

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

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

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

  143.         if (res.nVals >= nb) {
  144.             return res.vals[n];
  145.         } else if (res.nVals < 0) {
  146.             throw new MathIllegalArgumentException(LocalizedFormats.BESSEL_FUNCTION_BAD_ARGUMENT,order, x);
  147.         } else if (JdkMath.abs(res.vals[res.nVals - 1]) < 1e-100) {
  148.             return res.vals[n]; // underflow; return value (will be zero)
  149.         }
  150.         throw new ConvergenceException(LocalizedFormats.BESSEL_FUNCTION_FAILED_CONVERGENCE, order, x);
  151.     }

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

  172.         /** Bessel function values. */
  173.         private final double[] vals;

  174.         /** Valid value count. */
  175.         private final int nVals;

  176.         /**
  177.          * Create a new BesselJResult with the given values and valid value count.
  178.          *
  179.          * @param b values
  180.          * @param n count of valid values
  181.          */
  182.         public BesselJResult(double[] b, int n) {
  183.             vals = Arrays.copyOf(b, b.length);
  184.             nVals = n;
  185.         }

  186.         /**
  187.          * @return the computed function values
  188.          */
  189.         public double[] getVals() {
  190.             return Arrays.copyOf(vals, vals.length);
  191.         }

  192.         /**
  193.          * @return the number of valid function values (normally the same as the
  194.          *         length of the array returned by {@link #getnVals()})
  195.          */
  196.         public int getnVals() {
  197.             return nVals;
  198.         }
  199.     }

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

  220.         int ncalc = 0;
  221.         double alpem = 0;
  222.         double alp2em = 0;

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

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

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

  328.                     for (int j = 2; j <= m; j++) {
  329.                         xk -= 4.0;
  330.                         s = (xk - 1 - gnu) * (xk - 1 + gnu);
  331.                         t = (gnu - (xk - 3.0)) * (gnu + (xk - 3.0));
  332.                         capp = (capp + 1 / FACT[k - 2]) * s * t * xin;
  333.                         capq = (capq + 1 / FACT[k - 1]) * s * t1 * xin;
  334.                         k -= 2;
  335.                         t1 = t;
  336.                     }

  337.                     capp += 1;
  338.                     capq = (capq + 1) * ((gnu * gnu) - 1) * (0.125 / x);
  339.                     b[i - 1] = xc * (capp * vcos - capq * vsin);
  340.                     if (nb == 1) {
  341.                         return new BesselJResult(Arrays.copyOf(b, b.length),
  342.                                                  ncalc);
  343.                     }
  344.                     t = vsin;
  345.                     vsin = -vcos;
  346.                     vcos = t;
  347.                     gnu += 2.0;
  348.                 }

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

  478.                 boolean readyToNormalize = false;
  479.                 boolean calculatedB0 = false;

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

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

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

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

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

  580.                 if (JdkMath.abs(alpha) > 1e-16) {
  581.                     sum *= Gamma.value(alpha) * JdkMath.pow(x * 0.5, -alpha);
  582.                 }
  583.                 tempa = ENMTEN;
  584.                 if (sum > 1) {
  585.                     tempa *= sum;
  586.                 }

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