Example usage for java.math BigDecimal negate

List of usage examples for java.math BigDecimal negate

Introduction

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

Prototype

public BigDecimal negate() 

Source Link

Document

Returns a BigDecimal whose value is (-this) , and whose scale is this.scale() .

Usage

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

/**
 * Trigonometric sine./*from  w  w  w  .  jav a 2s.co  m*/
 *
 * @param x The argument in radians.
 * @return sin(x) in the range -1 to 1.
 */
static public BigDecimal sin(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ZERO) < 0) {
        return sin(x.negate()).negate();
    } else if (x.compareTo(BigDecimal.ZERO) == 0) {
        return BigDecimal.ZERO;
    } else {
        /* reduce modulo 2pi
         */
        BigDecimal res = mod2pi(x);
        double errpi = 0.5 * Math.abs(x.ulp().doubleValue());
        int val = 2 + err2prec(FastMath.PI, errpi);
        MathContext mc = new MathContext(val);
        BigDecimal p = pi(mc);
        mc = new MathContext(x.precision());
        if (res.compareTo(p) > 0) {
            /* pi<x<=2pi: sin(x)= - sin(x-pi)
             */
            return sin(subtractRound(res, p)).negate();
        } else if (res.multiply(new BigDecimal("2")).compareTo(p) > 0) {
            /* pi/2<x<=pi: sin(x)= sin(pi-x)
             */
            return sin(subtractRound(p, res));
        } else {
            /* for the range 0<=x<Pi/2 one could use sin(2x)=2sin(x)cos(x)
             * to split this further. Here, use the sine up to pi/4 and the cosine higher up.
             */
            if (res.multiply(new BigDecimal("4")).compareTo(p) > 0) {
                /* x>pi/4: sin(x) = cos(pi/2-x)
                 */
                return cos(subtractRound(p.divide(new BigDecimal("2")), res));
            } else {
                /* Simple Taylor expansion, sum_{i=1..infinity} (-1)^(..)res^(2i+1)/(2i+1)! */
                BigDecimal resul = res;
                /* x^i */
                BigDecimal xpowi = res;
                /* 2i+1 factorial */
                BigInteger ifac = BigInteger.ONE;
                /* The error in the result is set by the error in x itself.
                 */
                double xUlpDbl = res.ulp().doubleValue();
                /* The error in the result is set by the error in x itself.
                 * We need at most k terms to squeeze x^(2k+1)/(2k+1)! below this value.
                 * x^(2k+1) < x.ulp; (2k+1)*log10(x) < -x.precision; 2k*log10(x)< -x.precision;
                 * 2k*(-log10(x)) > x.precision; 2k*log10(1/x) > x.precision
                 */
                int k = (int) (res.precision() / Math.log10(1.0 / res.doubleValue())) / 2;
                MathContext mcTay = new MathContext(err2prec(res.doubleValue(), xUlpDbl / k));
                for (int i = 1;; i++) {
                    /* TBD: at which precision will 2*i or 2*i+1 overflow?
                     */
                    ifac = ifac.multiply(new BigInteger("" + (2 * i)));
                    ifac = ifac.multiply(new BigInteger("" + (2 * i + 1)));
                    xpowi = xpowi.multiply(res).multiply(res).negate();
                    BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
                    resul = resul.add(corr);
                    if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
                        break;
                    }
                }
                /* The error in the result is set by the error in x itself.
                 */
                mc = new MathContext(res.precision());
                return resul.round(mc);
            }
        }
    } /* sin */
}

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

/**
 * Trigonometric cosine./* w  w  w  .  java2s .  c  om*/
 *
 * @param x The argument in radians.
 * @return cos(x) in the range -1 to 1.
 */
