Example usage for org.apache.commons.math.analysis.solvers UnivariateRealSolverFactory newNewtonSolver

List of usage examples for org.apache.commons.math.analysis.solvers UnivariateRealSolverFactory newNewtonSolver

Introduction

In this page you can find the example usage for org.apache.commons.math.analysis.solvers UnivariateRealSolverFactory newNewtonSolver.

Prototype

public abstract UnivariateRealSolver newNewtonSolver();

Source Link

Document

Create a new UnivariateRealSolver .

Usage

From source file:geogebra.common.kernel.algos.AlgoRootInterval.java

@SuppressWarnings("deprecation")
final double calcRoot() {
    if (!(f.isDefined() && aGeo.isDefined() && bGeo.isDefined())) {
        return Double.NaN;
    }//  w  ww .  ja  va  2s .  c  o  m

    double root = Double.NaN;
    Function fun = f.getFunction();

    if (rootFinder == null) {
        UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
        rootFinder = fact.newBrentSolver();

        rootPolisher = fact.newNewtonSolver();
    }

    double min = a.getDouble();
    double max = b.getDouble();

    double newtonRoot = Double.NaN;

    try {
        // Brent's method (Apache 2.2)
        root = rootFinder.solve(new RealRootAdapter(fun), min, max);

        // Apache 3.3 - solver seems more accurate
        // #4691
        // BrentSolver brent3 = new BrentSolver();
        // root = brent3.solve(100, new RealRootAdapter3(fun), min, max);

    } catch (Exception e) {
        // e.printStackTrace();
        Log.debug("problem finding root: " + e.getMessage());

        try {
            // Let's try again by searching for a valid domain first
            double[] borders = RealRootUtil.getDefinedInterval(fun, min, max);
            root = rootFinder.solve(new RealRootAdapter(fun), borders[0], borders[1]);
        } catch (Exception ex) {
            // ex.printStackTrace();
            Log.debug("problem finding root: " + ex.getMessage());
            return Double.NaN;
        }
    }

    // Log.debug("result from Brent: " + root);

    // ******** Polish Root ***************
    // adpated from EquationSolver
    // #4691

    try {
        newtonRoot = rootPolisher.solve(new RealRootDerivAdapter(fun), min, max, root);

        if (Math.abs(fun.evaluate(newtonRoot)) < Math.abs(fun.evaluate(root))) {
            root = newtonRoot;
            // Log.debug("polished result from Newton is better: " +
            // newtonRoot);
        }

    } catch (Exception e) {
        Log.debug("problem polishing root: " + e.getMessage());
    }

    // check result
    if (Math.abs(fun.evaluate(root)) < Kernel.MIN_PRECISION) {
        return root;
    }

    Log.debug("problem with root accuracy");
    return Double.NaN;
}

From source file:geogebra.common.kernel.EquationSolver.java

/**
 * Calculates all roots of a polynomial given by eqn using Laguerres method.
 * Polishes roots found. The roots are stored in eqn again.
 * //from   ww  w . j av a2s  . com
 * @param eqn
 *            coefficients of polynomial
 */
