Class StableSampler.SpecialMath

  • Enclosing class:
    StableSampler

    static final class StableSampler.SpecialMath
    extends java.lang.Object
    Implement special math functions required by the CMS algorithm.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      private static double FOUR_PI
      4/pi.
      private static double P0
      tan2 product constant.
      private static double P1
      tan2 product constant.
      private static double P2
      tan2 product constant.
      private static double P3
      tan2 product constant.
      private static double P4
      tan2 product constant.
      private static double PI_4
      pi/4.
      private static double Q0
      tan2 quotient constant.
      private static double Q1
      tan2 quotient constant.
      private static double Q2
      tan2 quotient constant.
      private static double Q3
      tan2 quotient constant.
      private static double Q4
      tan2 quotient constant.
      private static double SWITCH_TO_EXPM1
      The threshold to switch to using Math.expm1(double).
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private SpecialMath()
      No instances.
    • Method Summary

      All Methods Static Methods Concrete Methods 
      Modifier and Type Method Description
      (package private) static double d2​(double x)
      Evaluate (exp(x) - 1) / x.
      (package private) static double tan2​(double x)
      Evaluate tan(x) / x.
      • Methods inherited from class java.lang.Object

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

      • SWITCH_TO_EXPM1

        private static final double SWITCH_TO_EXPM1
        The threshold to switch to using Math.expm1(double). The following table shows the mean (max) ULP difference between using expm1 and exp using random +/-x with different exponents (n=2^30):
         x        exp  positive x                 negative x
         64.0      6   0.10004021506756544  (2)   0.0                   (0)
         32.0      5   0.11177831795066595  (2)   0.0                   (0)
         16.0      4   0.0986650362610817   (2)   9.313225746154785E-10 (1)
         8.0       3   0.09863092936575413  (2)   4.9658119678497314E-6 (1)
         4.0       2   0.10015273280441761  (2)   4.547201097011566E-4  (1)
         2.0       1   0.14359260816127062  (2)   0.005623611621558666  (2)
         1.0       0   0.20160607434809208  (2)   0.03312791418284178   (2)
         0.5      -1   0.3993037799373269   (2)   0.28186883218586445   (2)
         0.25     -2   0.6307008266448975   (2)   0.5192863345146179    (2)
         0.125    -3   1.3862918205559254   (4)   1.386285437270999     (4)
         0.0625   -4   2.772640804760158    (8)   2.772612397558987     (8)
         

        The threshold of 0.5 has a mean ULP below 0.5 and max ULP of 2. The transition is monotonic. Neither is true for the next threshold of 0.25.

        See Also:
        Constant Field Values
    • Constructor Detail

      • SpecialMath

        private SpecialMath()
        No instances.
    • Method Detail

      • d2

        static double d2​(double x)
        Evaluate (exp(x) - 1) / x. For x in the range [-inf, inf] returns a result in [0, inf].
        • For x=-inf this returns 0.
        • For x=0 this returns 1.
        • For x=inf this returns inf.
        • For x=nan this returns nan.

        This corrects 0 / 0 and inf / inf division from NaN to either 1 or the upper bound respectively.

        Parameters:
        x - value to evaluate
        Returns:
        (exp(x) - 1) / x.
      • tan2

        static double tan2​(double x)
        Evaluate tan(x) / x.

        For x in the range [0, pi/4] this returns a value in the range [1, 4 / pi].

        The following properties are desirable for the CMS algorithm:

        • For x=0 this returns 1.
        • For x=pi/4 this returns 4/pi.
        • For x=pi/4 this multiplied by x returns 1.

        This method is called by the CMS algorithm when x < pi/4. In this case the method is almost as accurate as Math.tan(x) / x, does not require checking for x=0 and is faster.

        Parameters:
        x - the x
        Returns:
        tan(x) / x.