static public BigDecimal cos(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ZERO) < 0) {
        return cos(x.negate());
    } else if (x.compareTo(BigDecimal.ZERO) == 0) {
        return BigDecimal.ONE;
    } else {
        /* reduce modulo 2pi
         */
        BigDecimal res = mod2pi(x);
        double errpi = 0.5 * Math.abs(x.ulp().doubleValue());
        int val = +err2prec(FastMath.PI, errpi);
        MathContext mc = new MathContext(val);
        BigDecimal p = pi(mc);
        mc = new MathContext(x.precision());
        if (res.compareTo(p) > 0) {
            /* pi<x<=2pi: cos(x)= - cos(x-pi)
             */
            return cos(subtractRound(res, p)).negate();
        } else if (res.multiply(new BigDecimal("2")).compareTo(p) > 0) {
            /* pi/2<x<=pi: cos(x)= -cos(pi-x)
             */
            return cos(subtractRound(p, res)).negate();
        } else {
            /* for the range 0<=x<Pi/2 one could use cos(2x)= 1-2*sin^2(x)
             * to split this further, or use the cos up to pi/4 and the sine higher up.
            throw new ProviderException("Unimplemented cosine ") ;
             */
            if (res.multiply(new BigDecimal("4")).compareTo(p) > 0) {
                /* x>pi/4: cos(x) = sin(pi/2-x)
                 */
                return sin(subtractRound(p.divide(new BigDecimal("2")), res));
            } else {
                /* Simple Taylor expansion, sum_{i=0..infinity} (-1)^(..)res^(2i)/(2i)! */
                BigDecimal resul = BigDecimal.ONE;
                /* x^i */
                BigDecimal xpowi = BigDecimal.ONE;
                /* 2i factorial */
                BigInteger ifac = BigInteger.ONE;
                /* The absolute error in the result is the error in x^2/2 which is x times the error in x.
                 */
                double xUlpDbl = 0.5 * res.ulp().doubleValue() * res.doubleValue();
                /* The error in the result is set by the error in x^2/2 itself, xUlpDbl.
                 * We need at most k terms to push x^(2k+1)/(2k+1)! below this value.
                 * x^(2k) < xUlpDbl; (2k)*log(x) < log(xUlpDbl);
                 */
                int k = (int) (Math.log(xUlpDbl) / Math.log(res.doubleValue())) / 2;
                MathContext mcTay = new MathContext(err2prec(1., xUlpDbl / k));
                for (int i = 1;; i++) {
                    /* TBD: at which precision will 2*i-1 or 2*i overflow?
                     */
                    ifac = ifac.multiply(new BigInteger("" + (2 * i - 1)));
                    ifac = ifac.multiply(new BigInteger("" + (2 * i)));
                    xpowi = xpowi.multiply(res).multiply(res).negate();
                    BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
                    resul = resul.add(corr);
                    if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
                        break;
                    }
                }
                /* The error in the result is governed by the error in x itself.
                 */
                mc = new MathContext(err2prec(resul.doubleValue(), xUlpDbl));
                return resul.round(mc);
            }
        }
    }
}

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

/**
 * The hyperbolic sine.//from   ww w. ja va2  s.c om
 *
 * @param x the argument.
 * @return the sinh(x) = (exp(x)-exp(-x))/2 .
 */
