import java.math.BigDecimal;/* * InterestSolver.java * * Created on 14 December 2006, 16:55 * * To change this template, choose Tools | Template Manager * and open the template in the editor. *//** * * @author oem student */public class InterestSolver extends InterestSolverDefn{ private double rate, repayment, premium; private int months; /** Creates a new instance of InterestSolver */ public InterestSolver() { } public void setRate(double givenRate){ if (givenRate >= 100 || givenRate <= 0) throw new IllegalArgumentException("Invalid Rate given - Rates must be between 0 and 100"); this.rate = givenRate; } public void setRepayment(double givenRepayment) { if (givenRepayment <= 0) throw new IllegalArgumentException("Invalid Replayment given - repayments must be positive"); this.repayment = givenRepayment; } public void setMonths(int givenMonths) { if (givenMonths<= 0) throw new IllegalArgumentException("Invalid months given - amount of months must be positive and greater than 0"); this.months = givenMonths; } public void setPremium(double givenPremium) { if (givenPremium <= 0) throw new IllegalArgumentException("Invalid Premium given - The premium must be valid and greater than 0"); this.premium = givenPremium; } public double getRate() { return rate; //return round2dp(rate,1); } public double getRepayment() { return repayment; } public int getMonths() { return months; } public double getPremium() { return premium; } private double getJ(){ return (1 + rate/1200); } public void computeRepayment() { double j = getJ(); double r = (premium * Math.pow(j,months) * (1-j)) / (1-Math.pow(j,months)); repayment = round2dp(r,2); } public void computePremium() { double r = repayment; int m = months; double j = getJ(); double p = (r*(1-Math.pow(j,m))) / (Math.pow(j,m) * (1 - j)); p = p; premium = round2dp(p,2); } private double round2dp(double mdp, int dp) { mdp = Math.round (mdp*Math.pow(10,dp)); return mdp/Math.pow(10,dp); } public void computeMonths() { double r,j, p, m; r = repayment; j = getJ(); p = premium; m = (Math.log(r) - Math.log(p*(1-j) + r)) / Math.log(j); months = (int) Math.ceil(m); } public void computeRate() { if ((premium * rate * (1/12))/12 > repayment ) throw new RuntimeException("Can never be payed off"); double a = (months*(repayment+premium)) / (premium*(months+1)); double b = (13.0/12.0); rate = (bisection(a,b,0.001) - 1) *1200; } protected double bisection(double a, double b, double eps) { if ( (f(a)* f(b)) >= 0) throw new RuntimeException("a and b don't have a sign change."); /* double c; do { c = (a+b)/2.0; if ( f(c)*f(a) <0) b = c; else a = c; } while (eps > Math.abs((a-b)/(((a+b)/2.0)-2.0))); return c; */ eps = eps/1200; if (eps < Math.abs((a-b)/(((a+b)/2.0)-2.0))) { double fa = f(a); double fb = f(b); while ((eps < Math.abs((a-b)/(((a+b)/2.0)-2.0)))) { double fc = f((a+b)/2); if ((fa * fc) < 0 ) { b = (a+b)/2.0; fb = fc; } else { a = (a+b)/2.0; fa = fc; } } return (a+b)/2.0; } return 0.0; } protected double f(double J) { double r, p, m; r = repayment; p = premium; m = months; return p*Math.pow(J,m+1) - (r + p)*Math.pow(J,m) + r; }}