alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Commons Math example source code file (BrentSolverTest.java)

This example Commons Math source code file (BrentSolverTest.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Commons Math tags/keywords

brentsolver, brentsolver, exception, expecting, illegalargumentexception, illegalargumentexception, mathexception, monitoredfunction, secantsolver, sinfunction, univariaterealfunction, univariaterealfunction, univariaterealsolver, univariaterealsolver

The Commons Math BrentSolverTest.java source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.math.analysis.solvers;

import junit.framework.TestCase;

import org.apache.commons.math.MathException;
import org.apache.commons.math.analysis.MonitoredFunction;
import org.apache.commons.math.analysis.QuinticFunction;
import org.apache.commons.math.analysis.SinFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;

/**
 * Testcase for UnivariateRealSolver.
 * Because Brent-Dekker is guaranteed to converge in less than the default
 * maximum iteration count due to bisection fallback, it is quite hard to
 * debug. I include measured iteration counts plus one in order to detect
 * regressions. On average Brent-Dekker should use 4..5 iterations for the
 * default absolute accuracy of 10E-8 for sinus and the quintic function around
 * zero, and 5..10 iterations for the other zeros.
 *
 * @version $Revision:670469 $ $Date:2008-06-23 10:01:38 +0200 (lun., 23 juin 2008) $
 */
public final class BrentSolverTest extends TestCase {

    public BrentSolverTest(String name) {
        super(name);
    }

    @Deprecated
    public void testDeprecated() throws MathException {
        // The sinus function is behaved well around the root at #pi. The second
        // order derivative is zero, which means linar approximating methods will
        // still converge quadratically.
        UnivariateRealFunction f = new SinFunction();
        double result;
        UnivariateRealSolver solver = new BrentSolver(f);
        // Somewhat benign interval. The function is monotone.
        result = solver.solve(3, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 4 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 5);
        // Larger and somewhat less benign interval. The function is grows first.
        result = solver.solve(1, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 5 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 6);
        solver = new SecantSolver(f);
        result = solver.solve(3, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 4 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 5);
        result = solver.solve(1, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 5 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 6);
        assertEquals(result, solver.getResult(), 0);
    }

    public void testSinZero() throws MathException {
        // The sinus function is behaved well around the root at #pi. The second
        // order derivative is zero, which means linar approximating methods will
        // still converge quadratically.
        UnivariateRealFunction f = new SinFunction();
        double result;
        UnivariateRealSolver solver = new BrentSolver();
        // Somewhat benign interval. The function is monotone.
        result = solver.solve(f, 3, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 4 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 5);
        // Larger and somewhat less benign interval. The function is grows first.
        result = solver.solve(f, 1, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 5 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 6);
        solver = new SecantSolver();
        result = solver.solve(f, 3, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 4 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 5);
        result = solver.solve(f, 1, 4);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
        // 5 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 6);
        assertEquals(result, solver.getResult(), 0);
    }

   public void testQuinticZero() throws MathException {
        // The quintic function has zeros at 0, +-0.5 and +-1.
        // Around the root of 0 the function is well behaved, with a second derivative
        // of zero a 0.
        // The other roots are less well to find, in particular the root at 1, because
        // the function grows fast for x>1.
        // The function has extrema (first derivative is zero) at 0.27195613 and 0.82221643,
        // intervals containing these values are harder for the solvers.
        UnivariateRealFunction f = new QuinticFunction();
        double result;
        // Brent-Dekker solver.
        UnivariateRealSolver solver = new BrentSolver();
        // Symmetric bracket around 0. Test whether solvers can handle hitting
        // the root in the first iteration.
        result = solver.solve(f, -0.2, 0.2);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        assertTrue(solver.getIterationCount() <= 2);
        // 1 iterations on i586 JDK 1.4.1.
        // Asymmetric bracket around 0, just for fun. Contains extremum.
        result = solver.solve(f, -0.1, 0.3);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        // 5 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 6);
        // Large bracket around 0. Contains two extrema.
        result = solver.solve(f, -0.3, 0.45);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        // 6 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 7);
        // Benign bracket around 0.5, function is monotonous.
        result = solver.solve(f, 0.3, 0.7);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
        // 6 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 7);
        // Less benign bracket around 0.5, contains one extremum.
        result = solver.solve(f, 0.2, 0.6);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
        // 6 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 7);
        // Large, less benign bracket around 0.5, contains both extrema.
        result = solver.solve(f, 0.05, 0.95);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
        // 8 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 9);
        // Relatively benign bracket around 1, function is monotonous. Fast growth for x>1
        // is still a problem.
        result = solver.solve(f, 0.85, 1.25);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 8 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 9);
        // Less benign bracket around 1 with extremum.
        result = solver.solve(f, 0.8, 1.2);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 8 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 9);
        // Large bracket around 1. Monotonous.
        result = solver.solve(f, 0.85, 1.75);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 10 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 11);
        // Large bracket around 1. Interval contains extremum.
        result = solver.solve(f, 0.55, 1.45);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 7 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 8);
        // Very large bracket around 1 for testing fast growth behaviour.
        result = solver.solve(f, 0.85, 5);
        //System.out.println(
       //     "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 12 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 13);
        // Secant solver.
        solver = new SecantSolver();
        result = solver.solve(f, -0.2, 0.2);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        // 1 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 2);
        result = solver.solve(f, -0.1, 0.3);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        // 5 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 6);
        result = solver.solve(f, -0.3, 0.45);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        // 6 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 7);
        result = solver.solve(f, 0.3, 0.7);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
        // 7 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 8);
        result = solver.solve(f, 0.2, 0.6);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
        // 6 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 7);
        result = solver.solve(f, 0.05, 0.95);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
        // 8 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 9);
        result = solver.solve(f, 0.85, 1.25);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 10 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 11);
        result = solver.solve(f, 0.8, 1.2);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 8 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 9);
        result = solver.solve(f, 0.85, 1.75);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 14 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 15);
        // The followig is especially slow because the solver first has to reduce
        // the bracket to exclude the extremum. After that, convergence is rapide.
        result = solver.solve(f, 0.55, 1.45);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 7 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 8);
        result = solver.solve(f, 0.85, 5);
        //System.out.println(
        //    "Root: " + result + " Iterations: " + solver.getIterationCount());
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        // 14 iterations on i586 JDK 1.4.1.
        assertTrue(solver.getIterationCount() <= 15);
        // Static solve method
        result = UnivariateRealSolverUtils.solve(f, -0.2, 0.2);
        assertEquals(result, 0, solver.getAbsoluteAccuracy());
        result = UnivariateRealSolverUtils.solve(f, -0.1, 0.3);
        assertEquals(result, 0, 1E-8);
        result = UnivariateRealSolverUtils.solve(f, -0.3, 0.45);
        assertEquals(result, 0, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.3, 0.7);
        assertEquals(result, 0.5, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.2, 0.6);
        assertEquals(result, 0.5, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.05, 0.95);
        assertEquals(result, 0.5, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.85, 1.25);
        assertEquals(result, 1.0, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.8, 1.2);
        assertEquals(result, 1.0, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.85, 1.75);
        assertEquals(result, 1.0, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.55, 1.45);
        assertEquals(result, 1.0, 1E-6);
        result = UnivariateRealSolverUtils.solve(f, 0.85, 5);
        assertEquals(result, 1.0, 1E-6);
    }

    public void testRootEndpoints() throws Exception {
        UnivariateRealFunction f = new SinFunction();
        UnivariateRealSolver solver = new BrentSolver();

        // endpoint is root
        double result = solver.solve(f, Math.PI, 4);
        assertEquals(Math.PI, result, solver.getAbsoluteAccuracy());

        result = solver.solve(f, 3, Math.PI);
        assertEquals(Math.PI, result, solver.getAbsoluteAccuracy());

        result = solver.solve(f, Math.PI, 4, 3.5);
        assertEquals(Math.PI, result, solver.getAbsoluteAccuracy());

        result = solver.solve(f, 3, Math.PI, 3.07);
        assertEquals(Math.PI, result, solver.getAbsoluteAccuracy());

    }

    public void testBadEndpoints() throws Exception {
        UnivariateRealFunction f = new SinFunction();
        UnivariateRealSolver solver = new BrentSolver();
        try {  // bad interval
            solver.solve(f, 1, -1);
            fail("Expecting IllegalArgumentException - bad interval");
        } catch (IllegalArgumentException ex) {
            // expected
        }
        try {  // no bracket
            solver.solve(f, 1, 1.5);
            fail("Expecting IllegalArgumentException - non-bracketing");
        } catch (IllegalArgumentException ex) {
            // expected
        }
        try {  // no bracket
            solver.solve(f, 1, 1.5, 1.2);
            fail("Expecting IllegalArgumentException - non-bracketing");
        } catch (IllegalArgumentException ex) {
            // expected
        }
    }

    public void testInitialGuess() throws MathException {

        MonitoredFunction f = new MonitoredFunction(new QuinticFunction());
        UnivariateRealSolver solver = new BrentSolver();
        double result;

        // no guess
        result = solver.solve(f, 0.6, 7.0);
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        int referenceCallsCount = f.getCallsCount();
        assertTrue(referenceCallsCount >= 13);

        // invalid guess (it *is* a root, but outside of the range)
        try {
          result = solver.solve(f, 0.6, 7.0, 0.0);
          fail("an IllegalArgumentException was expected");
        } catch (IllegalArgumentException iae) {
            // expected behaviour
        } catch (Exception e) {
            fail("wrong exception caught: " + e.getMessage());
        }

        // bad guess
        f.setCallsCount(0);
        result = solver.solve(f, 0.6, 7.0, 0.61);
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        assertTrue(f.getCallsCount() > referenceCallsCount);

        // good guess
        f.setCallsCount(0);
        result = solver.solve(f, 0.6, 7.0, 0.999999);
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        assertTrue(f.getCallsCount() < referenceCallsCount);

        // perfect guess
        f.setCallsCount(0);
        result = solver.solve(f, 0.6, 7.0, 1.0);
        assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
        assertEquals(0, solver.getIterationCount());
        assertEquals(1, f.getCallsCount());

    }

}

Other Commons Math examples (source code examples)

Here is a short list of links related to this Commons Math BrentSolverTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.