static public BigDecimal sinh(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ZERO) < 0) {
        return sinh(x.negate()).negate();
    } else if (x.compareTo(BigDecimal.ZERO) == 0) {
        return BigDecimal.ZERO;
    } else {
        if (x.doubleValue() > 2.4) {
            /* Move closer to zero with sinh(2x)= 2*sinh(x)*cosh(x).
             */
            BigDecimal two = new BigDecimal(2);
            BigDecimal xhalf = x.divide(two);

            BigDecimal resul = sinh(xhalf).multiply(cosh(xhalf)).multiply(two);
            /* The error in the result is set by the error in x itself.
             * The first derivative of sinh(x) is cosh(x), so the absolute error
             * in the result is cosh(x)*errx, and the relative error is coth(x)*errx = errx/tanh(x)
             */

            double eps = Math.tanh(x.doubleValue());
            MathContext mc = new MathContext(err2prec(0.5 * x.ulp().doubleValue() / eps));

            return resul.round(mc);

        } else {
            BigDecimal xhighpr = scalePrec(x, 2);
            /* Simple Taylor expansion, sum_{i=0..infinity} x^(2i+1)/(2i+1)! */
            BigDecimal resul = xhighpr;
            /* x^i */
            BigDecimal xpowi = xhighpr;
            /* 2i+1 factorial */
            BigInteger ifac = BigInteger.ONE;
            /* The error in the result is set by the error in x itself.
             */

            double xUlpDbl = x.ulp().doubleValue();
            /* The error in the result is set by the error in x itself.
             * We need at most k terms to squeeze x^(2k+1)/(2k+1)! below this value.
             * x^(2k+1) < x.ulp; (2k+1)*log10(x) < -x.precision; 2k*log10(x)< -x.precision;
             * 2k*(-log10(x)) > x.precision; 2k*log10(1/x) > x.precision
             */

            int k = (int) (x.precision() / Math.log10(1.0 / xhighpr.doubleValue())) / 2;
            MathContext mcTay = new MathContext(err2prec(x.doubleValue(), xUlpDbl / k));

            for (int i = 1;; i++) {
                /* TBD: at which precision will 2*i or 2*i+1 overflow?
                 */
                ifac = ifac.multiply(new BigInteger("" + (2 * i)));
                ifac = ifac.multiply(new BigInteger("" + (2 * i + 1)));
                xpowi = xpowi.multiply(xhighpr).multiply(xhighpr);
                BigDecimal corr = xpowi.divide(new BigDecimal(ifac), mcTay);
                resul = resul.add(corr);

                if (corr.abs().doubleValue() < 0.5 * xUlpDbl) {
                    break;
                }

            } /* The error in the result is set by the error in x itself.
              */
            MathContext mc = new MathContext(x.precision());

            return resul.round(mc);

        }
    }
}

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

/**
 * The inverse trigonometric tangent./*from   www  .  ja v  a 2s. c  om*/
 *
 * @param x the argument.
 * @return the principal value of arctan(x) in radians in the range -pi/2 to +pi/2.
 */
static public BigDecimal atan(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ZERO) < 0) {
        return atan(x.negate()).negate();

    } else if (x.compareTo(BigDecimal.ZERO) == 0) {
        return BigDecimal.ZERO;
    } else if (x.doubleValue() > 0.7 && x.doubleValue() < 3.0) {
        /* Abramowitz-Stegun 4.4.34 convergence acceleration
         * 2*arctan(x) = arctan(2x/(1-x^2)) = arctan(y). x=(sqrt(1+y^2)-1)/y
         * This maps 0<=y<=3 to 0<=x<=0.73 roughly. Temporarily with 2 protectionist digits.
         */
        BigDecimal y = scalePrec(x, 2);
        BigDecimal newx = divideRound(hypot(1, y).subtract(BigDecimal.ONE), y);
        /* intermediate result with too optimistic error estimate*/
        BigDecimal resul = multiplyRound(atan(newx), 2);
        /* absolute error in the result is errx/(1+x^2), where errx = half of the ulp. */

        double eps = x.ulp().doubleValue() / (2.0 * Math.hypot(1.0, x.doubleValue()));
        MathContext mc = new MathContext(err2prec(resul.doubleValue(), eps));

        return resul.round(mc);

    } else if (x.doubleValue() < 0.71) {
        /* Taylor expansion around x=0; Abramowitz-Stegun 4.4.42 */
        final BigDecimal xhighpr = scalePrec(x, 2);
        final BigDecimal xhighprSq = multiplyRound(xhighpr, xhighpr).negate();
        BigDecimal resul = xhighpr.plus();
        /* signed x^(2i+1) */
        BigDecimal xpowi = xhighpr;
        /* absolute error in the result is errx/(1+x^2), where errx = half of the ulp.
         */

        double eps = x.ulp().doubleValue() / (2.0 * Math.hypot(1.0, x.doubleValue()));

        for (int i = 1;; i++) {
            xpowi = multiplyRound(xpowi, xhighprSq);
            BigDecimal c = divideRound(xpowi, 2 * i + 1);
            resul = resul.add(c);

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

        }
        MathContext mc = new MathContext(err2prec(resul.doubleValue(), eps));

        return resul.round(mc);

    } else {
        /* Taylor expansion around x=infinity; Abramowitz-Stegun 4.4.42 */
        /* absolute error in the result is errx/(1+x^2), where errx = half of the ulp.
         */
        double eps = x.ulp().doubleValue() / (2.0 * Math.hypot(1.0, x.doubleValue()));
        /* start with the term pi/2; gather its precision relative to the expected result
         */
        MathContext mc = new MathContext(2 + err2prec(3.1416, eps));
        BigDecimal onepi = pi(mc);
        BigDecimal resul = onepi.divide(new BigDecimal(2));
        final BigDecimal xhighpr = divideRound(-1, scalePrec(x, 2));
        final BigDecimal xhighprSq = multiplyRound(xhighpr, xhighpr).negate();
        /* signed x^(2i+1) */
        BigDecimal xpowi = xhighpr;

        for (int i = 0;; i++) {
            BigDecimal c = divideRound(xpowi, 2 * i + 1);
            resul = resul.add(c);

            if (Math.abs(c.doubleValue()) < 0.1 * eps) {
                break;
            }
            xpowi = multiplyRound(xpowi, xhighprSq);

        }
        mc = new MathContext(err2prec(resul.doubleValue(), eps));

        return resul.round(mc);

    }
}

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

