Example usage for java.math BigDecimal pow

List of usage examples for java.math BigDecimal pow

Introduction

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

Prototype

public BigDecimal pow(int n, MathContext mc) 

Source Link

Document

Returns a BigDecimal whose value is (thisn).

Usage

From source file:Main.java

public static void main(String[] args) {

    MathContext mc = new MathContext(4); // 4 precision

    BigDecimal bg1 = new BigDecimal("2.17");

    BigDecimal bg2 = bg1.pow(3, mc);

    System.out.println(bg2);/*from w  w  w  . ja  va 2 s . co  m*/
}

From source file:Main.java

public static BigDecimal cuberoot(BigDecimal b) {
    // Specify a math context with 40 digits of precision.

    MathContext mc = new MathContext(40);

    BigDecimal x = new BigDecimal("1", mc);

    // Search for the cube root via the Newton-Raphson loop. Output each // successive iteration's value.

    for (int i = 0; i < ITER; i++) {
        x = x.subtract(//from w  ww .ja  v  a2s .c o m
                x.pow(3, mc).subtract(b, mc).divide(new BigDecimal("3", mc).multiply(x.pow(2, mc), mc), mc),
                mc);
    }
    return x;
}

From source file:Main.java

public static BigDecimal cuberoot(BigDecimal b) {
    // Specify a math context with 40 digits of precision.

    MathContext mc = new MathContext(40);

    BigDecimal x = new BigDecimal("1", mc);

    // Search for the cube root via the Newton-Raphson loop. Output each //
    // successive iteration's value.

    for (int i = 0; i < ITER; i++) {
        x = x.subtract(//from w w  w  . ja  va2s.  c  om
                x.pow(3, mc).subtract(b, mc).divide(new BigDecimal("3", mc).multiply(x.pow(2, mc), mc), mc),
                mc);
    }
    return x;
}

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

/**
 * The exponential function.//from www  .  j  a  v a2  s . co m
 *
 * @param x the argument.
 * @return exp(x).
 * The precision of the result is implicitly defined by the precision in the argument.
 * 16
 * In particular this means that "Invalid Operation" errors are thrown if catastrophic
 * cancellation of digits causes the result to have no valid digits left.
 */
static public BigDecimal exp(BigDecimal x) {
    /* To calculate the value if x is negative, use exp(-x) = 1/exp(x)
     */
    if (x.compareTo(BigDecimal.ZERO) < 0) {
        final BigDecimal invx = exp(x.negate());
        /* Relative error in inverse of invx is the same as the relative errror in invx.
         * This is used to define the precision of the result.
         */
        MathContext mc = new MathContext(invx.precision());
        return BigDecimal.ONE.divide(invx, mc);
    } else if (x.compareTo(BigDecimal.ZERO) == 0) {
        /* recover the valid number of digits from x.ulp(), if x hits the
         * zero. The x.precision() is 1 then, and does not provide this information.
         */
        return scalePrec(BigDecimal.ONE, -(int) (Math.log10(x.ulp().doubleValue())));
    } else {
        /* Push the number in the Taylor expansion down to a small
         * value where TAYLOR_NTERM terms will do. If x<1, the n-th term is of the order
         * x^n/n!, and equal to both the absolute and relative error of the result
         * since the result is close to 1. The x.ulp() sets the relative and absolute error
         * of the result, as estimated from the first Taylor term.
         * We want x^TAYLOR_NTERM/TAYLOR_NTERM! < x.ulp, which is guaranteed if
         * x^TAYLOR_NTERM < TAYLOR_NTERM*(TAYLOR_NTERM-1)*...*x.ulp.
         */
        final double xDbl = x.doubleValue();
        final double xUlpDbl = x.ulp().doubleValue();
        if (Math.pow(xDbl, TAYLOR_NTERM) < TAYLOR_NTERM * (TAYLOR_NTERM - 1.0) * (TAYLOR_NTERM - 2.0)
                * xUlpDbl) {
            /* Add TAYLOR_NTERM terms of the Taylor expansion (Eulers sum formula)
             */
            BigDecimal resul = BigDecimal.ONE;
            /* x^i */
            BigDecimal xpowi = BigDecimal.ONE;
            /* i factorial */
            BigInteger ifac = BigInteger.ONE;
            /* TAYLOR_NTERM terms to be added means we move x.ulp() to the right
             * for each power of 10 in TAYLOR_NTERM, so the addition wont add noise beyond
             * whats already in x.
             */
            MathContext mcTay = new MathContext(err2prec(1., xUlpDbl / TAYLOR_NTERM));
            for (int i = 1; i <= TAYLOR_NTERM; i++) {
                ifac = ifac.multiply(new BigInteger("" + i));
                xpowi = xpowi.multiply(x);
                final BigDecimal c = xpowi.divide(new BigDecimal(ifac), mcTay);
                resul = resul.add(c);
                if (Math.abs(xpowi.doubleValue()) < i && Math.abs(c.doubleValue()) < 0.5 * xUlpDbl) {
                    break;
                }
            }
            /* exp(x+deltax) = exp(x)(1+deltax) if deltax is <<1. So the relative error
             * in the result equals the absolute error in the argument.
             */
            MathContext mc = new MathContext(err2prec(xUlpDbl / 2.));
            return resul.round(mc);
        } else {
            /* Compute exp(x) = (exp(0.1*x))^10. Division by 10 does not lead
             * to loss of accuracy.
             */
            int exSc = (int) (1.0 - Math.log10(TAYLOR_NTERM * (TAYLOR_NTERM - 1.0) * (TAYLOR_NTERM - 2.0)
                    * xUlpDbl / Math.pow(xDbl, TAYLOR_NTERM)) / (TAYLOR_NTERM - 1.0));
            BigDecimal xby10 = x.scaleByPowerOfTen(-exSc);
            BigDecimal expxby10 = exp(xby10);
            /* Final powering by 10 means that the relative error of the result
             * is 10 times the relative error of the base (First order binomial expansion).
             * This looses one digit.
             */
            MathContext mc = new MathContext(expxby10.precision() - exSc);
            /* Rescaling the powers of 10 is done in chunks of a maximum of 8 to avoid an invalid operation
            17
             * response by the BigDecimal.pow library or integer overflow.
             */
            while (exSc > 0) {
                int exsub = Math.min(8, exSc);
                exSc -= exsub;
                MathContext mctmp = new MathContext(expxby10.precision() - exsub + 2);
                int pex = 1;
                while (exsub-- > 0) {
                    pex *= 10;
                }
                expxby10 = expxby10.pow(pex, mctmp);
            }
            return expxby10.round(mc);
        }
    }
}

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