@SuppressWarnings("deprecation")
private int laguerreAll(double[] eqn) {
    // for fast evaluation of polynomial (used for root polishing)
    PolyFunction polyFunc = new PolyFunction(eqn);
    PolyFunction derivFunc = polyFunc.getDerivative();

    /*
     * double estx = 0; try { estx = rootPolisher.newtonRaphson(polyFunc,
     * LAGUERRE_START); Application.debug("newton estx: " + estx); if
     * (Double.isNaN(estx)) { estx = LAGUERRE_START;
     * Application.debug("corrected estx: " + estx); } } catch (Exception e)
     * {}
     */

    // calc roots with Laguerre method

    /*
     * old code using Flanagan library //ComplexPoly poly = new
     * ComplexPoly(eqn); //Complex [] complexRoots = poly.roots(false, new
     * Complex(LAGUERRE_START, 0)); // don't polish here
     */

    Complex[] complexRoots = null;
    try {
        if (laguerreSolver == null) {
            laguerreSolver = new LaguerreSolver();
        }
        complexRoots = laguerreSolver.solveAll(eqn, LAGUERRE_START);
    } catch (Exception e) {
        System.err.println("EquationSolver.LaguerreSolver: " + e.getLocalizedMessage());
    }

    if (complexRoots == null)
        complexRoots = new Complex[0];

    // sort complexRoots by real part into laguerreRoots
    double[] laguerreRoots = new double[complexRoots.length];
    for (int i = 0; i < laguerreRoots.length; i++) {
        laguerreRoots[i] = complexRoots[i].getReal();
    }
    Arrays.sort(laguerreRoots);

    // get the roots from Laguerre method
    int realRoots = 0;
    double root;

    for (int i = 0; i < laguerreRoots.length; i++) {
        // System.out.println("laguerreRoots[" + i + "] = " +
        // laguerreRoots[i]);

        // let's polish all complex roots to get all real roots
        root = laguerreRoots[i];

        // check if root is bounded in intervall [root-eps, root+eps]
        double left = i == 0 ? root - 1 : (root + laguerreRoots[i - 1]) / 2;
        double right = i == laguerreRoots.length - 1 ? root + 1 : (root + laguerreRoots[i + 1]) / 2;
        double f_left = polyFunc.evaluate(left);
        double f_right = polyFunc.evaluate(right);
        boolean bounded = f_left * f_right < 0.0;

        try {
            if (bounded) {
                if (rootFinderBrent == null) {
                    UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
                    rootFinderBrent = fact.newBrentSolver();
                }

                // small f'(root): don't go too far from our laguerre root !
                double brentRoot = rootFinderBrent.solve(new RealRootAdapter(polyFunc), left, right, root);
                if (Math.abs(polyFunc.evaluate(brentRoot)) < Math.abs(polyFunc.evaluate(root))) {
                    root = brentRoot;
                }
                // System.out.println("Polish bisectNewtonRaphson: " +
                // root);
            } else {
                if (rootFinderNewton == null) {
                    UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
                    rootFinderNewton = fact.newNewtonSolver();
                }

                // the root is not bounded: give Mr. Newton a chance
                double newtonRoot = rootFinderNewton.solve(new RealRootDerivAdapter(polyFunc), left, right,
                        root);
                if (Math.abs(polyFunc.evaluate(newtonRoot)) < Math.abs(polyFunc.evaluate(root))) {
                    root = newtonRoot;
                }
                // System.out.println("Polish newtonRaphson: " + root);
            }
        } catch (Exception e) {
            // Application.debug("Polish FAILED: ");
            // polishing failed: maybe we have an extremum here
            // try to find a local extremum
            try {
                if (rootFinderBrent == null) {
                    UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
                    rootFinderBrent = fact.newBrentSolver();
                }

                double brentRoot = rootFinderBrent.solve(new RealRootAdapter(derivFunc), left, right);
                if (Math.abs(polyFunc.evaluate(brentRoot)) < Math.abs(polyFunc.evaluate(root))) {
                    root = brentRoot;
                }
                // System.out.println("    find extremum successfull: " +
                // root);
            } catch (Exception ex) {
                App.debug(ex.getMessage());
            }
        }

        // check if the found root is really ok
        double[] val = polyFunc.evaluateDerivFunc(root); // get f(root) and
        // f'(root)
        double error = Math.abs(val[0]); // | f(root) |
        double slope = Math.abs(val[1]);

        boolean success;
        if (slope < 1)
            success = error < LAGUERRE_EPS;
        else
            success = error < LAGUERRE_EPS * slope;

        if (success) {
            // Application.debug("FOUND ROOT: " + root);
            eqn[realRoots] = root;
            realRoots++;
        } else {
            // Application.debug("no root: " + root + ", error " + error);
        }
    }
    return realRoots;
}

From source file:geogebra.kernel.EquationSolver.java

/**
 * Calculates all roots of a polynomial given by eqn using Laguerres method.
 * Polishes roots found. The roots are stored in eqn again.
 * @param eqn: coefficients of polynomial    
 */// w w w. jav  a  2 s .  c o  m
