I have the following code which gives the price given a certain rate :
public static void main(String[] args) {
double term = 5;
double coupon = 5;
double rate = 0.0432;
//should get the price == 103;
double price;
double sum = 0;
for (int i = 1; i <= term; i++) {
sum = sum + (coupon / Math.pow((1 + rate), i));
}
double lastAmount = (100 / Math.pow((1 + rate), (term)));
price = sum + lastAmount;
System.out.println("price is:" + price);
}
My question is, how can I do this other way around? where the price is given and the rate is unknown. So I figured out, it's going to be an exponential equation. where it should look like below:
103x^5 - 5x^4 - 5x^3 - 5x^2 - 5x - 105=0
where x = 1+rate
solving the exponential equation, you get x = 1.0432 which means the rate is 0.0432 as expected.
How can I implement this in java to solve the equation.
You would need to determine if your equation can be solved using radicals , and if so, you could try implementing that algorithm. Otherwise, you could try taking the TI-82 graphing calculator approach of "visualizing" the equation in code (iterating at a "sufficiently" small grain), watching for an inflection from positive to negative (or vice versa), or a point where the equation hits zero exactly, and approximating down to find a close enough value. However, in reading up on Quintic Functions, it seems there may not be a great formulaic solution to this problem (at least not one that my math capabilities can fathom).
The computation of the interest rate from the price is known to be a problem without a closed-form solution (for N>4
).
Using the summation formula for geometric progressions, the equation spells
((1+r)^N - 1) / r = R
which amounts to finding the roots of a polynomial of degree N
. You could use a polynomial solver, but here Netwon's method is more appropriate.
The function to be cancelled is
(1+r)^N - 1 - R r
and its derivative on r
,
N(1+r)^(N-1) - R.
The rate that would correspond to simple interest, R/N
, can be a good starting value.
Here is code that does it using the implementation of Brent's Method for root finding (from Apache Commons). It will print any roots between -10000 and +10000. It may not work for functions having multiple roots less than intervalSize
(0.01) apart (yours is not such a function).
package sandbox;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.solvers.BrentSolver;
public class BrentsMethodRootFinderExample {
private void solveit () {
BrentSolver solver = new BrentSolver();
UnivariateFunction f = new UnivariateFunction() {
@Override
public double value(double x) {
return 103*Math.pow(x, 5.0)-5*Math.pow(x, 4.0)-5*Math.pow(x, 3.0)-5*Math.pow(x, 2.0)-5*x - 105;
}
};
double intervalStart = -10000;
double intervalSize = 0.01;
while (intervalStart < 10000) {
intervalStart+= intervalSize;
if(Math.signum(f.value(intervalStart)) != Math.signum(f.value(intervalStart+intervalSize))) {
System.out.println("x = " + solver.solve(1000, f, intervalStart, intervalStart+intervalSize));
}
}
}
public static void main(String[] args) {
new BrentsMethodRootFinderExample().solveit();
}
}
Output:
x = 1.0432004413216969
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.