/**
 * Raise to an integer power and round./*from ww  w . j  av  a  2s  .  c o  m*/
 *
 * @param x The base.
 * @param n The exponent.
 * @return x^n.
 */
static public BigDecimal powRound(final BigDecimal x, final int n) {
    /* The relative error in the result is n times the relative error in the input.
     * The estimation is slightly optimistic due to the integer rounding of the logarithm.
     */
    MathContext mc = new MathContext(x.precision() - (int) Math.log10((double) (Math.abs(n))));
    return x.pow(n, mc);
}

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

/**
 * The Gamma function.//from ww w .  j  a v a 2s.c o  m
 *
 * @param x The argument.
 * @return Gamma(x).
 */
static public BigDecimal Gamma(final BigDecimal x) {
    /* reduce to interval near 1.0 with the functional relation, Abramowitz-Stegun 6.1.33
     */
    if (x.compareTo(BigDecimal.ZERO) < 0) {
        return divideRound(Gamma(x.add(BigDecimal.ONE)), x);
    } else if (x.doubleValue() > 1.5) {
        /* Gamma(x) = Gamma(xmin+n) = Gamma(xmin)*Pochhammer(xmin,n).
         */
        int n = (int) (x.doubleValue() - 0.5);
        BigDecimal xmin1 = x.subtract(new BigDecimal(n));

        return multiplyRound(Gamma(xmin1), pochhammer(xmin1, n));

    } else {
        /* apply Abramowitz-Stegun 6.1.33
         */
        BigDecimal z = x.subtract(BigDecimal.ONE);
        /* add intermediately 2 digits to the partial sum accumulation
         */
        z = scalePrec(z, 2);
        MathContext mcloc = new MathContext(z.precision());
        /* measure of the absolute error is the relative error in the first, logarithmic term
         */

        double eps = x.ulp().doubleValue() / x.doubleValue();
        BigDecimal resul = log(scalePrec(x, 2)).negate();

        if (x.compareTo(BigDecimal.ONE) != 0) {
            BigDecimal gammCompl = BigDecimal.ONE.subtract(gamma(mcloc));
            resul = resul.add(multiplyRound(z, gammCompl));

            for (int n = 2;; n++) {
                /* multiplying z^n/n by zeta(n-1) means that the two relative errors add.
                 * so the requirement in the relative error of zeta(n)-1 is that this is somewhat
                 * smaller than the relative error in z^n/n (the absolute error of thelatter is the
                 * absolute error in z)
                 */
                BigDecimal c = divideRound(z.pow(n, mcloc), n);
                MathContext m = new MathContext(err2prec(n * z.ulp().doubleValue() / 2. / z.doubleValue()));
                c = c.round(m);
                /* At larger n, zeta(n)-1 is roughly 1/2^n. The product is c/2^n.
                 * The relative error in c is c.ulp/2/c . The error in the product should be small versus eps/10.
                 * Error from 1/2^n is c*err(sigma-1).
                 * We need a relative error of zeta-1 of the order of c.ulp/50/c. This is an absolute
                 * error in zeta-1 of c.ulp/50/c/2^n, and also the absolute error in zeta, because zeta is
                 * of the order of 1.
                 */

                if (eps / 100. / c.doubleValue() < 0.01) {
                    m = new MathContext(err2prec(eps / 100. / c.doubleValue()));
                } else {
                    m = new MathContext(2);
                }
                /* zeta(n) -1 */
                BigDecimal zetm1 = zeta(n, m).subtract(BigDecimal.ONE);
                c = multiplyRound(c, zetm1);

                if (n % 2 == 0) {
                    resul = resul.add(c);
                } else {
                    resul = resul.subtract(c);
                }
                /* alternating sum, so truncating as eps is reached suffices
                 */

                if (Math.abs(c.doubleValue()) < eps) {
                    break;
                }

            }
        }
        /* The relative error in the result is the absolute error in the
         * input variable times the digamma (psi) value at that point.
         */
        double psi = 0.5772156649;

        double zdbl = z.doubleValue();

        for (int n = 1; n < 5; n++) {
            psi += zdbl / n / (n + zdbl);
        }
        eps = psi * x.ulp().doubleValue() / 2.;
        mcloc = new MathContext(err2prec(eps));

        return exp(resul).round(mcloc);

    }
}