BisectionSolver.java

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

  18. import org.apache.commons.math4.legacy.exception.TooManyEvaluationsException;
  19. import org.apache.commons.math4.core.jdkmath.JdkMath;

  20. /**
  21.  * Implements the <a href="http://mathworld.wolfram.com/Bisection.html">
  22.  * bisection algorithm</a> for finding zeros of univariate real functions.
  23.  * <p>
  24.  * The function should be continuous but not necessarily smooth.</p>
  25.  *
  26.  */
  27. public class BisectionSolver extends AbstractUnivariateSolver {
  28.     /** Default absolute accuracy. */
  29.     private static final double DEFAULT_ABSOLUTE_ACCURACY = 1e-6;

  30.     /**
  31.      * Construct a solver with default accuracy (1e-6).
  32.      */
  33.     public BisectionSolver() {
  34.         this(DEFAULT_ABSOLUTE_ACCURACY);
  35.     }
  36.     /**
  37.      * Construct a solver.
  38.      *
  39.      * @param absoluteAccuracy Absolute accuracy.
  40.      */
  41.     public BisectionSolver(double absoluteAccuracy) {
  42.         super(absoluteAccuracy);
  43.     }
  44.     /**
  45.      * Construct a solver.
  46.      *
  47.      * @param relativeAccuracy Relative accuracy.
  48.      * @param absoluteAccuracy Absolute accuracy.
  49.      */
  50.     public BisectionSolver(double relativeAccuracy,
  51.                            double absoluteAccuracy) {
  52.         super(relativeAccuracy, absoluteAccuracy);
  53.     }

  54.     /**
  55.      * {@inheritDoc}
  56.      */
  57.     @Override
  58.     protected double doSolve()
  59.         throws TooManyEvaluationsException {
  60.         double min = getMin();
  61.         double max = getMax();
  62.         verifyInterval(min, max);
  63.         final double absoluteAccuracy = getAbsoluteAccuracy();
  64.         double m;
  65.         double fm;
  66.         double fmin;

  67.         while (true) {
  68.             m = UnivariateSolverUtils.midpoint(min, max);
  69.             fmin = computeObjectiveValue(min);
  70.             fm = computeObjectiveValue(m);

  71.             if (fm * fmin > 0) {
  72.                 // max and m bracket the root.
  73.                 min = m;
  74.             } else {
  75.                 // min and m bracket the root.
  76.                 max = m;
  77.             }

  78.             if (JdkMath.abs(max - min) <= absoluteAccuracy) {
  79.                 m = UnivariateSolverUtils.midpoint(min, max);
  80.                 return m;
  81.             }
  82.         }
  83.     }
  84. }