private int laguerreAll(double[] eqn) {
    // for fast evaluation of polynomial (used for root polishing)
    PolyFunction polyFunc = new PolyFunction(eqn);
    PolyFunction derivFunc = polyFunc.getDerivative();

    /*
    double estx = 0;      
    try {
       estx = rootPolisher.newtonRaphson(polyFunc, LAGUERRE_START);   
       Application.debug("newton estx: " + estx);
       if (Double.isNaN(estx)) {
    estx = LAGUERRE_START;
    Application.debug("corrected estx: " + estx);
       }
    } catch (Exception e) {}
    */

    // calc roots with Laguerre method

    /* old code using Flanagan library
    //ComplexPoly poly = new ComplexPoly(eqn);   
    //Complex [] complexRoots = poly.roots(false, new Complex(LAGUERRE_START, 0)); // don't polish here 
    */

    Complex[] complexRoots = null;
    try {
        if (laguerreSolver == null) {
            laguerreSolver = new LaguerreSolver();
        }
        complexRoots = laguerreSolver.solveAll(eqn, LAGUERRE_START);
    } catch (Exception e) {
        System.err.println("EquationSolver.LaguerreSolver: " + e.getLocalizedMessage());
    }

    if (complexRoots == null)
        complexRoots = new Complex[0];

    // sort complexRoots by real part into laguerreRoots
    double[] laguerreRoots = new double[complexRoots.length];
    for (int i = 0; i < laguerreRoots.length; i++) {
        laguerreRoots[i] = complexRoots[i].getReal();
    }
    Arrays.sort(laguerreRoots);

    // get the roots from Laguerre method
    int realRoots = 0;
    double root;

    for (int i = 0; i < laguerreRoots.length; i++) {
        //System.out.println("laguerreRoots[" + i + "] = " + laguerreRoots[i]);   

        // let's polish all complex roots to get all real roots
        root = laguerreRoots[i];

        // check if root is bounded in intervall [root-eps, root+eps]
        double left = i == 0 ? root - 1 : (root + laguerreRoots[i - 1]) / 2;
        double right = i == laguerreRoots.length - 1 ? root + 1 : (root + laguerreRoots[i + 1]) / 2;
        double f_left = polyFunc.evaluate(left);
        double f_right = polyFunc.evaluate(right);
        boolean bounded = f_left * f_right < 0.0;

        try {
            if (bounded) {
                if (rootFinderBrent == null) {
                    UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
                    rootFinderBrent = fact.newBrentSolver();
                }

                //   small f'(root): don't go too far from our laguerre root !   
                double brentRoot = rootFinderBrent.solve(new RealRootAdapter(polyFunc), left, right, root);
                if (Math.abs(polyFunc.evaluate(brentRoot)) < Math.abs(polyFunc.evaluate(root))) {
                    root = brentRoot;
                }
                //System.out.println("Polish bisectNewtonRaphson: " + root);
            } else {
                if (rootFinderNewton == null) {
                    UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
                    rootFinderNewton = fact.newNewtonSolver();
                }

                // the root is not bounded: give Mr. Newton a chance
                double newtonRoot = rootFinderNewton.solve(new RealRootDerivAdapter(polyFunc), left, right,
                        root);
                if (Math.abs(polyFunc.evaluate(newtonRoot)) < Math.abs(polyFunc.evaluate(root))) {
                    root = newtonRoot;
                }
                //System.out.println("Polish newtonRaphson: " + root);
            }
        } catch (Exception e) {
            // Application.debug("Polish FAILED: ");
            // polishing failed: maybe we have an extremum here
            // try to find a local extremum
            try {
                if (rootFinderBrent == null) {
                    UnivariateRealSolverFactory fact = UnivariateRealSolverFactory.newInstance();
                    rootFinderBrent = fact.newBrentSolver();
                }

                double brentRoot = rootFinderBrent.solve(new RealRootAdapter(derivFunc), left, right);
                if (Math.abs(polyFunc.evaluate(brentRoot)) < Math.abs(polyFunc.evaluate(root))) {
                    root = brentRoot;
                }
                //System.out.println("    find extremum successfull: " + root);
            } catch (Exception ex) {
                Application.debug(ex.getMessage());
            }
        }

        //   check if the found root is really ok                                     
        double[] val = polyFunc.evaluateDerivFunc(root); // get f(root) and f'(root)
        double error = Math.abs(val[0]); // | f(root) |
        double slope = Math.abs(val[1]);

        boolean success;
        if (slope < 1)
            success = error < LAGUERRE_EPS;
        else
            success = error < LAGUERRE_EPS * slope;

        if (success) {
            // Application.debug("FOUND ROOT: " + root);
            eqn[realRoots] = root;
            realRoots++;
        } else {
            //Application.debug("no root: " + root + ", error " + error);
        }
    }
    return realRoots;
}