简体   繁体   中英

Solving polynomial equation in Java

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM