0

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.

Shafin Mahmud
  • 3,831
  • 1
  • 23
  • 35
rezan21
  • 1,065
  • 10
  • 14
  • 2
    Your equation `103x^5 - 5x^4 - 5x^3 - 5x^2 - 5x - 105=0` is a polynomial equation, not an exponential equation. – rgettman Nov 27 '17 at 18:50
  • It's been proven that a degree five polynomial has no general closed-form solution. You're going to have to choose a numeric method. There's plenty of information about this out there - you just may have to search a little. – Dawood ibn Kareem Nov 27 '17 at 18:52
  • Apache Commons has an implementation of Brent's Method for root finding. See: http://commons.apache.org/proper/commons-math/javadocs/api-3.3/org/apache/commons/math3/analysis/solvers/BrentSolver.html – Matthew McPeak Nov 27 '17 at 18:58

4 Answers4

0

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).

CodeMonkey1313
  • 15,717
  • 17
  • 76
  • 109
  • The qunitinc equation can indeed not be solved by radicals, and there are specific numerical methods much more efficient than graphing and zooming. –  Nov 27 '17 at 19:02
0

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.

0

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

Matthew McPeak
  • 17,705
  • 2
  • 27
  • 59
0

Another option for finding polynomial real roots may be using a library just programed by me.

The output using the command line version is the following:

$ java -jar ./polynomial-roots-v1.0-SNAPSHOT-all.jar -precision 15 -polynomial_coefs "-105 -5 -5 -5 -5 103"
{ 103 * x ^ 5 - 5 * x ^ 4 - 5 * x ^ 3 - 5 * x ^ 2 - 5 * x - 105 = 0 }

Solution[1]: x = 1.04320048314876

The library can be easily included in a Java application (it is offered under lgpl license)

You can download it at:

real polynomial root calculation library download