List of usage examples for java.math BigDecimal negate
public BigDecimal negate()
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; } }