/**
 * The trigonometric tangent./*from ww  w .  j av a2 s . c  om*/
 *
 * @param x the argument in radians.
 * @return the tan(x)
 */
static public BigDecimal tan(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ZERO) == 0) {
        return BigDecimal.ZERO;
    } else if (x.compareTo(BigDecimal.ZERO) < 0) {
        return tan(x.negate()).negate();
    } else {
        /* reduce modulo pi
         */
        BigDecimal res = modpi(x);
        /* absolute error in the result is err(x)/cos^2(x) to lowest order
         */
        final double xDbl = res.doubleValue();
        final double xUlpDbl = x.ulp().doubleValue() / 2.;
        final double eps = xUlpDbl / 2. / Math.pow(Math.cos(xDbl), 2.);
        if (xDbl > 0.8) {
            /* tan(x) = 1/cot(x) */
            BigDecimal co = cot(x);
            MathContext mc = new MathContext(err2prec(1. / co.doubleValue(), eps));
            return BigDecimal.ONE.divide(co, mc);
        } else {
            final BigDecimal xhighpr = scalePrec(res, 2);
            final BigDecimal xhighprSq = multiplyRound(xhighpr, xhighpr);
            BigDecimal resul = xhighpr.plus();
            /* x^(2i+1) */
            BigDecimal xpowi = xhighpr;
            Bernoulli b = new Bernoulli();
            /* 2^(2i) */
            BigInteger fourn = new BigInteger("4");
            /* (2i)! */
            BigInteger fac = new BigInteger("2");
            for (int i = 2;; i++) {
                Rational f = b.at(2 * i).abs();
                fourn = fourn.shiftLeft(2);
                fac = fac.multiply(new BigInteger("" + (2 * i))).multiply(new BigInteger("" + (2 * i - 1)));
                f = f.multiply(fourn).multiply(fourn.subtract(BigInteger.ONE)).divide(fac);
                xpowi = multiplyRound(xpowi, xhighprSq);
                BigDecimal c = multiplyRound(xpowi, f);
                resul = resul.add(c);
                if (Math.abs(c.doubleValue()) < 0.1 * eps) {
                    break;
                }
            }
            MathContext mc = new MathContext(err2prec(resul.doubleValue(), eps));
            return resul.round(mc);
        }
    }
}

From source file:org.kuali.kpme.tklm.leave.payout.service.LeavePayoutServiceImpl.java

