Class BoostTools

java.lang.Object
org.apache.commons.numbers.gamma.BoostTools

final class BoostTools extends Object
Utility tools used by the Boost functions.

This code has been adapted from the Boost c++ implementations in <boost/math/tools/>. All work is copyright John Maddock 2006 and subject to the Boost Software License.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    private static final double
    The minimum epsilon value for relative error in the summation.
    private static final double
    The minimum epsilon value for relative error in the Kahan summation.
    private static final String
    Message for failure to converge.
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    private
    Private constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    (package private) static double
    evaluatePolynomial(double[] c, double x)
    Evaluate the polynomial using Horner's method.
    private static double
    getEpsilon(double epsilon, double minEpsilon)
    Gets the epsilon ensuring it satisfies the minimum allowed value.
    (package private) static double
    kahanSumSeries(DoubleSupplier func, double epsilon, int maxTerms)
    Sum the series using Kahan summation.
    (package private) static double
    kahanSumSeries(DoubleSupplier func, double epsilon, int maxTerms, double initValue)
    Sum the series using Kahan summation.
    (package private) static double
    sumSeries(DoubleSupplier func, double epsilon, int maxTerms)
    Sum the series.
    (package private) static double
    sumSeries(DoubleSupplier func, double epsilon, int maxTerms, double initValue)
    Sum the series.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • EPSILON

      private static final double EPSILON
      The minimum epsilon value for relative error in the summation. Equal to Math.ulp(1.0) or 2^-52.

      Note

      The summation will terminate when any additional terms are too small to change the sum. Assuming additional terms are reducing in magnitude this occurs when the term is 1 ULP from the sum:

      
       ulp(sum) >= term
       

      The epsilon is used to set a configurable threshold using:

      
       sum * eps >= term
       

      The minimum epsilon is the smallest value that will create a value >= 1 ULP and < 2 ULP of the sum. For any normal number the ULP of all values with the same exponent b is scalb(1.0, b - 52). This can be achieved by multiplication by 2^-52.

      See Also:
    • KAHAN_EPSILON

      private static final double KAHAN_EPSILON
      The minimum epsilon value for relative error in the Kahan summation. This can be lower than EPSILON. Set to 2^-62.

      Note

      The Kahan summation uses a carry term to extend the precision of the sum. This extends the 53-bit mantissa by adding more bits to hold round-off error. Thus the term may effect the sum when it has a magnitude smaller than 1 ULP of the current sum. The epsilon can be lowered from 2^-52 to include the extra bits in the convergence criteria. The lower limit for the epsilon is 2^-104. Boost uses an epsilon specified as a number of bits of accuracy. Each lowering of the epsilon by a factor of 2 adds a guard digit to the sum. Slower converging series will benefit from a lower epsilon. This uses 2^-62 to add 10 guard digits and allow testing of different thresholds when the Kahan summation is used, for example in the gamma function. Lowering the epsilon further is only of benefit if the terms can be computed exactly. Otherwise the rounding errors of the early terms affect the final result as much as the inclusion of extra guard digits.

      See Also:
    • MSG_FAILED_TO_CONVERGE

      private static final String MSG_FAILED_TO_CONVERGE
      Message for failure to converge.
      See Also:
  • Constructor Details

    • BoostTools

      private BoostTools()
      Private constructor.
  • Method Details

    • sumSeries

      static double sumSeries(DoubleSupplier func, double epsilon, int maxTerms)
      Sum the series.

      Adapted from boost/math/tools/series.hpp.

      Parameters:
      func - Series generator
      epsilon - Maximum relative error allowed
      maxTerms - Maximum number of terms
      Returns:
      result
    • sumSeries

      static double sumSeries(DoubleSupplier func, double epsilon, int maxTerms, double initValue)
      Sum the series.

      Adapted from boost/math/tools/series.hpp.

      Parameters:
      func - Series generator
      epsilon - Maximum relative error allowed
      maxTerms - Maximum number of terms
      initValue - Initial value
      Returns:
      result
    • kahanSumSeries

      static double kahanSumSeries(DoubleSupplier func, double epsilon, int maxTerms)
      Sum the series using Kahan summation.

      Adapted from boost/math/tools/series.hpp.

      Parameters:
      func - Series generator
      epsilon - Maximum relative error allowed
      maxTerms - Maximum number of terms
      Returns:
      result
    • kahanSumSeries

      static double kahanSumSeries(DoubleSupplier func, double epsilon, int maxTerms, double initValue)
      Sum the series using Kahan summation.

      Adapted from boost/math/tools/series.hpp.

      Parameters:
      func - Series generator
      epsilon - Maximum relative error allowed
      maxTerms - Maximum number of terms
      initValue - Initial value
      Returns:
      result
    • getEpsilon

      private static double getEpsilon(double epsilon, double minEpsilon)
      Gets the epsilon ensuring it satisfies the minimum allowed value.

      This is returning the maximum of the two arguments. Do not use Math.max as it returns NaN if either value is NaN. In this case the desired result in the default minEpsilon, not NaN. Math.max will also check ordering when terms are equal to support -0.0 and 0.0. This does not apply here and a single conditional returns the desired result.

      Parameters:
      epsilon - Configured epsilon
      minEpsilon - Minimum allowed epsilon
      Returns:
      the epsilon
    • evaluatePolynomial

      static double evaluatePolynomial(double[] c, double x)
      Evaluate the polynomial using Horner's method. The coefficients are used in descending order, for example a polynomial of order 3 requires 4 coefficients:
       f(x) = c[3] * x^3 + c[2] * x^2 + c[1] * x + c[0]
       
      Parameters:
      c - Polynomial coefficients (must have length > 0)
      x - Argument x
      Returns:
      polynomial value