Example usage for java.math BigDecimal ulp

List of usage examples for java.math BigDecimal ulp

Introduction

In this page you can find the example usage for java.math BigDecimal ulp.

Prototype

public BigDecimal ulp() 

Source Link

Document

Returns the size of an ulp, a unit in the last place, of this BigDecimal .

Usage

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Pochhammers function.//from w  w w  . j  av a  2 s.  c o  m
 *
 * @param x The main argument.
 * @param n The non-negative index.
 * @return (x)_n = x(x+1)(x+2)*...*(x+n-1).
 */
static public BigDecimal pochhammer(final BigDecimal x, final int n) {
    /* reduce to interval near 1.0 with the functional relation, Abramowitz-Stegun 6.1.33
     */
    if (n < 0) {
        throw new ProviderException("Unimplemented pochhammer with negative index " + n);
    } else if (n == 0) {
        return BigDecimal.ONE;
    } else {
        /* internally two safety digits
         */
        BigDecimal xhighpr = scalePrec(x, 2);
        BigDecimal resul = xhighpr;

        double xUlpDbl = x.ulp().doubleValue();

        double xDbl = x.doubleValue();
        /* relative error of the result is the sum of the relative errors of the factors
         */

        double eps = 0.5 * xUlpDbl / Math.abs(xDbl);

        for (int i = 1; i < n; i++) {
            eps += 0.5 * xUlpDbl / Math.abs(xDbl + i);

            resul = resul.multiply(xhighpr.add(new BigDecimal(i)));
            final MathContext mcloc = new MathContext(4 + err2prec(eps));
            resul = resul.round(mcloc);

        }
        return resul.round(new MathContext(err2prec(eps)));

    }
}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Reduce value to the interval [0,2*Pi].
 *
 * @param x the original value/*from  w  w  w  .j  a  v  a2 s. co m*/
 * @return the value modulo 2*pi in the interval from 0 to 2*pi.
 */
static public BigDecimal mod2pi(BigDecimal x) {
    /* write x= 2*pi*k+r with the precision in r defined by the precision of x and not
     * compromised by the precision of 2*pi, so the ulp of 2*pi*k should match the ulp of x.
     * First getFloat a guess of k to figure out how many digits of 2*pi are needed.
     */
    int k = (int) (0.5 * x.doubleValue() / Math.PI);
    /* want to have err(2*pi*k)< err(x)=0.5*x.ulp, so err(pi) = err(x)/(4k) with two safety digits
     */

    double err2pi;

    if (k != 0) {
        err2pi = 0.25 * Math.abs(x.ulp().doubleValue() / k);
    } else {
        err2pi = 0.5 * Math.abs(x.ulp().doubleValue());
    }
    MathContext mc = new MathContext(2 + err2prec(6.283, err2pi));
    BigDecimal twopi = pi(mc).multiply(new BigDecimal(2));
    /* Delegate the actual operation to the BigDecimal class, which may return
     * a negative value of x was negative .
     */
    BigDecimal res = x.remainder(twopi);

    if (res.compareTo(BigDecimal.ZERO) < 0) {
        res = res.add(twopi);
    }
    /* The actual precision is set by the input value, its absolute value of x.ulp()/2.
     */
    mc = new MathContext(err2prec(res.doubleValue(), x.ulp().doubleValue() / 2.));

    return res.round(mc);

}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Reduce value to the interval [-Pi/2,Pi/2].
 *
 * @param x The original value// w  w  w  .  j  a  v a2s  .co m
 * @return The value modulo pi, shifted to the interval from -Pi/2 to Pi/2.
 */
static public BigDecimal modpi(BigDecimal x) {
    /* write x= pi*k+r with the precision in r defined by the precision of x and not
     * compromised by the precision of pi, so the ulp of pi*k should match the ulp of x.
     * First getFloat a guess of k to figure out how many digits of pi are needed.
     */
    int k = (int) (x.doubleValue() / Math.PI);
    /* want to have err(pi*k)< err(x)=x.ulp/2, so err(pi) = err(x)/(2k) with two safety digits
     */

    double errpi;

    if (k != 0) {
        errpi = 0.5 * Math.abs(x.ulp().doubleValue() / k);
    } else {
        errpi = 0.5 * Math.abs(x.ulp().doubleValue());
    }
    MathContext mc = new MathContext(2 + err2prec(3.1416, errpi));
    BigDecimal onepi = pi(mc);
    BigDecimal pihalf = onepi.divide(new BigDecimal(2));
    /* Delegate the actual operation to the BigDecimal class, which may return
     * a negative value of x was negative .
     */
    BigDecimal res = x.remainder(onepi);

    if (res.compareTo(pihalf) > 0) {
        res = res.subtract(onepi);
    } else if (res.compareTo(pihalf.negate()) < 0) {
        res = res.add(onepi);
    }
    /* The actual precision is set by the input value, its absolute value of x.ulp()/2.
     */
    mc = new MathContext(err2prec(res.doubleValue(), x.ulp().doubleValue() / 2.));

    return res.round(mc);

}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Add and round according to the larger of the two ulps.
 *
 * @param x The left summand/*from  w w w  .j a  va2  s.  c  o  m*/
 * @param y The right summand
 * @return The sum x+y.
 */
static public BigDecimal addRound(final BigDecimal x, final BigDecimal y) {
    BigDecimal resul = x.add(y);
    /* The estimation of the absolute error in the result is |err(y)|+|err(x)|
     */

    double errR = Math.abs(y.ulp().doubleValue() / 2.) + Math.abs(x.ulp().doubleValue() / 2.);
    MathContext mc = new MathContext(err2prec(resul.doubleValue(), errR));

    return resul.round(mc);

}

From source file:org.nd4j.linalg.util.BigDecimalMath.java

/**
 * Subtract and round according to the larger of the two ulps.
 *
 * @param x The left term./* w w  w  .jav a 2 s .c  o m*/
 * @param y The right term.
 * @return The difference x-y.
 */
static public BigDecimal subtractRound(final BigDecimal x, final BigDecimal y) {
    BigDecimal resul = x.subtract(y);
    /* The estimation of the absolute error in the result is |err(y)|+|err(x)|
     */

    double errR = Math.abs(y.ulp().doubleValue() / 2.) + Math.abs(x.ulp().doubleValue() / 2.);
    MathContext mc = new MathContext(err2prec(resul.doubleValue(), errR));

    return resul.round(mc);

}