@Override
public LeavePayout payout(LeavePayout leavePayout) {
    if (ObjectUtils.isNull(leavePayout)) {
        //         throw new RuntimeException("did not supply a valid LeavePayout object.");
        LOG.error("did not supply a valid LeavePayout object.");
        return null;
    } else {/*  w  w w.  j a va  2s .  c o m*/
        List<LeaveBlockBo> leaveBlocks = new ArrayList<LeaveBlockBo>();
        BigDecimal transferAmount = leavePayout.getPayoutAmount();
        LeaveBlockBo aLeaveBlock = null;

        if (ObjectUtils.isNotNull(transferAmount)) {
            if (transferAmount.compareTo(BigDecimal.ZERO) > 0) {

                aLeaveBlock = new LeaveBlockBo();
                //Create a leave block that adds the adjusted transfer amount to the "transfer to" accrual category.
                aLeaveBlock.setPrincipalId(leavePayout.getPrincipalId());
                aLeaveBlock.setLeaveDate(leavePayout.getEffectiveDate());
                aLeaveBlock.setEarnCode(leavePayout.getEarnCode());
                aLeaveBlock.setAccrualCategory(leavePayout.getEarnCodeObj().getAccrualCategory());
                aLeaveBlock.setDescription("Amount payed out");
                aLeaveBlock.setLeaveAmount(leavePayout.getPayoutAmount());
                aLeaveBlock.setAccrualGenerated(true);
                aLeaveBlock.setTransactionDocId(leavePayout.getDocumentHeaderId());
                aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT);
                aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.REQUESTED);
                aLeaveBlock.setDocumentId(leavePayout.getLeaveCalendarDocumentId());
                aLeaveBlock.setBlockId(0L);

                //Want to store the newly created leave block id on this maintainable object
                //when the status of the maintenance document encapsulating this maintainable changes
                //the id will be used to fetch and update the leave block statuses.
                LeaveBlock lb = LmServiceLocator.getLeaveBlockService().saveLeaveBlock(
                        LeaveBlockBo.to(aLeaveBlock), GlobalVariables.getUserSession().getPrincipalId());

                leavePayout.setPayoutLeaveBlockId(lb.getLmLeaveBlockId());

                //Create leave block that removes the correct transfer amount from the originating accrual category.
                aLeaveBlock = new LeaveBlockBo();
                aLeaveBlock.setPrincipalId(leavePayout.getPrincipalId());
                aLeaveBlock.setLeaveDate(leavePayout.getEffectiveDate());
                aLeaveBlock.setEarnCode(leavePayout.getFromAccrualCategoryObj().getEarnCode());
                aLeaveBlock.setAccrualCategory(leavePayout.getFromAccrualCategory());
                aLeaveBlock.setDescription("Payout amount");
                aLeaveBlock.setLeaveAmount(leavePayout.getPayoutAmount().negate());
                aLeaveBlock.setAccrualGenerated(true);
                aLeaveBlock.setTransactionDocId(leavePayout.getDocumentHeaderId());
                aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT);
                aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.REQUESTED);
                aLeaveBlock.setDocumentId(leavePayout.getLeaveCalendarDocumentId());
                aLeaveBlock.setBlockId(0L);

                //Want to store the newly created leave block id on this maintainable object.
                //when the status of the maintenance document encapsulating this maintainable changes
                //the id will be used to fetch and update the leave block statuses.
                lb = LmServiceLocator.getLeaveBlockService().saveLeaveBlock(LeaveBlockBo.to(aLeaveBlock),
                        GlobalVariables.getUserSession().getPrincipalId());

                leavePayout.setPayoutFromLeaveBlockId(lb.getLmLeaveBlockId());
            }
        }

        BigDecimal forfeitedAmount = leavePayout.getForfeitedAmount();
        if (ObjectUtils.isNotNull(forfeitedAmount)) {
            //Any amount forfeited must come out of the originating accrual category in order to bring balance back to max.
            if (forfeitedAmount.compareTo(BigDecimal.ZERO) > 0) {
                //for balance transfers with action = lose, transfer amount must be moved to forfeitedAmount
                aLeaveBlock = new LeaveBlockBo();
                aLeaveBlock.setPrincipalId(leavePayout.getPrincipalId());
                aLeaveBlock.setLeaveDate(leavePayout.getEffectiveDate());
                aLeaveBlock.setEarnCode(leavePayout.getFromAccrualCategoryObj().getEarnCode());
                aLeaveBlock.setAccrualCategory(leavePayout.getFromAccrualCategory());
                aLeaveBlock.setDescription(LMConstants.PAYOUT_FORFEIT_LB_DESCRIPTION);
                aLeaveBlock.setLeaveAmount(forfeitedAmount.negate());
                aLeaveBlock.setAccrualGenerated(true);
                aLeaveBlock.setTransactionDocId(leavePayout.getDocumentHeaderId());
                aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.LEAVE_PAYOUT);
                aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.REQUESTED);
                aLeaveBlock.setDocumentId(leavePayout.getLeaveCalendarDocumentId());
                aLeaveBlock.setBlockId(0L);

                //Want to store the newly created leave block id on this maintainable object
                //when the status of the maintenance document encapsulating this maintainable changes
                //the id will be used to fetch and update the leave block statuses.
                LeaveBlock lb = LmServiceLocator.getLeaveBlockService().saveLeaveBlock(
                        LeaveBlockBo.to(aLeaveBlock), GlobalVariables.getUserSession().getPrincipalId());

                leavePayout.setForfeitedLeaveBlockId(lb.getLmLeaveBlockId());
            }
        }
        return leavePayout;
    }
}

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

