This is the first half of this pr. Commit of analysis solvers.

PR: http://nagoya.apache.org/bugzilla/show_bug.cgi?id=20844
Submitted by:	J. Pietschman


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@140943 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark R. Diggory 2003-06-24 03:01:40 +00:00
parent 4f17b718b3
commit 50520ebc12
6 changed files with 1035 additions and 0 deletions

View File

@ -0,0 +1,197 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
/**
* Provide the Brent algorithm for solving for zeros of real univariate
* functions.
* It will only search for one zero in the given interval.
* The function is supposed to be continuous but not necessarily smooth.
*
* @author pietsch at apache.org
*/
public class BrentSolver extends UnivariateRealSolverImpl {
private UnivariateRealFunction f;
public BrentSolver(UnivariateRealFunction f) {
super(100, 1E-6);
this.f = f;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
*/
public double solve(double min, double max) throws MathException {
clearResult();
// Index 0 is the old approximation for the root.
// Index 1 is the last calculated approximation for the root.
// Index 2 is a bracket for the root with respect to x1.
double x0 = min;
double x1 = max;
double y0 = f.value(x0);
double y1 = f.value(x1);
if ((y0 > 0) == (y1 > 0)) {
throw new MathException("Interval doesn't bracket a zero.");
}
double x2 = x0;
double y2 = y0;
double delta = x1 - x0;
double oldDelta = delta;
int i = 0;
while (i < maximalIterationCount) {
if (Math.abs(y2) < Math.abs(y1)) {
x0 = x1;
x1 = x2;
x2 = x0;
y0 = y1;
y1 = y2;
y2 = y0;
}
if (Math.abs(y1) <= functionValueAccuracy) {
// Avoid division by very small values. Assume
// the iteration has converged (the problem may
// still be ill conditioned)
setResult(x1, i);
return result;
}
double dx = (x2 - x1);
double tolerance =
Math.max(relativeAccuracy * Math.abs(x1), absoluteAccuracy);
if (Math.abs(dx) <= tolerance) {
setResult(x1, i);
return result;
}
// System.out.println(
// " x0="
// + x0
// + " y0="
// + y0
// + " x1="
// + x1
// + " y1="
// + y1
// + " x2="
// + x2+" y2="+y2);
// System.out.println(" dx="+dx+" delta: "+delta+" olddelta: "+oldDelta);
if (Math.abs(oldDelta) < tolerance
|| Math.abs(y0) <= Math.abs(y1)) {
// System.out.println("bisection");
// Force bisection.
delta = 0.5 * dx;
oldDelta = delta;
} else {
double r3 = y1 / y0;
double p;
double p1;
if (x0 == x2) {
// Linear interpolation.
// System.out.println("linear");
p = dx * r3;
p1 = 1.0 - r3;
} else {
// Inverse quadratic interpolation.
// System.out.println("invers quad");
double r1 = y0 / y2;
double r2 = y1 / y2;
p = r3 * (dx * r1 * (r1 - r2) - (x1 - x0) * (r2 - 1.0));
p1 = (r1 - 1.0) * (r2 - 1.0) * (r3 - 1.0);
}
if (p > 0.0) {
p1 = -p1;
} else {
p = -p;
}
// System.out.println(" p="+p+" p1="+p1+" qq: "+(1.5 * dx * p1 - Math.abs(tolerance * p1)));
// System.out.println(" p="+p+" q: "+p1+" ad="+Math.abs(0.5 * oldDelta * p1));
if (2.0 * p >= 1.5 * dx * p1 - Math.abs(tolerance * p1)
|| p >= Math.abs(0.5 * oldDelta * p1)) {
// Inverse quadratic interpolation gives a value
// in the wrong direction, or progress is slow.
// Fall back to bisection.
// System.out.println("bisection fallback");
delta = 0.5 * dx;
oldDelta = delta;
} else {
oldDelta = delta;
delta = p / p1;
}
}
// Save old X1, Y1
x0 = x1;
y0 = y1;
// Compute new X1, Y1
if (Math.abs(delta) > tolerance) {
x1 = x1 + delta;
} else if (dx > 0.0) {
x1 = x1 + 0.5*tolerance;
} else if (dx <= 0.0) {
x1 = x1 - 0.5*tolerance;
}
y1 = f.value(x1);
if ((y1 > 0) == (y2 > 0)) {
x2 = x0;
y2 = y0;
delta = x1 - x0;
oldDelta = delta;
}
i++;
}
throw new MathException("Maximal iteration number exceeded.");
}
}

View File

@ -0,0 +1,145 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
/**
* Provide the secant algorithm for solving for zeros of real univariate
* functions. Because of forced bracketing, convergence is slower than
* the unrestricted secant algorithm. However, slow convergence of the
* Regula Falsi can be avoided.
* It will only search for one zero in the given interval.
* The function is supposed to be continuous but not necessarily smooth.
*
* @author pietsch at apache.org
*/
public class SecantSolver extends UnivariateRealSolverImpl {
private UnivariateRealFunction f;
public SecantSolver(UnivariateRealFunction f) {
super(100, 1E-6);
this.f = f;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
*/
public double solve(double min, double max) throws MathException {
clearResult();
// Index 0 is the old approximation for the root.
// Index 1 is the last calculated approximation for the root.
// Index 2 is a bracket for the root with respect to x0.
// OldDelta is the length of the bracketing interval of the last
// iteration.
double x0 = min;
double x1 = max;
double y0 = f.value(x0);
double y1 = f.value(x1);
if ((y0>0)== (y1>0)) {
throw new MathException("Interval doesn't bracket a zero.");
}
double x2 = x0;
double y2 = y0;
double oldDelta = x2 - x1;
int i = 0;
while (i < maximalIterationCount) {
if (Math.abs(y2) < Math.abs(y1)) {
x0 = x1;
x1 = x2;
x2 = x0;
y0 = y1;
y1 = y2;
y2 = y0;
}
if (Math.abs(y1) <= functionValueAccuracy) {
setResult(x1, i);
return result;
}
if (Math.abs(oldDelta)
< Math.max(relativeAccuracy * Math.abs(x1), absoluteAccuracy)) {
setResult(x1, i);
return result;
}
double delta;
if (Math.abs(y1) > Math.abs(y0)) {
// Function value increased in last iteration. Force bisection.
delta = 0.5 * oldDelta;
// System.out.println("Forced Bisection");
} else {
delta = (x0 - x1) / (1 - y0 / y1);
// System.out.println("delta=" + delta + " olddelta=" + oldDelta);
if (delta / oldDelta > 1) {
// New approximation falls outside bracket. Fall back to bisection.
delta = 0.5 * oldDelta;
// System.out.println("Fallback Bisection");
}
}
x0 = x1;
y0 = y1;
x1 = x1 + delta;
y1 = f.value(x1);
if ((y1>0) == (y2>0)) {
// New bracket is (x0,x1).
x2 = x0;
y2 = y0;
}
oldDelta = x2 - x1;
i++;
}
throw new MathException("Maximal iteration number exceeded");
}
}

View File

@ -0,0 +1,110 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
/**
* Provide an interface univariate real functions.
* The object may held temporary data which is shared between calculations
* of the value and the derivatives for the same argument. It is not guaranteed
* that derivatives are evaluated after the value, the evaluation algorithm
* should throw an InvalidStateException if it can't cope with this.
*
* @author pietsch at apache.org
*/
public interface UnivariateRealFunction {
/**
* Compute the value for the function.
* @param x the point for which the function value should be computed
* @return the value
* @throws MathException if the function couldn't be computed due to
* missing additional data or other environmental problems.
* @throws RuntimeException if the operation isn't supported, the argument
* was outside the supported domain or any other problem.
*
*/
public double value(double x) throws MathException;
/**
* Compute the value for the first derivative of the function.
* It is recommended to provide this method only if the first derivative is
* analytical. Numerical derivatives may be acceptable in some cases.
* An implementation should throw an UnsupportedOperationException if
* this method is not implemented.
* @param x the point for which the first derivative should be computed
* @return the value
* @throws MathException if the derivative couldn't be computed.
* @throws RuntimeException if the operation isn't supported, the argument
* was outside the supported domain or any other problem.
*
*/
public double firstDerivative(double x) throws MathException;
/**
* Compute the value for the second derivative of the function.
* It is recommended to provide this method only if the second derivative is
* analytical. Numerical derivatives may be acceptable in some cases.
* An implementation should throw an UnsupportedOperationException if
* this method is not implemented.
* @param x the point for which the first derivative should be computed
* @return the value
* @throws MathException if the second derivative couldn't be computed.
* @throws RuntimeException if the operation isn't supported, the argument
* was outside the supported domain or any other problem.
*
*/
public double secondDerivative(double x) throws MathException;
}

View File

@ -0,0 +1,209 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
/**
* Provide an interface to algorithms for solving for zeros of real univariate
* functions.
* An implementation will only search for one zero in the given interval.
*
* @author pietsch at apache.org
*/
public interface UnivariateRealSolver {
/**
* Set the upper limit for the number of iterations.
* Usually a high iteration count indicates convergence problems. However,
* the "reasonable value" varies widely for different solvers, users are
* advised to use the default value supplied by the solver.
* An exception will be thrown if the number is exceeded.
*
* @param count
*/
public void setMaximalIterationCount(int count);
/**
* Get the upper limit for the number of iterations.
* @return the actual upper limit
*/
public int getMaximalIterationCount();
/**
* Reset the upper limit for the number of iterations to the default.
* The default value is supplied by the solver implementation.
*
* @see #setMaximalIterationCount(int)
*/
public void resetMaximalIterationCount();
/**
* Set the absolute accuracy.
* The default is usually choosen so taht roots in the interval
* -10..-0.1 and +0.1..+10 can be found wit a reasonable accuracy. If the expected
* absolute value of your roots is of much smaller magnitude, set this to a smaller
* value.
* Solvers are advised to do a plausibility check with the relative accuracy, but
* clients should not rely on this.
* @param accuracy the accuracy.
* @throws MathException if the accuracy can't be achieved by the solver or is
* otherwise deemed unreasonable.
*/
public void setAbsoluteAccuracy(double accuracy) throws MathException;
/**
* Get the actual absolute accuracy.
* @return the accuracy
*/
public double getAbsoluteAccuracy();
/**
* Reset the absolute accuracy to the default.
* The default value is provided by the solver implementation.
*/
public void resetAbsoluteAccuracy();
/**
* Set the relative accuracy.
* This is used to stop iterations if the absolute accuracy can't be achieved
* due to large values or short mantissa length.
* If this should be the primary criterium for convergence rather then a safety
* measure, set the absolute accuracy to a ridiculously small value, like 1E-1000.
* @param accuracy the relative accuracy.
* @throws MathException if the accuracy can't be achieved by the solver or is
* otherwise deemed unreasonable.
*/
public void setRelativeAccuracy(double Accuracy) throws MathException;
/**
* Get the actual relative accuracy.
* @return the accuracy
*/
public double getRelativeAccuracy();
/**
* Reset the relative accuracy to the default.
* The default value is provided by the solver implementation.
*/
public void resetRelativeAccuracy();
/**
* Set the function value accuracy.
* This is used to determine whan an evaluated function value or some other
* value which is used as divisor is zero.
* This is a safety guard and it shouldn't be necesary to change this in general.
* @param accuracy the accuracy.
* @throws MathException if the accuracy can't be achieved by the solver or is
* otherwise deemed unreasonable.
*/
public void setFunctionValueAccuracy(double Accuracy) throws MathException;
/**
* Get the actual function value accuracy.
* @return the accuracy
*/
public double getFunctionValueAccuracy();
/**
* Reset the actual function accuracy to the default.
* The default value is provided by the solver implementation.
*/
public void resetFunctionValueAccuracy();
/**
* Solve for a zero root in the given interval.
* A solver may require that the interval brackets a single zero root.
* @param min the lower bound for the interval.
* @param max the upper bound for the interval.
* @return the value where the function is zero
* @throws MathException if the iteration count was exceeded or the
* solver detects convergence problems otherwise.
*/
public double solve(double min, double max) throws MathException;
/**
* Solve for a zero in the given interval, start at startValue.
* A solver may require that the interval brackets a single zero root.
* @param min the lower bound for the interval.
* @param max the upper bound for the interval.
* @param startValue the start value to use
* @return the value where the function is zero
* @throws MathException if the iteration count was exceeded or the
* solver detects convergence problems otherwise.
*/
public double solve(double min, double max, double startValue)
throws MathException;
/**
* Get the result of the last run of the solver.
* @return the last result.
* @throws MathException if there is no result available, either
* because no result was yet computed or the last attempt failed.
*/
public double getResult() throws MathException;
/**
* Get the number of iterations in the last run of the solver.
* This is mainly meant for testing purposes. It may occasionally
* help track down performance problems: if the iteration count
* is notoriously high, check whether the function is evaluated
* properly, and whether another solver is more amenable to the
* problem.
* @return the last iteration count.
* @throws MathException if there is no result available, either
* because no result was yet computed or the last attempt failed.
*/
public int getIterationCount() throws MathException;
}

View File

@ -0,0 +1,136 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.analysis;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.math.MathConfigurationException;
import org.apache.commons.math.MathException;
/**
* @author pietsch at apache.org
*
* A factory to easily get a default solver and some convenience
* functions.
* Because solvers are easily reusable, the factory does not
* store configuration data and creates preconfigured solvers
* (this may be controversial, because the configuration data
* may also be used for the default solver used by the static
* solve() method).
*
*/
public class UnivariateRealSolverFactory {
protected UnivariateRealSolverFactory() {
}
public static UnivariateRealSolver newSolver(UnivariateRealFunction f)
throws MathConfigurationException {
String solverClassName =
System.getProperty(
"org.apache.commons.math.analysis.UnivariateRealSolver",
"org.apache.commons.math.analysis.BrentSolver");
try {
Class clazz = Class.forName(solverClassName);
Class paramClass[] = new Class[1];
paramClass[0] =
Class.forName("org.apache.commons.math.analysis.UnivariateRealFunction");
Object param[] = new Object[1];
param[0] = f;
return (UnivariateRealSolver)clazz.getConstructor(
paramClass).newInstance(
param);
} catch (IllegalArgumentException e) {
throw new MathConfigurationException(e);
} catch (SecurityException e) {
throw new MathConfigurationException(
"Can't access " + solverClassName,
e);
} catch (ClassNotFoundException e) {
throw new MathConfigurationException(
"Class not found: " + solverClassName,
e);
} catch (InstantiationException e) {
throw new MathConfigurationException(
"Can't instantiate " + solverClassName,
e);
} catch (IllegalAccessException e) {
throw new MathConfigurationException(
"Can't access " + solverClassName,
e);
} catch (InvocationTargetException e) {
throw new MathConfigurationException(e);
} catch (NoSuchMethodException e) {
throw new MathConfigurationException(
"No constructor with UnivariateRealFunction in "
+ solverClassName,
e);
}
}
public static double solve(UnivariateRealFunction f, double x0, double x1)
throws MathException {
return newSolver(f).solve(x0, x1);
}
public static double solve(
UnivariateRealFunction f,
double x0,
double x1,
double absoluteAccuracy)
throws MathException {
UnivariateRealSolver solver = newSolver(f);
solver.setAbsoluteAccuracy(absoluteAccuracy);
return solver.solve(x0, x1);
}
}

View File

@ -0,0 +1,238 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Commons", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.MathException;
/**
* Provide a default implementation for several functions useful to generic
* solvers.
*
* @author pietsch at apache.org
*/
public abstract class UnivariateRealSolverImpl
implements UnivariateRealSolver {
protected double absoluteAccuracy;
protected double relativeAccuracy;
protected double functionValueAccuracy;
protected int maximalIterationCount;
protected double defaultAbsoluteAccuracy;
protected double defaultRelativeAccuracy;
protected double defaultFunctionValueAccuracy;
protected int defaultMaximalIterationCount;
protected boolean resultComputed = false;
protected double result;
// Mainly for test framework.
protected int iterationCount;
protected UnivariateRealSolverImpl(
int defaultMaximalIterationCount,
double defaultAbsoluteAccuracy) {
this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy;
this.defaultRelativeAccuracy = 1E-14;
this.defaultFunctionValueAccuracy = 1E-15;
this.absoluteAccuracy = defaultAbsoluteAccuracy;
this.relativeAccuracy = defaultRelativeAccuracy;
this.functionValueAccuracy = defaultFunctionValueAccuracy;
this.defaultMaximalIterationCount = defaultMaximalIterationCount;
this.maximalIterationCount = defaultMaximalIterationCount;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#solve(double, double)
*/
public double solve(double min, double max) throws MathException {
throw new UnsupportedOperationException();
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#solve(double, double, double)
*/
public double solve(double min, double max, double startValue)
throws MathException {
throw new UnsupportedOperationException();
}
/*
* Get result of last solver run.
* @see org.apache.commons.math.UnivariateRealSolver#getResult()
*/
public double getResult() throws MathException {
if (resultComputed) {
return result;
} else {
throw new MathException("No result available");
}
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#getIterationCount()
*/
public int getIterationCount() throws MathException {
if (resultComputed) {
return iterationCount;
} else {
throw new MathException("No result available");
}
}
/*
* Convenience function for implementations.
* @param result the result to set
* @param iteratinCount the iteration count to set
*/
protected final void setResult(double result, int iterationCount) {
this.result = result;
this.iterationCount = iterationCount;
this.resultComputed = true;
}
/*
* Convenience function for implementations.
*/
protected final void clearResult() {
this.resultComputed = false;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#setAccuracy(double)
*/
public void setAbsoluteAccuracy(double accuracy)
throws MathException {
absoluteAccuracy = accuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#getAccuracy()
*/
public double getAbsoluteAccuracy() {
return absoluteAccuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#resetAbsoluteAccuracy()
*/
public void resetAbsoluteAccuracy() {
absoluteAccuracy = defaultAbsoluteAccuracy;
}
/* Set maximum iteration count.
* @see org.apache.commons.math.UnivariateRealSolver#setMaximalIterationCount(int)
*/
public void setMaximalIterationCount(int count) {
maximalIterationCount = count;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#getMaximalIterationCount()
*/
public int getMaximalIterationCount() {
return maximalIterationCount;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#resetMaximalIterationCount()
*/
public void resetMaximalIterationCount() {
maximalIterationCount = defaultMaximalIterationCount;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#setRelativeAccuracy(double)
*/
public void setRelativeAccuracy(double accuracy) throws MathException {
relativeAccuracy = accuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#getRelativeAccuracy()
*/
public double getRelativeAccuracy() {
return relativeAccuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#resetRelativeAccuracy()
*/
public void resetRelativeAccuracy() {
relativeAccuracy = defaultRelativeAccuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#setFunctionValueAccuracy(double)
*/
public void setFunctionValueAccuracy(double accuracy)
throws MathException {
functionValueAccuracy = accuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#getFunctionValueAccuracy()
*/
public double getFunctionValueAccuracy() {
return functionValueAccuracy;
}
/* (non-Javadoc)
* @see org.apache.commons.math.UnivariateRealSolver#resetFunctionValueAccuracy()
*/
public void resetFunctionValueAccuracy() {
functionValueAccuracy = defaultFunctionValueAccuracy;
}
}