/**
 * The exponential function./*from w  ww .j a va 2  s.com*/
 *
 * @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

/**
 * The trigonometric co-tangent.//from w  w  w  .  j  av  a 2 s  .c o  m
 *
 * @param x the argument in radians.
 * @return the cot(x)
 */
static public BigDecimal cot(final BigDecimal x) {
    if (x.compareTo(BigDecimal.ZERO) == 0) {
        throw new ArithmeticException("Cannot take cot of zero " + x.toString());
    } else if (x.compareTo(BigDecimal.ZERO) < 0) {
        return cot(x.negate()).negate();
    } else {
        /* reduce modulo pi
         */
        BigDecimal res = modpi(x);
        /* absolute error in the result is err(x)/sin^2(x) to lowest order
         */
        final double xDbl = res.doubleValue();
        final double xUlpDbl = x.ulp().doubleValue() / 2.;
        final double eps = xUlpDbl / 2. / Math.pow(Math.sin(xDbl), 2.);
        final BigDecimal xhighpr = scalePrec(res, 2);
        final BigDecimal xhighprSq = multiplyRound(xhighpr, xhighpr);
        MathContext mc = new MathContext(err2prec(xhighpr.doubleValue(), eps));
        BigDecimal resul = BigDecimal.ONE.divide(xhighpr, mc);
        /* x^(2i-1) */
        BigDecimal xpowi = xhighpr;
        Bernoulli b = new Bernoulli();
        /* 2^(2i) */
        BigInteger fourn = new BigInteger("4");
        /* (2i)! */
        BigInteger fac = BigInteger.ONE;
        for (int i = 1;; i++) {
            Rational f = b.at(2 * i);
            fac = fac.multiply(new BigInteger("" + (2 * i))).multiply(new BigInteger("" + (2 * i - 1)));
            f = f.multiply(fourn).divide(fac);
            BigDecimal c = multiplyRound(xpowi, f);
            if (i % 2 == 0) {
                resul = resul.add(c);
            } else {
                resul = resul.subtract(c);
            }
            if (Math.abs(c.doubleValue()) < 0.1 * eps) {
                break;
            }
            fourn = fourn.shiftLeft(2);
            xpowi = multiplyRound(xpowi, xhighprSq);
        }
        mc = new MathContext(err2prec(resul.doubleValue(), eps));
        return resul.round(mc);
    }
}

From source file:com.excilys.ebi.bank.service.impl.BankServiceImpl.java

@Override
@Transactional(readOnly = false)//www. ja  va 2 s.  c o  m
public void performTransfer(Integer debitedAccountId, Integer creditedAccountId, @Min(10) BigDecimal amount)
        throws UnsufficientBalanceException {

    isTrue(!debitedAccountId.equals(creditedAccountId), "accounts must be different");

    Account debitedAccount = accountDao.findOne(debitedAccountId);
    notNull(debitedAccount, "account with number {} not found", debitedAccount);

    if (debitedAccount.getBalance().compareTo(amount) < 0) {
        throw new UnsufficientBalanceException();
    }

    Account creditedAccount = accountDao.findOne(creditedAccountId);
    notNull(creditedAccount, "account with number {} not found", creditedAccount);

    debitedAccount.setBalance(debitedAccount.getBalance().subtract(amount));
    creditedAccount.setBalance(creditedAccount.getBalance().add(amount));

    DateTime now = now();
    OperationStatusRef status = operationStatusDao.findOne(OperationStatus.RESOLVED);
    OperationTypeRef type = operationTypeDao.findOne(OperationType.TRANSFER);

    Operation debitOperation = newOperation().withName("transfert -" + amount).withAccount(debitedAccount)
            .withAmount(amount.negate()).withDate(now).withStatus(status).withType(type).build();
    Operation creditOperation = newOperation().withName("transfert +" + amount).withAccount(creditedAccount)
            .withAmount(amount).withDate(now).withStatus(status).withType(type).build();

    operationDao.save(debitOperation);
    operationDao.save(creditOperation);
}

From source file:org.kuali.kpme.tklm.leave.transfer.service.BalanceTransferServiceImpl.java

@Override
public BalanceTransfer transfer(BalanceTransfer balanceTransfer) {
    if (ObjectUtils.isNull(balanceTransfer)) {
        LOG.error("did not supply a valid BalanceTransfer object.");
        return null;
        //         throw new RuntimeException("did not supply a valid BalanceTransfer object.");
    } else {/*from   w w w.j  a  va  2 s  .  co m*/
        BigDecimal transferAmount = balanceTransfer.getTransferAmount();
        LeaveBlockBo aLeaveBlock = null;

        if (ObjectUtils.isNotNull(balanceTransfer.getAmountTransferred())) {
            if (balanceTransfer.getAmountTransferred().compareTo(BigDecimal.ZERO) > 0) {

                //TODO switch to LeaveBlock.Builder
                aLeaveBlock = new LeaveBlockBo();
                //Create a leave block that adds the adjusted transfer amount to the "transfer to" accrual category.
                aLeaveBlock.setPrincipalId(balanceTransfer.getPrincipalId());
                aLeaveBlock.setLeaveDate(balanceTransfer.getEffectiveDate());
                aLeaveBlock.setEarnCode(balanceTransfer.getCreditedAccrualCategory().getEarnCode());
                aLeaveBlock.setAccrualCategory(balanceTransfer.getToAccrualCategory());
                aLeaveBlock.setDescription("Amount transferred");
                aLeaveBlock.setLeaveAmount(balanceTransfer.getAmountTransferred());
                aLeaveBlock.setAccrualGenerated(true);
                aLeaveBlock.setTransactionDocId(balanceTransfer.getDocumentHeaderId());
                aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
                aLeaveBlock.setDocumentId(balanceTransfer.getLeaveCalendarDocumentId());
                aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.REQUESTED);
                aLeaveBlock.setBlockId(0L);

                //Want to store the newly created leave block id on this maintainable object
                //when the status of the maintenance document encapsulating this maintainable changes
                //the id will be used to fetch and update the leave block statuses.
                LeaveBlock lb = LmServiceLocator.getLeaveBlockService().saveLeaveBlock(
                        LeaveBlockBo.to(aLeaveBlock), GlobalVariables.getUserSession().getPrincipalId());

                balanceTransfer.setAccruedLeaveBlockId(lb.getLmLeaveBlockId());
            }
        }

        if (ObjectUtils.isNotNull(transferAmount)) {
            if (transferAmount.compareTo(BigDecimal.ZERO) > 0) {
                //Create leave block that removes the correct transfer amount from the originating accrual category.
                aLeaveBlock = new LeaveBlockBo();
                aLeaveBlock.setPrincipalId(balanceTransfer.getPrincipalId());
                aLeaveBlock.setLeaveDate(balanceTransfer.getEffectiveDate());
                aLeaveBlock.setEarnCode(balanceTransfer.getDebitedAccrualCategory().getEarnCode());
                aLeaveBlock.setAccrualCategory(balanceTransfer.getFromAccrualCategory());
                aLeaveBlock.setDescription("Transferred amount");
                aLeaveBlock.setLeaveAmount(balanceTransfer.getTransferAmount().negate());
                aLeaveBlock.setAccrualGenerated(true);
                aLeaveBlock.setTransactionDocId(balanceTransfer.getDocumentHeaderId());
                aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
                aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.REQUESTED);
                aLeaveBlock.setDocumentId(balanceTransfer.getLeaveCalendarDocumentId());
                aLeaveBlock.setBlockId(0L);

                //Want to store the newly created leave block id on this maintainable object.
                //when the status of the maintenance document encapsulating this maintainable changes
                //the id will be used to fetch and update the leave block statuses.
                LeaveBlock lb = LmServiceLocator.getLeaveBlockService().saveLeaveBlock(
                        LeaveBlockBo.to(aLeaveBlock), GlobalVariables.getUserSession().getPrincipalId());

                balanceTransfer.setDebitedLeaveBlockId(lb.getLmLeaveBlockId());
            }
        }

        BigDecimal forfeitedAmount = balanceTransfer.getForfeitedAmount();
        if (ObjectUtils.isNotNull(forfeitedAmount)) {
            //Any amount forfeited must come out of the originating accrual category in order to bring balance back to max.
            if (forfeitedAmount.compareTo(BigDecimal.ZERO) > 0) {
                //for balance transfers with action = lose, transfer amount must be moved to forfeitedAmount
                aLeaveBlock = new LeaveBlockBo();
                aLeaveBlock.setPrincipalId(balanceTransfer.getPrincipalId());
                aLeaveBlock.setLeaveDate(balanceTransfer.getEffectiveDate());
                aLeaveBlock.setEarnCode(balanceTransfer.getDebitedAccrualCategory().getEarnCode());
                aLeaveBlock.setAccrualCategory(balanceTransfer.getFromAccrualCategory());
                aLeaveBlock.setDescription(LMConstants.TRANSFER_FORFEIT_LB_DESCRIPTION);
                aLeaveBlock.setLeaveAmount(forfeitedAmount.negate());
                aLeaveBlock.setAccrualGenerated(true);
                aLeaveBlock.setTransactionDocId(balanceTransfer.getDocumentHeaderId());
                aLeaveBlock.setLeaveBlockType(LMConstants.LEAVE_BLOCK_TYPE.BALANCE_TRANSFER);
                aLeaveBlock.setRequestStatus(HrConstants.REQUEST_STATUS.REQUESTED);
                aLeaveBlock.setDocumentId(balanceTransfer.getLeaveCalendarDocumentId());
                aLeaveBlock.setBlockId(0L);

                //Want to store the newly created leave block id on this maintainable object
                //when the status of the maintenance document encapsulating this maintainable changes
                //the id will be used to fetch and update the leave block statuses.

                LeaveBlock lb = LmServiceLocator.getLeaveBlockService().saveLeaveBlock(
                        LeaveBlockBo.to(aLeaveBlock), GlobalVariables.getUserSession().getPrincipalId());
                balanceTransfer.setForfeitedLeaveBlockId(lb.getLmLeaveBlockId());
            }
        }
        return balanceTransfer;
    }
}