The root solvers now take the function to solve as a parameter to

the solve methods, thus allowing to reuse the same solver for different
functions.

JIRA:MATH-218

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@724191 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2008-12-07 20:24:10 +00:00
parent 50fea38398
commit 71a29150bb
22 changed files with 828 additions and 438 deletions

View File

@ -196,15 +196,15 @@ public class MessagesResources_fr
"taille de vecteur invalide : {0} au lieu de {1} attendue" }, "taille de vecteur invalide : {0} au lieu de {1} attendue" },
{ "dimensions mismatch: got {0}x{1} but expected {2}x{3}", { "dimensions mismatch: got {0}x{1} but expected {2}x{3}",
"dimensions incoh\u00e9rentes : {0}x{1} \u00e0 la place de {2}x{3}" }, "dimensions incoh\u00e9rentes : {0}x{1} \u00e0 la place de {2}x{3}" },
// org.apache.commons.math.linear.BigMatrixImpl
// org.apache.commons.math.linear.RealMatrixImpl
{ "matrix must have at least one row", { "matrix must have at least one row",
"une matrice doit comporter au moins une ligne" }, "une matrice doit comporter au moins une ligne" },
{ "matrix must have at least one column", { "matrix must have at least one column",
"une matrice doit comporter au moins une colonne" }, "une matrice doit comporter au moins une colonne" },
{ "some rows have length {0} while others have length {1}", { "some rows have length {0} while others have length {1}",
"certaines ligne ont une longueur de {0} alors que d''autres ont une longueur de {1}" }, "certaines ligne ont une longueur de {0} alors que d''autres ont une longueur de {1}" },
// org.apache.commons.math.linear.BigMatrixImpl
// org.apache.commons.math.linear.RealMatrixImpl
{ "row index {0} out of allowed range [{1}, {2}]", { "row index {0} out of allowed range [{1}, {2}]",
"index de ligne {0} hors de la plage autoris\u00e9e [{1}, {2}]" }, "index de ligne {0} hors de la plage autoris\u00e9e [{1}, {2}]" },
{ "column index {0} out of allowed range [{1}, {2}]", { "column index {0} out of allowed range [{1}, {2}]",
@ -261,6 +261,18 @@ public class MessagesResources_fr
{ "identical abscissas x[{0}] == x[{1}] == {2} cause division by zero", { "identical abscissas x[{0}] == x[{1}] == {2} cause division by zero",
"division par z\u00e9ro caus\u00e9e par les abscisses identiques x[{0}] == x[{1}] == {2}" }, "division par z\u00e9ro caus\u00e9e par les abscisses identiques x[{0}] == x[{1}] == {2}" },
// org.apache.commons.math.analysis.UnivariateRealSolverImpl
{ "function to solve cannot be null",
"la fonction \u00e0 r\u00e9soudre ne peux pas \u00eatre nulle" },
// org.apache.commons.math.analysis.LaguerreSolver
{ "function is not polynomial",
"la fonction n''est pas p\u00f4lynomiale" },
// org.apache.commons.math.analysis.NewtonSolver
{ "function is not differentiable",
"la fonction n''est pas diff\u00e9rentiable" },
// org.apache.commons.math.fraction.Fraction // org.apache.commons.math.fraction.Fraction
{ "zero denominator in fraction {0}/{1}", { "zero denominator in fraction {0}/{1}",
"d\u00e9nominateur null dans le nombre rationnel {0}/{1}" }, "d\u00e9nominateur null dans le nombre rationnel {0}/{1}" },

View File

@ -30,49 +30,54 @@ import org.apache.commons.math.MaxIterationsExceededException;
public class BisectionSolver extends UnivariateRealSolverImpl { public class BisectionSolver extends UnivariateRealSolverImpl {
/** Serializable version identifier */ /** Serializable version identifier */
private static final long serialVersionUID = 4963578633786538912L; private static final long serialVersionUID = 5227509383222989438L;
/** /**
* Construct a solver for the given function. * Construct a solver for the given function.
* *
* @param f function to solve. * @param f function to solve.
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public BisectionSolver(UnivariateRealFunction f) { public BisectionSolver(UnivariateRealFunction f) {
super(f, 100, 1E-6); super(f, 100, 1E-6);
} }
/** /**
* Find a zero in the given interval. * Construct a solver.
* *
* @param min the lower bound for the interval.
* @param max the upper bound for the interval.
* @param initial the start value to use (ignored).
* @return the value where the function is zero
* @throws MaxIterationsExceededException the maximum iteration count is exceeded
* @throws FunctionEvaluationException if an error occurs evaluating
* the function
* @throws IllegalArgumentException if min is not less than max
*/ */
public BisectionSolver() {
super(100, 1E-6);
}
/** {@inheritDoc} */
@Deprecated
public double solve(double min, double max, double initial) public double solve(double min, double max, double initial)
throws MaxIterationsExceededException, FunctionEvaluationException { throws MaxIterationsExceededException, FunctionEvaluationException {
return solve(f, min, max);
return solve(min, max);
} }
/** /** {@inheritDoc} */
* Find a zero root in the given interval. @Deprecated
* public double solve(double min, double max)
* @param min the lower bound for the interval throws MaxIterationsExceededException, FunctionEvaluationException {
* @param max the upper bound for the interval return solve(f, min, max);
* @return the value where the function is zero }
* @throws MaxIterationsExceededException if the maximum iteration count is exceeded.
* @throws FunctionEvaluationException if an error occurs evaluating the /** {@inheritDoc} */
* function public double solve(final UnivariateRealFunction f, double min, double max, double initial)
* @throws IllegalArgumentException if min is not less than max throws MaxIterationsExceededException, FunctionEvaluationException {
*/ return solve(min, max);
public double solve(double min, double max) throws MaxIterationsExceededException, }
FunctionEvaluationException {
/** {@inheritDoc} */
public double solve(final UnivariateRealFunction f, double min, double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
clearResult(); clearResult();
verifyInterval(min,max); verifyInterval(min,max);
double m; double m;

View File

@ -31,17 +31,43 @@ import org.apache.commons.math.MaxIterationsExceededException;
public class BrentSolver extends UnivariateRealSolverImpl { public class BrentSolver extends UnivariateRealSolverImpl {
/** Serializable version identifier */ /** Serializable version identifier */
private static final long serialVersionUID = -2136672307739067002L; private static final long serialVersionUID = 7694577816772532779L;
/** /**
* Construct a solver for the given function. * Construct a solver for the given function.
* *
* @param f function to solve. * @param f function to solve.
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public BrentSolver(UnivariateRealFunction f) { public BrentSolver(UnivariateRealFunction f) {
super(f, 100, 1E-6); super(f, 100, 1E-6);
} }
/**
* Construct a solver.
*/
public BrentSolver() {
super(100, 1E-6);
}
/** {@inheritDoc} */
@Deprecated
public double solve(double min, double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
return solve(f, min, max);
}
/** {@inheritDoc} */
@Deprecated
public double solve(double min, double max, double initial)
throws MaxIterationsExceededException, FunctionEvaluationException {
return solve(f, min, max, initial);
}
/** /**
* Find a zero in the given interval with an initial guess. * Find a zero in the given interval with an initial guess.
* <p>Throws <code>IllegalArgumentException</code> if the values of the * <p>Throws <code>IllegalArgumentException</code> if the values of the
@ -49,6 +75,7 @@ public class BrentSolver extends UnivariateRealSolverImpl {
* allowed to have endpoints with the same sign if the initial point has * allowed to have endpoints with the same sign if the initial point has
* opposite sign function-wise).</p> * opposite sign function-wise).</p>
* *
* @param f function to solve.
* @param min the lower bound for the interval. * @param min the lower bound for the interval.
* @param max the upper bound for the interval. * @param max the upper bound for the interval.
* @param initial the start value to use (must be set to min if no * @param initial the start value to use (must be set to min if no
@ -61,7 +88,8 @@ public class BrentSolver extends UnivariateRealSolverImpl {
* @throws IllegalArgumentException if initial is not between min and max * @throws IllegalArgumentException if initial is not between min and max
* (even if it <em>is</em> a root) * (even if it <em>is</em> a root)
*/ */
public double solve(double min, double max, double initial) public double solve(final UnivariateRealFunction f,
final double min, final double max, final double initial)
throws MaxIterationsExceededException, FunctionEvaluationException { throws MaxIterationsExceededException, FunctionEvaluationException {
if (((initial - min) * (max -initial)) < 0) { if (((initial - min) * (max -initial)) < 0) {
@ -86,7 +114,7 @@ public class BrentSolver extends UnivariateRealSolverImpl {
// reduce interval if min and initial bracket the root // reduce interval if min and initial bracket the root
if (yInitial * yMin < 0) { if (yInitial * yMin < 0) {
return solve(min, yMin, initial, yInitial, min, yMin); return solve(f, min, yMin, initial, yInitial, min, yMin);
} }
// return the second endpoint if it is good enough // return the second endpoint if it is good enough
@ -98,11 +126,11 @@ public class BrentSolver extends UnivariateRealSolverImpl {
// reduce interval if initial and max bracket the root // reduce interval if initial and max bracket the root
if (yInitial * yMax < 0) { if (yInitial * yMax < 0) {
return solve(initial, yInitial, max, yMax, initial, yInitial); return solve(f, initial, yInitial, max, yMax, initial, yInitial);
} }
// full Brent algorithm starting with provided initial guess // full Brent algorithm starting with provided initial guess
return solve(min, yMin, max, yMax, initial, yInitial); return solve(f, min, yMin, max, yMax, initial, yInitial);
} }
@ -122,7 +150,9 @@ public class BrentSolver extends UnivariateRealSolverImpl {
* @throws IllegalArgumentException if min is not less than max or the * @throws IllegalArgumentException if min is not less than max or the
* signs of the values of the function at the endpoints are not opposites * signs of the values of the function at the endpoints are not opposites
*/ */
public double solve(double min, double max) throws MaxIterationsExceededException, public double solve(final UnivariateRealFunction f,
final double min, final double max)
throws MaxIterationsExceededException,
FunctionEvaluationException { FunctionEvaluationException {
clearResult(); clearResult();
@ -152,7 +182,7 @@ public class BrentSolver extends UnivariateRealSolverImpl {
} }
} else if (sign < 0){ } else if (sign < 0){
// solve using only the first endpoint as initial guess // solve using only the first endpoint as initial guess
ret = solve(min, yMin, max, yMax, min, yMin); ret = solve(f, min, yMin, max, yMax, min, yMin);
} else { } else {
// either min or max is a root // either min or max is a root
if (yMin == 0.0) { if (yMin == 0.0) {
@ -167,6 +197,7 @@ public class BrentSolver extends UnivariateRealSolverImpl {
/** /**
* Find a zero starting search according to the three provided points. * Find a zero starting search according to the three provided points.
* @param f the function to solve
* @param x0 old approximation for the root * @param x0 old approximation for the root
* @param y0 function value at the approximation for the root * @param y0 function value at the approximation for the root
* @param x1 last calculated approximation for the root * @param x1 last calculated approximation for the root
@ -181,7 +212,8 @@ public class BrentSolver extends UnivariateRealSolverImpl {
* @throws FunctionEvaluationException if an error occurs evaluating * @throws FunctionEvaluationException if an error occurs evaluating
* the function * the function
*/ */
private double solve(double x0, double y0, private double solve(final UnivariateRealFunction f,
double x0, double y0,
double x1, double y1, double x1, double y1,
double x2, double y2) double x2, double y2)
throws MaxIterationsExceededException, FunctionEvaluationException { throws MaxIterationsExceededException, FunctionEvaluationException {

View File

@ -18,6 +18,7 @@ package org.apache.commons.math.analysis;
import org.apache.commons.math.ConvergenceException; import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.complex.Complex; import org.apache.commons.math.complex.Complex;
@ -38,7 +39,10 @@ public class LaguerreSolver extends UnivariateRealSolverImpl {
/** serializable version identifier */ /** serializable version identifier */
private static final long serialVersionUID = -3775334783473775723L; private static final long serialVersionUID = -3775334783473775723L;
/** polynomial function to solve */ /** polynomial function to solve.
* @deprecated as of 2.0 the function is not stored anymore in the instance
*/
@Deprecated
private PolynomialFunction p; private PolynomialFunction p;
/** /**
@ -46,32 +50,60 @@ public class LaguerreSolver extends UnivariateRealSolverImpl {
* *
* @param f function to solve * @param f function to solve
* @throws IllegalArgumentException if function is not polynomial * @throws IllegalArgumentException if function is not polynomial
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public LaguerreSolver(UnivariateRealFunction f) throws public LaguerreSolver(UnivariateRealFunction f) throws
IllegalArgumentException { IllegalArgumentException {
super(f, 100, 1E-6); super(f, 100, 1E-6);
if (f instanceof PolynomialFunction) { if (f instanceof PolynomialFunction) {
p = (PolynomialFunction)f; p = (PolynomialFunction) f;
} else { } else {
throw new IllegalArgumentException("Function is not polynomial."); throw MathRuntimeException.createIllegalArgumentException("function is not polynomial", null);
} }
} }
/**
* Construct a solver.
*/
public LaguerreSolver() {
super(100, 1E-6);
}
/** /**
* Returns a copy of the polynomial function. * Returns a copy of the polynomial function.
* *
* @return a fresh copy of the polynomial function * @return a fresh copy of the polynomial function
* @deprecated as of 2.0 the function is not stored anymore within the instance.
*/ */
@Deprecated
public PolynomialFunction getPolynomialFunction() { public PolynomialFunction getPolynomialFunction() {
return new PolynomialFunction(p.getCoefficients()); return new PolynomialFunction(p.getCoefficients());
} }
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max)
throws ConvergenceException, FunctionEvaluationException {
return solve(p, min, max);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max, final double initial)
throws ConvergenceException, FunctionEvaluationException {
return solve(p, min, max, initial);
}
/** /**
* Find a real root in the given interval with initial value. * Find a real root in the given interval with initial value.
* <p> * <p>
* Requires bracketing condition.</p> * Requires bracketing condition.</p>
* *
* @param f function to solve (must be polynomial)
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @param initial the start value to use * @param initial the start value to use
@ -82,21 +114,23 @@ public class LaguerreSolver extends UnivariateRealSolverImpl {
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
*/ */
public double solve(double min, double max, double initial) throws public double solve(final UnivariateRealFunction f,
ConvergenceException, FunctionEvaluationException { final double min, final double max, final double initial)
throws ConvergenceException, FunctionEvaluationException {
// check for zeros before verifying bracketing // check for zeros before verifying bracketing
if (p.value(min) == 0.0) { return min; } if (f.value(min) == 0.0) { return min; }
if (p.value(max) == 0.0) { return max; } if (f.value(max) == 0.0) { return max; }
if (p.value(initial) == 0.0) { return initial; } if (f.value(initial) == 0.0) { return initial; }
verifyBracketing(min, max, p); verifyBracketing(min, max, f);
verifySequence(min, initial, max); verifySequence(min, initial, max);
if (isBracketing(min, initial, p)) { if (isBracketing(min, initial, f)) {
return solve(min, initial); return solve(f, min, initial);
} else { } else {
return solve(initial, max); return solve(f, initial, max);
} }
} }
/** /**
@ -108,6 +142,7 @@ public class LaguerreSolver extends UnivariateRealSolverImpl {
* another initial value, or, as we did here, call solveAll() to obtain * another initial value, or, as we did here, call solveAll() to obtain
* all roots and pick up the one that we're looking for.</p> * all roots and pick up the one that we're looking for.</p>
* *
* @param f the function to solve
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @return the point at which the function value is zero * @return the point at which the function value is zero
@ -117,15 +152,21 @@ public class LaguerreSolver extends UnivariateRealSolverImpl {
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
*/ */
public double solve(double min, double max) throws ConvergenceException, public double solve(final UnivariateRealFunction f,
FunctionEvaluationException { final double min, final double max)
throws ConvergenceException, FunctionEvaluationException {
// check function type
if (!(f instanceof PolynomialFunction)) {
throw MathRuntimeException.createIllegalArgumentException("function is not polynomial", null);
}
// check for zeros before verifying bracketing // check for zeros before verifying bracketing
if (p.value(min) == 0.0) { return min; } if (f.value(min) == 0.0) { return min; }
if (p.value(max) == 0.0) { return max; } if (f.value(max) == 0.0) { return max; }
verifyBracketing(min, max, p); verifyBracketing(min, max, f);
double coefficients[] = p.getCoefficients(); double coefficients[] = ((PolynomialFunction) f).getCoefficients();
Complex c[] = new Complex[coefficients.length]; Complex c[] = new Complex[coefficients.length];
for (int i = 0; i < coefficients.length; i++) { for (int i = 0; i < coefficients.length; i++) {
c[i] = new Complex(coefficients[i], 0.0); c[i] = new Complex(coefficients[i], 0.0);

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.commons.math.analysis; package org.apache.commons.math.analysis;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.MathUtils;
@ -36,22 +37,49 @@ import org.apache.commons.math.util.MathUtils;
public class MullerSolver extends UnivariateRealSolverImpl { public class MullerSolver extends UnivariateRealSolverImpl {
/** serializable version identifier */ /** serializable version identifier */
private static final long serialVersionUID = 6552227503458976920L; private static final long serialVersionUID = 7768903775784754323L;
/** /**
* Construct a solver for the given function. * Construct a solver for the given function.
* *
* @param f function to solve * @param f function to solve
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public MullerSolver(UnivariateRealFunction f) { public MullerSolver(UnivariateRealFunction f) {
super(f, 100, 1E-6); super(f, 100, 1E-6);
} }
/**
* Construct a solver.
*/
public MullerSolver() {
super(100, 1E-6);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max)
throws ConvergenceException, FunctionEvaluationException {
return solve(f, min, max);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max, final double initial)
throws ConvergenceException, FunctionEvaluationException {
return solve(f, min, max, initial);
}
/** /**
* Find a real root in the given interval with initial value. * Find a real root in the given interval with initial value.
* <p> * <p>
* Requires bracketing condition.</p> * Requires bracketing condition.</p>
* *
* @param f the function to solve
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @param initial the start value to use * @param initial the start value to use
@ -62,8 +90,9 @@ public class MullerSolver extends UnivariateRealSolverImpl {
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
*/ */
public double solve(double min, double max, double initial) throws public double solve(final UnivariateRealFunction f,
MaxIterationsExceededException, FunctionEvaluationException { final double min, final double max, final double initial)
throws MaxIterationsExceededException, FunctionEvaluationException {
// check for zeros before verifying bracketing // check for zeros before verifying bracketing
if (f.value(min) == 0.0) { return min; } if (f.value(min) == 0.0) { return min; }
@ -73,9 +102,9 @@ public class MullerSolver extends UnivariateRealSolverImpl {
verifyBracketing(min, max, f); verifyBracketing(min, max, f);
verifySequence(min, initial, max); verifySequence(min, initial, max);
if (isBracketing(min, initial, f)) { if (isBracketing(min, initial, f)) {
return solve(min, initial); return solve(f, min, initial);
} else { } else {
return solve(initial, max); return solve(f, initial, max);
} }
} }
@ -94,6 +123,7 @@ public class MullerSolver extends UnivariateRealSolverImpl {
* <p> * <p>
* The formulas here use divided differences directly.</p> * The formulas here use divided differences directly.</p>
* *
* @param f the function to solve
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @return the point at which the function value is zero * @return the point at which the function value is zero
@ -103,8 +133,9 @@ public class MullerSolver extends UnivariateRealSolverImpl {
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
*/ */
public double solve(double min, double max) throws MaxIterationsExceededException, public double solve(final UnivariateRealFunction f,
FunctionEvaluationException { final double min, final double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
// [x0, x2] is the bracketing interval in each iteration // [x0, x2] is the bracketing interval in each iteration
// x1 is the last approximation and an interpolation point in (x0, x2) // x1 is the last approximation and an interpolation point in (x0, x2)
@ -208,9 +239,43 @@ public class MullerSolver extends UnivariateRealSolverImpl {
* @throws FunctionEvaluationException if an error occurs evaluating the * @throws FunctionEvaluationException if an error occurs evaluating the
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
* @deprecated replaced by {@link #solve2(UnivariateRealFunction, double, double)
* since 2.0
*/ */
public double solve2(double min, double max) throws MaxIterationsExceededException, @Deprecated
FunctionEvaluationException { public double solve2(final double min, final double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
return solve2(f, min, max);
}
/**
* Find a real root in the given interval.
* <p>
* solve2() differs from solve() in the way it avoids complex operations.
* Except for the initial [min, max], solve2() does not require bracketing
* condition, e.g. f(x0), f(x1), f(x2) can have the same sign. If complex
* number arises in the computation, we simply use its modulus as real
* approximation.</p>
* <p>
* Because the interval may not be bracketing, bisection alternative is
* not applicable here. However in practice our treatment usually works
* well, especially near real zeros where the imaginary part of complex
* approximation is often negligible.</p>
* <p>
* The formulas here do not use divided differences directly.</p>
*
* @param min the lower bound for the interval
* @param max the upper bound for the interval
* @return the point at which the function value is zero
* @throws MaxIterationsExceededException if the maximum iteration count is exceeded
* or the solver detects convergence problems otherwise
* @throws FunctionEvaluationException if an error occurs evaluating the
* function
* @throws IllegalArgumentException if any parameters are invalid
*/
public double solve2(final UnivariateRealFunction f,
final double min, final double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
// x2 is the last root approximation // x2 is the last root approximation
// x is the new approximation and new x2 for next round // x is the new approximation and new x2 for next round

View File

@ -17,8 +17,8 @@
package org.apache.commons.math.analysis; package org.apache.commons.math.analysis;
import java.io.IOException; import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.MaxIterationsExceededException;
/** /**
@ -32,18 +32,41 @@ import org.apache.commons.math.MaxIterationsExceededException;
public class NewtonSolver extends UnivariateRealSolverImpl { public class NewtonSolver extends UnivariateRealSolverImpl {
/** Serializable version identifier */ /** Serializable version identifier */
private static final long serialVersionUID = 2067325783137941016L; private static final long serialVersionUID = 7579593514004764309L;
/** The first derivative of the target function. */
private transient UnivariateRealFunction derivative;
/** /**
* Construct a solver for the given function. * Construct a solver for the given function.
* @param f function to solve. * @param f function to solve.
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public NewtonSolver(DifferentiableUnivariateRealFunction f) { public NewtonSolver(DifferentiableUnivariateRealFunction f) {
super(f, 100, 1E-6); super(f, 100, 1E-6);
derivative = f.derivative(); }
/**
* Construct a solver.
*/
public NewtonSolver() {
super(100, 1E-6);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max)
throws MaxIterationsExceededException,
FunctionEvaluationException {
return solve(f, min, max);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max, final double startValue)
throws MaxIterationsExceededException, FunctionEvaluationException {
return solve(f, min, max, startValue);
} }
/** /**
@ -57,9 +80,10 @@ public class NewtonSolver extends UnivariateRealSolverImpl {
* function or derivative * function or derivative
* @throws IllegalArgumentException if min is not less than max * @throws IllegalArgumentException if min is not less than max
*/ */
public double solve(double min, double max) throws MaxIterationsExceededException, public double solve(final UnivariateRealFunction f,
FunctionEvaluationException { final double min, final double max)
return solve(min, max, UnivariateRealSolverUtils.midpoint(min, max)); throws MaxIterationsExceededException, FunctionEvaluationException {
return solve(f, min, max, UnivariateRealSolverUtils.midpoint(min, max));
} }
/** /**
@ -72,43 +96,41 @@ public class NewtonSolver extends UnivariateRealSolverImpl {
* @throws MaxIterationsExceededException if the maximum iteration count is exceeded * @throws MaxIterationsExceededException if the maximum iteration count is exceeded
* @throws FunctionEvaluationException if an error occurs evaluating the * @throws FunctionEvaluationException if an error occurs evaluating the
* function or derivative * function or derivative
* @throws IllegalArgumentException if startValue is not between min and max * @throws IllegalArgumentException if startValue is not between min and max or
* if function is not a {@link DifferentiableUnivariateRealFunction} instance
*/ */
public double solve(double min, double max, double startValue) public double solve(final UnivariateRealFunction f,
final double min, final double max, final double startValue)
throws MaxIterationsExceededException, FunctionEvaluationException { throws MaxIterationsExceededException, FunctionEvaluationException {
clearResult();
verifySequence(min, startValue, max);
double x0 = startValue; try {
double x1;
final UnivariateRealFunction derivative =
int i = 0; ((DifferentiableUnivariateRealFunction) f).derivative();
while (i < maximalIterationCount) { clearResult();
x1 = x0 - (f.value(x0) / derivative.value(x0)); verifySequence(min, startValue, max);
if (Math.abs(x1 - x0) <= absoluteAccuracy) {
double x0 = startValue;
setResult(x1, i); double x1;
return x1;
int i = 0;
while (i < maximalIterationCount) {
x1 = x0 - (f.value(x0) / derivative.value(x0));
if (Math.abs(x1 - x0) <= absoluteAccuracy) {
setResult(x1, i);
return x1;
}
x0 = x1;
++i;
} }
x0 = x1; throw new MaxIterationsExceededException(maximalIterationCount);
++i; } catch (ClassCastException cce) {
throw MathRuntimeException.createIllegalArgumentException("function is not differentiable",
null);
} }
throw new MaxIterationsExceededException(maximalIterationCount);
} }
/**
* Custom deserialization to initialize transient deriviate field.
*
* @param in serialized object input stream
* @throws IOException if IO error occurs
* @throws ClassNotFoundException if instantiation error occurs
*/
private void readObject(java.io.ObjectInputStream in)
throws IOException, ClassNotFoundException {
in.defaultReadObject();
derivative = ((DifferentiableUnivariateRealFunction) f).derivative();
}
} }

View File

@ -16,6 +16,7 @@
*/ */
package org.apache.commons.math.analysis; package org.apache.commons.math.analysis;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.util.MathUtils; import org.apache.commons.math.util.MathUtils;
@ -35,22 +36,49 @@ import org.apache.commons.math.util.MathUtils;
public class RiddersSolver extends UnivariateRealSolverImpl { public class RiddersSolver extends UnivariateRealSolverImpl {
/** serializable version identifier */ /** serializable version identifier */
private static final long serialVersionUID = -4703139035737911735L; private static final long serialVersionUID = -1556464494585337088L;
/** /**
* Construct a solver for the given function. * Construct a solver for the given function.
* *
* @param f function to solve * @param f function to solve
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public RiddersSolver(UnivariateRealFunction f) { public RiddersSolver(UnivariateRealFunction f) {
super(f, 100, 1E-6); super(f, 100, 1E-6);
} }
/**
* Construct a solver.
*/
public RiddersSolver() {
super(100, 1E-6);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max)
throws ConvergenceException, FunctionEvaluationException {
return solve(f, min, max);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max, final double initial)
throws ConvergenceException, FunctionEvaluationException {
return solve(f, min, max, initial);
}
/** /**
* Find a root in the given interval with initial value. * Find a root in the given interval with initial value.
* <p> * <p>
* Requires bracketing condition.</p> * Requires bracketing condition.</p>
* *
* @param f the function to solve
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @param initial the start value to use * @param initial the start value to use
@ -60,8 +88,9 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
*/ */
public double solve(double min, double max, double initial) throws public double solve(final UnivariateRealFunction f,
MaxIterationsExceededException, FunctionEvaluationException { final double min, final double max, final double initial)
throws MaxIterationsExceededException, FunctionEvaluationException {
// check for zeros before verifying bracketing // check for zeros before verifying bracketing
if (f.value(min) == 0.0) { return min; } if (f.value(min) == 0.0) { return min; }
@ -71,9 +100,9 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
verifyBracketing(min, max, f); verifyBracketing(min, max, f);
verifySequence(min, initial, max); verifySequence(min, initial, max);
if (isBracketing(min, initial, f)) { if (isBracketing(min, initial, f)) {
return solve(min, initial); return solve(f, min, initial);
} else { } else {
return solve(initial, max); return solve(f, initial, max);
} }
} }
@ -82,6 +111,7 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
* <p> * <p>
* Requires bracketing condition.</p> * Requires bracketing condition.</p>
* *
* @param f the function to solve
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @return the point at which the function value is zero * @return the point at which the function value is zero
@ -90,8 +120,9 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
* function * function
* @throws IllegalArgumentException if any parameters are invalid * @throws IllegalArgumentException if any parameters are invalid
*/ */
public double solve(double min, double max) throws MaxIterationsExceededException, public double solve(final UnivariateRealFunction f,
FunctionEvaluationException { final double min, final double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
// [x1, x2] is the bracketing interval in each iteration // [x1, x2] is the bracketing interval in each iteration
// x3 is the midpoint of [x1, x2] // x3 is the midpoint of [x1, x2]

View File

@ -18,6 +18,7 @@ package org.apache.commons.math.analysis;
import java.io.Serializable; import java.io.Serializable;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException; import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException; import org.apache.commons.math.MaxIterationsExceededException;
@ -41,19 +42,46 @@ import org.apache.commons.math.MaxIterationsExceededException;
public class SecantSolver extends UnivariateRealSolverImpl implements Serializable { public class SecantSolver extends UnivariateRealSolverImpl implements Serializable {
/** Serializable version identifier */ /** Serializable version identifier */
private static final long serialVersionUID = 1984971194738974867L; private static final long serialVersionUID = 2477470651270304246L;
/** /**
* Construct a solver for the given function. * Construct a solver for the given function.
* @param f function to solve. * @param f function to solve.
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
public SecantSolver(UnivariateRealFunction f) { public SecantSolver(UnivariateRealFunction f) {
super(f, 100, 1E-6); super(f, 100, 1E-6);
} }
/**
* Construct a solver.
*/
public SecantSolver() {
super(100, 1E-6);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max)
throws ConvergenceException, FunctionEvaluationException {
return solve(f, min, max);
}
/** {@inheritDoc} */
@Deprecated
public double solve(final double min, final double max, final double initial)
throws ConvergenceException, FunctionEvaluationException {
return solve(f, min, max, initial);
}
/** /**
* Find a zero in the given interval. * Find a zero in the given interval.
* *
* @param f the function to solve
* @param min the lower bound for the interval * @param min the lower bound for the interval
* @param max the upper bound for the interval * @param max the upper bound for the interval
* @param initial the start value to use (ignored) * @param initial the start value to use (ignored)
@ -64,14 +92,15 @@ public class SecantSolver extends UnivariateRealSolverImpl implements Serializab
* @throws IllegalArgumentException if min is not less than max or the * @throws IllegalArgumentException if min is not less than max or the
* signs of the values of the function at the endpoints are not opposites * signs of the values of the function at the endpoints are not opposites
*/ */
public double solve(double min, double max, double initial) public double solve(final UnivariateRealFunction f,
final double min, final double max, final double initial)
throws MaxIterationsExceededException, FunctionEvaluationException { throws MaxIterationsExceededException, FunctionEvaluationException {
return solve(f, min, max);
return solve(min, max);
} }
/** /**
* Find a zero in the given interval. * Find a zero in the given interval.
* @param f the function to solve
* @param min the lower bound for the interval. * @param min the lower bound for the interval.
* @param max the upper bound for the interval. * @param max the upper bound for the interval.
* @return the value where the function is zero * @return the value where the function is zero
@ -81,8 +110,9 @@ public class SecantSolver extends UnivariateRealSolverImpl implements Serializab
* @throws IllegalArgumentException if min is not less than max or the * @throws IllegalArgumentException if min is not less than max or the
* signs of the values of the function at the endpoints are not opposites * signs of the values of the function at the endpoints are not opposites
*/ */
public double solve(double min, double max) throws MaxIterationsExceededException, public double solve(final UnivariateRealFunction f,
FunctionEvaluationException { final double min, final double max)
throws MaxIterationsExceededException, FunctionEvaluationException {
clearResult(); clearResult();
verifyInterval(min, max); verifyInterval(min, max);

View File

@ -158,10 +158,33 @@ public interface UnivariateRealSolver {
* function * function
* @throws IllegalArgumentException if min > max or the endpoints do not * @throws IllegalArgumentException if min > max or the endpoints do not
* satisfy the requirements specified by the solver * satisfy the requirements specified by the solver
* @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double)
* since 2.0
*/ */
@Deprecated
double solve(double min, double max) throws ConvergenceException, double solve(double min, double max) throws ConvergenceException,
FunctionEvaluationException; FunctionEvaluationException;
/**
* Solve for a zero root in the given interval.
* A solver may require that the interval brackets a single zero root.
*
* @param f the function to solve.
* @param min the lower bound for the interval.
* @param max the upper bound for the interval.
* @return a value where the function is zero
* @throws ConvergenceException if the maximum iteration count is exceeded
* or the solver detects convergence problems otherwise.
* @throws FunctionEvaluationException if an error occurs evaluating the
* function
* @throws IllegalArgumentException if min > max or the endpoints do not
* satisfy the requirements specified by the solver
* @since 2.0
*/
double solve(UnivariateRealFunction f, double min, double max)
throws ConvergenceException,
FunctionEvaluationException;
/** /**
* Solve for a zero in the given interval, start at startValue. * Solve for a zero in the given interval, start at startValue.
* A solver may require that the interval brackets a single zero root. * A solver may require that the interval brackets a single zero root.
@ -176,10 +199,33 @@ public interface UnivariateRealSolver {
* function * function
* @throws IllegalArgumentException if min > max or the arguments do not * @throws IllegalArgumentException if min > max or the arguments do not
* satisfy the requirements specified by the solver * satisfy the requirements specified by the solver
* @deprecated replaced by {@link #solve(UnivariateRealFunction, double, double, double)
* since 2.0
*/ */
@Deprecated
double solve(double min, double max, double startValue) double solve(double min, double max, double startValue)
throws ConvergenceException, FunctionEvaluationException; throws ConvergenceException, FunctionEvaluationException;
/**
* Solve for a zero in the given interval, start at startValue.
* A solver may require that the interval brackets a single zero root.
*
* @param f the function to solve.
* @param min the lower bound for the interval.
* @param max the upper bound for the interval.
* @param startValue the start value to use
* @return a value where the function is zero
* @throws ConvergenceException if the maximum iteration count is exceeded
* or the solver detects convergence problems otherwise.
* @throws FunctionEvaluationException if an error occurs evaluating the
* function
* @throws IllegalArgumentException if min > max or the arguments do not
* satisfy the requirements specified by the solver
* @since 2.0
*/
double solve(UnivariateRealFunction f, double min, double max, double startValue)
throws ConvergenceException, FunctionEvaluationException;
/** /**
* Get the result of the last run of the solver. * Get the result of the last run of the solver.
* *

View File

@ -31,8 +31,8 @@ package org.apache.commons.math.analysis;
* Common usage:<pre> * Common usage:<pre>
* SolverFactory factory = UnivariateRealSolverFactory.newInstance();</p> * SolverFactory factory = UnivariateRealSolverFactory.newInstance();</p>
* *
* // create a Brent solver to use with a UnivariateRealFunction f * // create a Brent solver to use
* BrentSolver solver = factory.newBrentSolver(f); * BrentSolver solver = factory.newBrentSolver();
* </pre> * </pre>
* *
* @version $Revision$ $Date$ * @version $Revision$ $Date$
@ -53,47 +53,38 @@ public abstract class UnivariateRealSolverFactory {
} }
/** /**
* Create a new {@link UnivariateRealSolver} for the given function. The * Create a new {@link UnivariateRealSolver}. The
* actual solver returned is determined by the underlying factory. * actual solver returned is determined by the underlying factory.
* @param f the function.
* @return the new solver. * @return the new solver.
*/ */
public abstract UnivariateRealSolver newDefaultSolver( public abstract UnivariateRealSolver newDefaultSolver();
UnivariateRealFunction f);
/** /**
* Create a new {@link UnivariateRealSolver} for the given function. The * Create a new {@link UnivariateRealSolver}. The
* solver is an implementation of the bisection method. * solver is an implementation of the bisection method.
* @param f the function.
* @return the new solver. * @return the new solver.
*/ */
public abstract UnivariateRealSolver newBisectionSolver( public abstract UnivariateRealSolver newBisectionSolver();
UnivariateRealFunction f);
/** /**
* Create a new {@link UnivariateRealSolver} for the given function. The * Create a new {@link UnivariateRealSolver}. The
* solver is an implementation of the Brent method. * solver is an implementation of the Brent method.
* @param f the function.
* @return the new solver. * @return the new solver.
*/ */
public abstract UnivariateRealSolver newBrentSolver( public abstract UnivariateRealSolver newBrentSolver();
UnivariateRealFunction f);
/** /**
* Create a new {@link UnivariateRealSolver} for the given function. The * Create a new {@link UnivariateRealSolver}. The
* solver is an implementation of Newton's Method. * solver is an implementation of Newton's Method.
* @param f the function.
* @return the new solver. * @return the new solver.
*/ */
public abstract UnivariateRealSolver newNewtonSolver( public abstract UnivariateRealSolver newNewtonSolver();
DifferentiableUnivariateRealFunction f);
/** /**
* Create a new {@link UnivariateRealSolver} for the given function. The * Create a new {@link UnivariateRealSolver}. The
* solver is an implementation of the secant method. * solver is an implementation of the secant method.
* @param f the function.
* @return the new solver. * @return the new solver.
*/ */
public abstract UnivariateRealSolver newSecantSolver( public abstract UnivariateRealSolver newSecantSolver();
UnivariateRealFunction f);
} }

View File

@ -32,58 +32,28 @@ public class UnivariateRealSolverFactoryImpl extends UnivariateRealSolverFactory
public UnivariateRealSolverFactoryImpl() { public UnivariateRealSolverFactoryImpl() {
} }
/** /** {@inheritDoc} */
* Create a new {@link UnivariateRealSolver} for the given function. The public UnivariateRealSolver newDefaultSolver() {
* actual solver returned is determined by the underlying factory. return newBrentSolver();
*
* This factory returns a {@link BrentSolver} instance.
*
* @param f the function.
* @return the new solver.
*/
public UnivariateRealSolver newDefaultSolver(UnivariateRealFunction f) {
return newBrentSolver(f);
} }
/** /** {@inheritDoc} */
* Create a new {@link UnivariateRealSolver} for the given function. The public UnivariateRealSolver newBisectionSolver() {
* solver is an implementation of the bisection method. return new BisectionSolver();
* @param f the function.
* @return the new solver.
*/
public UnivariateRealSolver newBisectionSolver(UnivariateRealFunction f) {
return new BisectionSolver(f);
} }
/** /** {@inheritDoc} */
* Create a new {@link UnivariateRealSolver} for the given function. The public UnivariateRealSolver newBrentSolver() {
* solver is an implementation of the Brent method. return new BrentSolver();
* @param f the function.
* @return the new solver.
*/
public UnivariateRealSolver newBrentSolver(UnivariateRealFunction f) {
return new BrentSolver(f);
} }
/** /** {@inheritDoc} */
* Create a new {@link UnivariateRealSolver} for the given function. The public UnivariateRealSolver newNewtonSolver() {
* solver is an implementation of Newton's Method. return new NewtonSolver();
* @param f the function.
* @return the new solver.
*/
public UnivariateRealSolver newNewtonSolver(
DifferentiableUnivariateRealFunction f) {
return new NewtonSolver(f);
} }
/** /** {@inheritDoc} */
* Create a new {@link UnivariateRealSolver} for the given function. The public UnivariateRealSolver newSecantSolver() {
* solver is an implementation of the secant method. return new SecantSolver();
* @param f the function.
* @return the new solver.
*/
public UnivariateRealSolver newSecantSolver(UnivariateRealFunction f) {
return new SecantSolver(f);
} }
} }

View File

@ -68,7 +68,12 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver,
/** The last iteration count. */ /** The last iteration count. */
protected int iterationCount; protected int iterationCount;
/** The function to solve. */ /** The function to solve.
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method. */
@Deprecated
protected UnivariateRealFunction f; protected UnivariateRealFunction f;
/** /**
@ -79,19 +84,43 @@ public abstract class UnivariateRealSolverImpl implements UnivariateRealSolver,
* @param defaultMaximalIterationCount maximum number of iterations * @param defaultMaximalIterationCount maximum number of iterations
* @throws IllegalArgumentException if f is null or the * @throws IllegalArgumentException if f is null or the
* defaultAbsoluteAccuracy is not valid * defaultAbsoluteAccuracy is not valid
* @deprecated as of 2.0 the function to solve is passed as an argument
* to the {@link #solve(UnivariateRealFunction, double, double)} or
* {@link UnivariateRealSolverImpl#solve(UnivariateRealFunction, double, double, double)}
* method.
*/ */
@Deprecated
protected UnivariateRealSolverImpl( protected UnivariateRealSolverImpl(
UnivariateRealFunction f, UnivariateRealFunction f,
int defaultMaximalIterationCount, int defaultMaximalIterationCount,
double defaultAbsoluteAccuracy) { double defaultAbsoluteAccuracy) {
super();
if (f == null) { if (f == null) {
throw new IllegalArgumentException("function can not be null."); throw MathRuntimeException.createIllegalArgumentException("function to solve cannot be null",
null);
} }
this.f = f; this.f = f;
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;
}
/**
* Construct a solver with given iteration count and accuracy.
*
* @param defaultAbsoluteAccuracy maximum absolute error
* @param defaultMaximalIterationCount maximum number of iterations
* @throws IllegalArgumentException if f is null or the
* defaultAbsoluteAccuracy is not valid
*/
protected UnivariateRealSolverImpl(int defaultMaximalIterationCount,
double defaultAbsoluteAccuracy) {
this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy; this.defaultAbsoluteAccuracy = defaultAbsoluteAccuracy;
this.defaultRelativeAccuracy = 1E-14; this.defaultRelativeAccuracy = 1E-14;
this.defaultFunctionValueAccuracy = 1E-15; this.defaultFunctionValueAccuracy = 1E-15;

View File

@ -52,7 +52,7 @@ public class UnivariateRealSolverUtils {
public static double solve(UnivariateRealFunction f, double x0, double x1) public static double solve(UnivariateRealFunction f, double x0, double x1)
throws ConvergenceException, FunctionEvaluationException { throws ConvergenceException, FunctionEvaluationException {
setup(f); setup(f);
return factory.newDefaultSolver(f).solve(x0, x1); return factory.newDefaultSolver().solve(f, x0, x1);
} }
/** /**
@ -76,9 +76,9 @@ public class UnivariateRealSolverUtils {
FunctionEvaluationException { FunctionEvaluationException {
setup(f); setup(f);
UnivariateRealSolver solver = factory.newDefaultSolver(f); UnivariateRealSolver solver = factory.newDefaultSolver();
solver.setAbsoluteAccuracy(absoluteAccuracy); solver.setAbsoluteAccuracy(absoluteAccuracy);
return solver.solve(x0, x1); return solver.solve(f, x0, x1);
} }
/** /**

View File

@ -39,6 +39,11 @@ The <action> type attribute can be add,update,fix,remove.
</properties> </properties>
<body> <body>
<release version="2.0" date="TBD" description="TBD"> <release version="2.0" date="TBD" description="TBD">
<action dev="luc" type="update" issue="MATH-218" >
The root solvers now take the function to solve as a parameter to
the solve methods, thus allowing to reuse the same solver for different
functions.
</action>
<action dev="luc" type="add" issue="MATH-234" > <action dev="luc" type="add" issue="MATH-234" >
Added setter methods for rows and columns in matrices. Added setter methods for rows and columns in matrices.
</action> </action>

View File

@ -50,6 +50,12 @@
Newton's Method</a></li> Newton's Method</a></li>
<li><a href="../apidocs/org/apache/commons/math/analysis/SecantSolver.html"> <li><a href="../apidocs/org/apache/commons/math/analysis/SecantSolver.html">
Secant Method</a></li> Secant Method</a></li>
<li><a href="../apidocs/org/apache/commons/math/analysis/MullerSolver.html">
Muller's Method</a></li>
<li><a href="../apidocs/org/apache/commons/math/analysis/LaguerreSolver.html">
Laguerre's Method</a></li>
<li><a href="../apidocs/org/apache/commons/math/analysis/RidderSolver.html">
Ridder's Method</a></li>
</ul> </ul>
</p> </p>
<p> <p>
@ -83,9 +89,8 @@
used to create all of the solver objects supported by Commons-Math. used to create all of the solver objects supported by Commons-Math.
The typical usage of <code>UnivariateRealSolverFactory</code> The typical usage of <code>UnivariateRealSolverFactory</code>
to create a solver object would be:</p> to create a solver object would be:</p>
<source>UnivariateRealFunction function = // some user defined function object <source>UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance();
UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance(); UnivariateRealSolver solver = factory.newDefaultSolver();</source>
UnivariateRealSolver solver = factory.newDefaultSolver(function);</source>
<p> <p>
The solvers that can be instantiated via the The solvers that can be instantiated via the
<code>UnivariateRealSolverFactory</code> are detailed below: <code>UnivariateRealSolverFactory</code> are detailed below:
@ -95,6 +100,9 @@ UnivariateRealSolver solver = factory.newDefaultSolver(function);</source>
<tr><td>Brent</td><td>newBrentSolver</td><td><div>Root must be bracketted.</div><div>Super-linear, guaranteed convergence</div></td></tr> <tr><td>Brent</td><td>newBrentSolver</td><td><div>Root must be bracketted.</div><div>Super-linear, guaranteed convergence</div></td></tr>
<tr><td>Newton</td><td>newNewtonSolver</td><td><div>Uses single value for initialization.</div><div>Super-linear, non-guaranteed convergence</div><div>Function must be differentiable</div></td></tr> <tr><td>Newton</td><td>newNewtonSolver</td><td><div>Uses single value for initialization.</div><div>Super-linear, non-guaranteed convergence</div><div>Function must be differentiable</div></td></tr>
<tr><td>Secant</td><td>newSecantSolver</td><td><div>Root must be bracketted.</div><div>Super-linear, non-guaranteed convergence</div></td></tr> <tr><td>Secant</td><td>newSecantSolver</td><td><div>Root must be bracketted.</div><div>Super-linear, non-guaranteed convergence</div></td></tr>
<tr><td>Muller</td><td>newMullerSolver</td><td><div>Root must be bracketted.</div><div>We restrict ourselves to real valued functions, not complex ones</div></td></tr>
<tr><td>Laguerre</td><td>newLaguerreSolver</td><td><div>Root must be bracketted.</div><div>Function must be a polynomial</div></td></tr>
<tr><td>Ridder</td><td>newRidderSolver</td><td><div>Root must be bracketted.</div><div></div></td></tr>
</table> </table>
</p> </p>
<p> <p>
@ -111,8 +119,8 @@ UnivariateRealSolver solver = factory.newDefaultSolver(function);</source>
</p> </p>
<source>UnivariateRealFunction function = // some user defined function object <source>UnivariateRealFunction function = // some user defined function object
UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance(); UnivariateRealSolverFactory factory = UnivariateRealSolverFactory.newInstance();
UnivariateRealSolver solver = factory.newBisectionSolver(function); UnivariateRealSolver solver = factory.newBisectionSolver();
double c = solver.solve(1.0, 5.0);</source> double c = solver.solve(function, 1.0, 5.0);</source>
<p> <p>
The <code>BrentSolve</code> uses the Brent-Dekker algorithm which is The <code>BrentSolve</code> uses the Brent-Dekker algorithm which is
fast and robust. This algorithm is recommended for most users and the fast and robust. This algorithm is recommended for most users and the

View File

@ -25,10 +25,9 @@ import junit.framework.TestCase;
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public final class BisectionSolverTest extends TestCase { public final class BisectionSolverTest extends TestCase {
/**
* @Deprecated
*/ public void testDeprecated() throws MathException {
public void testSinZero() throws MathException {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
double result; double result;
@ -40,45 +39,54 @@ public final class BisectionSolverTest extends TestCase {
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy()); assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
} }
/** public void testSinZero() throws MathException {
* UnivariateRealFunction f = new SinFunction();
*/ double result;
public void testQuinticZero() throws MathException {
UnivariateRealSolver solver = new BisectionSolver();
result = solver.solve(f, 3, 4);
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
result = solver.solve(f, 1, 4);
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
}
public void testQuinticZero() throws MathException {
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealFunction f = new QuinticFunction();
double result; double result;
UnivariateRealSolver solver = new BisectionSolver(f); UnivariateRealSolver solver = new BisectionSolver();
result = solver.solve(-0.2, 0.2); result = solver.solve(f, -0.2, 0.2);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
result = solver.solve(-0.1, 0.3); result = solver.solve(f, -0.1, 0.3);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
result = solver.solve(-0.3, 0.45); result = solver.solve(f, -0.3, 0.45);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
result = solver.solve(0.3, 0.7); result = solver.solve(f, 0.3, 0.7);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
result = solver.solve(0.2, 0.6); result = solver.solve(f, 0.2, 0.6);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
result = solver.solve(0.05, 0.95); result = solver.solve(f, 0.05, 0.95);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.25); result = solver.solve(f, 0.85, 1.25);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.8, 1.2); result = solver.solve(f, 0.8, 1.2);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.75); result = solver.solve(f, 0.85, 1.75);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.55, 1.45); result = solver.solve(f, 0.55, 1.45);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.85, 5); result = solver.solve(f, 0.85, 5);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(result, solver.getResult(), 0); assertEquals(result, solver.getResult(), 0);
@ -90,8 +98,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testSetFunctionValueAccuracy(){ public void testSetFunctionValueAccuracy(){
double expected = 1.0e-2; double expected = 1.0e-2;
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealSolver solver = new BisectionSolver(f);
solver.setFunctionValueAccuracy(expected); solver.setFunctionValueAccuracy(expected);
assertEquals(expected, solver.getFunctionValueAccuracy(), 1.0e-2); assertEquals(expected, solver.getFunctionValueAccuracy(), 1.0e-2);
} }
@ -101,8 +108,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testResetFunctionValueAccuracy(){ public void testResetFunctionValueAccuracy(){
double newValue = 1.0e-2; double newValue = 1.0e-2;
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealSolver solver = new BisectionSolver(f);
double oldValue = solver.getFunctionValueAccuracy(); double oldValue = solver.getFunctionValueAccuracy();
solver.setFunctionValueAccuracy(newValue); solver.setFunctionValueAccuracy(newValue);
solver.resetFunctionValueAccuracy(); solver.resetFunctionValueAccuracy();
@ -114,8 +120,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testSetAbsoluteAccuracy(){ public void testSetAbsoluteAccuracy(){
double expected = 1.0e-2; double expected = 1.0e-2;
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealSolver solver = new BisectionSolver(f);
solver.setAbsoluteAccuracy(expected); solver.setAbsoluteAccuracy(expected);
assertEquals(expected, solver.getAbsoluteAccuracy(), 1.0e-2); assertEquals(expected, solver.getAbsoluteAccuracy(), 1.0e-2);
} }
@ -125,8 +130,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testResetAbsoluteAccuracy(){ public void testResetAbsoluteAccuracy(){
double newValue = 1.0e-2; double newValue = 1.0e-2;
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealSolver solver = new BisectionSolver(f);
double oldValue = solver.getAbsoluteAccuracy(); double oldValue = solver.getAbsoluteAccuracy();
solver.setAbsoluteAccuracy(newValue); solver.setAbsoluteAccuracy(newValue);
solver.resetAbsoluteAccuracy(); solver.resetAbsoluteAccuracy();
@ -138,9 +142,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testSetMaximalIterationCount(){ public void testSetMaximalIterationCount(){
int expected = 100; int expected = 100;
UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new BisectionSolver(f);
solver.setMaximalIterationCount(expected); solver.setMaximalIterationCount(expected);
assertEquals(expected, solver.getMaximalIterationCount()); assertEquals(expected, solver.getMaximalIterationCount());
} }
@ -150,9 +152,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testResetMaximalIterationCount(){ public void testResetMaximalIterationCount(){
int newValue = 10000; int newValue = 10000;
UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new BisectionSolver(f);
int oldValue = solver.getMaximalIterationCount(); int oldValue = solver.getMaximalIterationCount();
solver.setMaximalIterationCount(newValue); solver.setMaximalIterationCount(newValue);
solver.resetMaximalIterationCount(); solver.resetMaximalIterationCount();
@ -164,9 +164,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testSetRelativeAccuracy(){ public void testSetRelativeAccuracy(){
double expected = 1.0e-2; double expected = 1.0e-2;
UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new BisectionSolver(f);
solver.setRelativeAccuracy(expected); solver.setRelativeAccuracy(expected);
assertEquals(expected, solver.getRelativeAccuracy(), 1.0e-2); assertEquals(expected, solver.getRelativeAccuracy(), 1.0e-2);
} }
@ -176,8 +174,7 @@ public final class BisectionSolverTest extends TestCase {
*/ */
public void testResetRelativeAccuracy(){ public void testResetRelativeAccuracy(){
double newValue = 1.0e-2; double newValue = 1.0e-2;
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealSolver solver = new BisectionSolver();
UnivariateRealSolver solver = new BisectionSolver(f);
double oldValue = solver.getRelativeAccuracy(); double oldValue = solver.getRelativeAccuracy();
solver.setRelativeAccuracy(newValue); solver.setRelativeAccuracy(newValue);
solver.resetRelativeAccuracy(); solver.resetRelativeAccuracy();
@ -191,57 +188,57 @@ public final class BisectionSolverTest extends TestCase {
UnivariateRealFunction f = (UnivariateRealFunction)TestUtils.serializeAndRecover(new QuinticFunction()); UnivariateRealFunction f = (UnivariateRealFunction)TestUtils.serializeAndRecover(new QuinticFunction());
double result; double result;
BisectionSolver solver = new BisectionSolver(f); BisectionSolver solver = new BisectionSolver();
UnivariateRealSolver solver2 = (UnivariateRealSolver)TestUtils.serializeAndRecover(solver); UnivariateRealSolver solver2 = (UnivariateRealSolver)TestUtils.serializeAndRecover(solver);
result = solver.solve(-0.2, 0.2); result = solver.solve(f, -0.2, 0.2);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(-0.2, 0.2), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, -0.2, 0.2), result, solver2.getAbsoluteAccuracy());
result = solver.solve(-0.1, 0.3); result = solver.solve(f, -0.1, 0.3);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(-0.1, 0.3), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, -0.1, 0.3), result, solver2.getAbsoluteAccuracy());
result = solver.solve(-0.3, 0.45); result = solver.solve(f, -0.3, 0.45);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(-0.3, 0.45), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, -0.3, 0.45), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.3, 0.7); result = solver.solve(f, 0.3, 0.7);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.3, 0.7), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.3, 0.7), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.2, 0.6); result = solver.solve(f, 0.2, 0.6);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.2, 0.6), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.2, 0.6), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.05, 0.95); result = solver.solve(f, 0.05, 0.95);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.05, 0.95), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.05, 0.95), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.25); result = solver.solve(f, 0.85, 1.25);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.85, 1.25), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.85, 1.25), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.8, 1.2); result = solver.solve(f, 0.8, 1.2);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.8, 1.2), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.8, 1.2), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.75); result = solver.solve(f, 0.85, 1.75);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.85, 1.75), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.85, 1.75), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.55, 1.45); result = solver.solve(f, 0.55, 1.45);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.55, 1.45), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.55, 1.45), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.85, 5); result = solver.solve(f, 0.85, 5);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.85, 5), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.85, 5), result, solver2.getAbsoluteAccuracy());
/* Test Reset */ /* Test Reset */
double newValue = 1.0e-2; double newValue = 1.0e-2;
f = (UnivariateRealFunction)TestUtils.serializeAndRecover(new QuinticFunction()); f = (UnivariateRealFunction)TestUtils.serializeAndRecover(new QuinticFunction());
solver = new BisectionSolver(f); solver = new BisectionSolver();
double oldValue = solver.getRelativeAccuracy(); double oldValue = solver.getRelativeAccuracy();
solver.setRelativeAccuracy(newValue); solver.setRelativeAccuracy(newValue);

View File

@ -45,7 +45,8 @@ public final class BrentSolverTest extends TestCase {
return suite; return suite;
} }
public void testSinZero() throws MathException { @Deprecated
public void testDeprecated() throws MathException {
// The sinus function is behaved well around the root at #pi. The second // The sinus function is behaved well around the root at #pi. The second
// order derivative is zero, which means linar approximating methods will // order derivative is zero, which means linar approximating methods will
// still converge quadratically. // still converge quadratically.
@ -82,7 +83,44 @@ public final class BrentSolverTest extends TestCase {
assertEquals(result, solver.getResult(), 0); assertEquals(result, solver.getResult(), 0);
} }
public void testQuinticZero() throws MathException { 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. // 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 // Around the root of 0 the function is well behaved, with a second derivative
// of zero a 0. // of zero a 0.
@ -93,45 +131,45 @@ public final class BrentSolverTest extends TestCase {
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealFunction f = new QuinticFunction();
double result; double result;
// Brent-Dekker solver. // Brent-Dekker solver.
UnivariateRealSolver solver = new BrentSolver(f); UnivariateRealSolver solver = new BrentSolver();
// Symmetric bracket around 0. Test whether solvers can handle hitting // Symmetric bracket around 0. Test whether solvers can handle hitting
// the root in the first iteration. // the root in the first iteration.
result = solver.solve(-0.2, 0.2); result = solver.solve(f, -0.2, 0.2);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertTrue(solver.getIterationCount() <= 2); assertTrue(solver.getIterationCount() <= 2);
// 1 iterations on i586 JDK 1.4.1. // 1 iterations on i586 JDK 1.4.1.
// Asymmetric bracket around 0, just for fun. Contains extremum. // Asymmetric bracket around 0, just for fun. Contains extremum.
result = solver.solve(-0.1, 0.3); result = solver.solve(f, -0.1, 0.3);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
// 5 iterations on i586 JDK 1.4.1. // 5 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 6); assertTrue(solver.getIterationCount() <= 6);
// Large bracket around 0. Contains two extrema. // Large bracket around 0. Contains two extrema.
result = solver.solve(-0.3, 0.45); result = solver.solve(f, -0.3, 0.45);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
// 6 iterations on i586 JDK 1.4.1. // 6 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 7); assertTrue(solver.getIterationCount() <= 7);
// Benign bracket around 0.5, function is monotonous. // Benign bracket around 0.5, function is monotonous.
result = solver.solve(0.3, 0.7); result = solver.solve(f, 0.3, 0.7);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
// 6 iterations on i586 JDK 1.4.1. // 6 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 7); assertTrue(solver.getIterationCount() <= 7);
// Less benign bracket around 0.5, contains one extremum. // Less benign bracket around 0.5, contains one extremum.
result = solver.solve(0.2, 0.6); result = solver.solve(f, 0.2, 0.6);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
// 6 iterations on i586 JDK 1.4.1. // 6 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 7); assertTrue(solver.getIterationCount() <= 7);
// Large, less benign bracket around 0.5, contains both extrema. // Large, less benign bracket around 0.5, contains both extrema.
result = solver.solve(0.05, 0.95); result = solver.solve(f, 0.05, 0.95);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
@ -139,91 +177,91 @@ public final class BrentSolverTest extends TestCase {
assertTrue(solver.getIterationCount() <= 9); assertTrue(solver.getIterationCount() <= 9);
// Relatively benign bracket around 1, function is monotonous. Fast growth for x>1 // Relatively benign bracket around 1, function is monotonous. Fast growth for x>1
// is still a problem. // is still a problem.
result = solver.solve(0.85, 1.25); result = solver.solve(f, 0.85, 1.25);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 8 iterations on i586 JDK 1.4.1. // 8 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 9); assertTrue(solver.getIterationCount() <= 9);
// Less benign bracket around 1 with extremum. // Less benign bracket around 1 with extremum.
result = solver.solve(0.8, 1.2); result = solver.solve(f, 0.8, 1.2);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 8 iterations on i586 JDK 1.4.1. // 8 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 9); assertTrue(solver.getIterationCount() <= 9);
// Large bracket around 1. Monotonous. // Large bracket around 1. Monotonous.
result = solver.solve(0.85, 1.75); result = solver.solve(f, 0.85, 1.75);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 10 iterations on i586 JDK 1.4.1. // 10 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 11); assertTrue(solver.getIterationCount() <= 11);
// Large bracket around 1. Interval contains extremum. // Large bracket around 1. Interval contains extremum.
result = solver.solve(0.55, 1.45); result = solver.solve(f, 0.55, 1.45);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 7 iterations on i586 JDK 1.4.1. // 7 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 8); assertTrue(solver.getIterationCount() <= 8);
// Very large bracket around 1 for testing fast growth behaviour. // Very large bracket around 1 for testing fast growth behaviour.
result = solver.solve(0.85, 5); result = solver.solve(f, 0.85, 5);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 12 iterations on i586 JDK 1.4.1. // 12 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 13); assertTrue(solver.getIterationCount() <= 13);
// Secant solver. // Secant solver.
solver = new SecantSolver(f); solver = new SecantSolver();
result = solver.solve(-0.2, 0.2); result = solver.solve(f, -0.2, 0.2);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
// 1 iterations on i586 JDK 1.4.1. // 1 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 2); assertTrue(solver.getIterationCount() <= 2);
result = solver.solve(-0.1, 0.3); result = solver.solve(f, -0.1, 0.3);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
// 5 iterations on i586 JDK 1.4.1. // 5 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 6); assertTrue(solver.getIterationCount() <= 6);
result = solver.solve(-0.3, 0.45); result = solver.solve(f, -0.3, 0.45);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
// 6 iterations on i586 JDK 1.4.1. // 6 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 7); assertTrue(solver.getIterationCount() <= 7);
result = solver.solve(0.3, 0.7); result = solver.solve(f, 0.3, 0.7);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
// 7 iterations on i586 JDK 1.4.1. // 7 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 8); assertTrue(solver.getIterationCount() <= 8);
result = solver.solve(0.2, 0.6); result = solver.solve(f, 0.2, 0.6);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
// 6 iterations on i586 JDK 1.4.1. // 6 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 7); assertTrue(solver.getIterationCount() <= 7);
result = solver.solve(0.05, 0.95); result = solver.solve(f, 0.05, 0.95);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
// 8 iterations on i586 JDK 1.4.1. // 8 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 9); assertTrue(solver.getIterationCount() <= 9);
result = solver.solve(0.85, 1.25); result = solver.solve(f, 0.85, 1.25);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 10 iterations on i586 JDK 1.4.1. // 10 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 11); assertTrue(solver.getIterationCount() <= 11);
result = solver.solve(0.8, 1.2); result = solver.solve(f, 0.8, 1.2);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 8 iterations on i586 JDK 1.4.1. // 8 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 9); assertTrue(solver.getIterationCount() <= 9);
result = solver.solve(0.85, 1.75); result = solver.solve(f, 0.85, 1.75);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
@ -231,13 +269,13 @@ public final class BrentSolverTest extends TestCase {
assertTrue(solver.getIterationCount() <= 15); assertTrue(solver.getIterationCount() <= 15);
// The followig is especially slow because the solver first has to reduce // The followig is especially slow because the solver first has to reduce
// the bracket to exclude the extremum. After that, convergence is rapide. // the bracket to exclude the extremum. After that, convergence is rapide.
result = solver.solve(0.55, 1.45); result = solver.solve(f, 0.55, 1.45);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
// 7 iterations on i586 JDK 1.4.1. // 7 iterations on i586 JDK 1.4.1.
assertTrue(solver.getIterationCount() <= 8); assertTrue(solver.getIterationCount() <= 8);
result = solver.solve(0.85, 5); result = solver.solve(f, 0.85, 5);
//System.out.println( //System.out.println(
// "Root: " + result + " Iterations: " + solver.getIterationCount()); // "Root: " + result + " Iterations: " + solver.getIterationCount());
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
@ -270,27 +308,27 @@ public final class BrentSolverTest extends TestCase {
public void testRootEndpoints() throws Exception { public void testRootEndpoints() throws Exception {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new BrentSolver(f); UnivariateRealSolver solver = new BrentSolver();
// endpoint is root // endpoint is root
double result = solver.solve(Math.PI, 4); double result = solver.solve(f, Math.PI, 4);
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy()); assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
result = solver.solve(3, Math.PI); result = solver.solve(f, 3, Math.PI);
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy()); assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
} }
public void testBadEndpoints() throws Exception { public void testBadEndpoints() throws Exception {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new BrentSolver(f); UnivariateRealSolver solver = new BrentSolver();
try { // bad interval try { // bad interval
solver.solve(1, -1); solver.solve(f, 1, -1);
fail("Expecting IllegalArgumentException - bad interval"); fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { // no bracket try { // no bracket
solver.solve(1, 1.5); solver.solve(f, 1, 1.5);
fail("Expecting IllegalArgumentException - non-bracketing"); fail("Expecting IllegalArgumentException - non-bracketing");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
@ -300,18 +338,18 @@ public final class BrentSolverTest extends TestCase {
public void testInitialGuess() throws MathException { public void testInitialGuess() throws MathException {
MonitoredFunction f = new MonitoredFunction(new QuinticFunction()); MonitoredFunction f = new MonitoredFunction(new QuinticFunction());
UnivariateRealSolver solver = new BrentSolver(f); UnivariateRealSolver solver = new BrentSolver();
double result; double result;
// no guess // no guess
result = solver.solve(0.6, 7.0); result = solver.solve(f, 0.6, 7.0);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
int referenceCallsCount = f.getCallsCount(); int referenceCallsCount = f.getCallsCount();
assertTrue(referenceCallsCount >= 13); assertTrue(referenceCallsCount >= 13);
// invalid guess (it *is* a root, but outside of the range) // invalid guess (it *is* a root, but outside of the range)
try { try {
result = solver.solve(0.6, 7.0, 0.0); result = solver.solve(f, 0.6, 7.0, 0.0);
fail("an IllegalArgumentException was expected"); fail("an IllegalArgumentException was expected");
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
// expected behaviour // expected behaviour
@ -321,19 +359,19 @@ public final class BrentSolverTest extends TestCase {
// bad guess // bad guess
f.setCallsCount(0); f.setCallsCount(0);
result = solver.solve(0.6, 7.0, 0.61); result = solver.solve(f, 0.6, 7.0, 0.61);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertTrue(f.getCallsCount() > referenceCallsCount); assertTrue(f.getCallsCount() > referenceCallsCount);
// good guess // good guess
f.setCallsCount(0); f.setCallsCount(0);
result = solver.solve(0.6, 7.0, 0.999999); result = solver.solve(f, 0.6, 7.0, 0.999999);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertTrue(f.getCallsCount() < referenceCallsCount); assertTrue(f.getCallsCount() < referenceCallsCount);
// perfect guess // perfect guess
f.setCallsCount(0); f.setCallsCount(0);
result = solver.solve(0.6, 7.0, 1.0); result = solver.solve(f, 0.6, 7.0, 1.0);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(0, solver.getIterationCount()); assertEquals(0, solver.getIterationCount());
assertEquals(1, f.getCallsCount()); assertEquals(1, f.getCallsCount());

View File

@ -34,9 +34,10 @@ import junit.framework.TestCase;
public final class LaguerreSolverTest extends TestCase { public final class LaguerreSolverTest extends TestCase {
/** /**
* Test of solver for the linear function. * Test deprecated APIs.
*/ */
public void testLinearFunction() throws MathException { @Deprecated
public void testDeprecated() throws MathException {
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
// p(x) = 4x - 1 // p(x) = 4x - 1
@ -51,6 +52,24 @@ public final class LaguerreSolverTest extends TestCase {
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
/**
* Test of solver for the linear function.
*/
public void testLinearFunction() throws MathException {
double min, max, expected, result, tolerance;
// p(x) = 4x - 1
double coefficients[] = { -1.0, 4.0 };
PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver();
min = 0.0; max = 1.0; expected = 0.25;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance);
}
/** /**
* Test of solver for the quadratic function. * Test of solver for the quadratic function.
*/ */
@ -60,18 +79,18 @@ public final class LaguerreSolverTest extends TestCase {
// p(x) = 2x^2 + 5x - 3 = (x+3)(2x-1) // p(x) = 2x^2 + 5x - 3 = (x+3)(2x-1)
double coefficients[] = { -3.0, 5.0, 2.0 }; double coefficients[] = { -3.0, 5.0, 2.0 };
PolynomialFunction f = new PolynomialFunction(coefficients); PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f); UnivariateRealSolver solver = new LaguerreSolver();
min = 0.0; max = 2.0; expected = 0.5; min = 0.0; max = 2.0; expected = 0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -4.0; max = -1.0; expected = -3.0; min = -4.0; max = -1.0; expected = -3.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -84,24 +103,24 @@ public final class LaguerreSolverTest extends TestCase {
// p(x) = x^5 - x^4 - 12x^3 + x^2 - x - 12 = (x+1)(x+3)(x-4)(x^2-x+1) // p(x) = x^5 - x^4 - 12x^3 + x^2 - x - 12 = (x+1)(x+3)(x-4)(x^2-x+1)
double coefficients[] = { -12.0, -1.0, 1.0, -12.0, -1.0, 1.0 }; double coefficients[] = { -12.0, -1.0, 1.0, -12.0, -1.0, 1.0 };
PolynomialFunction f = new PolynomialFunction(coefficients); PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f); UnivariateRealSolver solver = new LaguerreSolver();
min = -2.0; max = 2.0; expected = -1.0; min = -2.0; max = 2.0; expected = -1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -5.0; max = -2.5; expected = -3.0; min = -5.0; max = -2.5; expected = -3.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = 3.0; max = 6.0; expected = 4.0; min = 3.0; max = 6.0; expected = 4.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -114,8 +133,7 @@ public final class LaguerreSolverTest extends TestCase {
// p(x) = x^5 + 4x^3 + x^2 + 4 = (x+1)(x^2-x+1)(x^2+4) // p(x) = x^5 + 4x^3 + x^2 + 4 = (x+1)(x^2-x+1)(x^2+4)
double coefficients[] = { 4.0, 0.0, 1.0, 4.0, 0.0, 1.0 }; double coefficients[] = { 4.0, 0.0, 1.0, 4.0, 0.0, 1.0 };
PolynomialFunction f = new PolynomialFunction(coefficients); LaguerreSolver solver = new LaguerreSolver();
LaguerreSolver solver = new LaguerreSolver(f);
result = solver.solveAll(coefficients, initial); result = solver.solveAll(coefficients, initial);
expected = new Complex(0.0, -2.0); expected = new Complex(0.0, -2.0);
@ -150,26 +168,25 @@ public final class LaguerreSolverTest extends TestCase {
public void testParameters() throws Exception { public void testParameters() throws Exception {
double coefficients[] = { -3.0, 5.0, 2.0 }; double coefficients[] = { -3.0, 5.0, 2.0 };
PolynomialFunction f = new PolynomialFunction(coefficients); PolynomialFunction f = new PolynomialFunction(coefficients);
UnivariateRealSolver solver = new LaguerreSolver(f); UnivariateRealSolver solver = new LaguerreSolver();
try { try {
// bad interval // bad interval
solver.solve(1, -1); solver.solve(f, 1, -1);
fail("Expecting IllegalArgumentException - bad interval"); fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
// no bracketing // no bracketing
solver.solve(2, 3); solver.solve(f, 2, 3);
fail("Expecting IllegalArgumentException - no bracketing"); fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
// bad function // bad function
UnivariateRealFunction f2 = new SinFunction(); solver.solve(new SinFunction(), -1, 1);
new LaguerreSolver(f2);
fail("Expecting IllegalArgumentException - bad function"); fail("Expecting IllegalArgumentException - bad function");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected

View File

@ -35,9 +35,10 @@ import junit.framework.TestCase;
public final class MullerSolverTest extends TestCase { public final class MullerSolverTest extends TestCase {
/** /**
* Test of solver for the sine function. * Test deprecated APIs.
*/ */
public void testSinFunction() throws MathException { @Deprecated
public void testDeprecated() throws MathException {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver(f); UnivariateRealSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
@ -55,24 +56,73 @@ public final class MullerSolverTest extends TestCase {
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
/**
* Test deprecated APIs.
*/
@Deprecated
public void testDeprecated2() throws MathException {
UnivariateRealFunction f = new QuinticFunction();
MullerSolver solver = new MullerSolver(f);
double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max);
assertEquals(expected, result, tolerance);
}
/**
* Test of solver for the sine function.
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver();
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance);
}
/** /**
* Test of solver for the sine function using solve2(). * Test of solver for the sine function using solve2().
*/ */
public void testSinFunction2() throws MathException { public void testSinFunction2() throws MathException {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
MullerSolver solver = new MullerSolver(f); MullerSolver solver = new MullerSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI; min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0; min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -81,25 +131,25 @@ public final class MullerSolverTest extends TestCase {
*/ */
public void testQuinticFunction() throws MathException { public void testQuinticFunction() throws MathException {
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new MullerSolver(f); UnivariateRealSolver solver = new MullerSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0; min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0; min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5; min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -108,25 +158,25 @@ public final class MullerSolverTest extends TestCase {
*/ */
public void testQuinticFunction2() throws MathException { public void testQuinticFunction2() throws MathException {
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealFunction f = new QuinticFunction();
MullerSolver solver = new MullerSolver(f); MullerSolver solver = new MullerSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0; min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0; min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5; min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -139,25 +189,25 @@ public final class MullerSolverTest extends TestCase {
*/ */
public void testExpm1Function() throws MathException { public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function(); UnivariateRealFunction f = new Expm1Function();
UnivariateRealSolver solver = new MullerSolver(f); UnivariateRealSolver solver = new MullerSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0; min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0; min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0; min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -168,25 +218,25 @@ public final class MullerSolverTest extends TestCase {
*/ */
public void testExpm1Function2() throws MathException { public void testExpm1Function2() throws MathException {
UnivariateRealFunction f = new Expm1Function(); UnivariateRealFunction f = new Expm1Function();
MullerSolver solver = new MullerSolver(f); MullerSolver solver = new MullerSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0; min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0; min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0; min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve2(min, max); result = solver.solve2(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -195,18 +245,18 @@ public final class MullerSolverTest extends TestCase {
*/ */
public void testParameters() throws Exception { public void testParameters() throws Exception {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new MullerSolver(f); UnivariateRealSolver solver = new MullerSolver();
try { try {
// bad interval // bad interval
solver.solve(1, -1); solver.solve(f, 1, -1);
fail("Expecting IllegalArgumentException - bad interval"); fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
// no bracketing // no bracketing
solver.solve(2, 3); solver.solve(f, 2, 3);
fail("Expecting IllegalArgumentException - no bracketing"); fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected

View File

@ -26,10 +26,9 @@ import junit.framework.TestCase;
* @version $Revision$ $Date$ * @version $Revision$ $Date$
*/ */
public final class NewtonSolverTest extends TestCase { public final class NewtonSolverTest extends TestCase {
/**
* @Deprecated
*/ public void testDeprecated() throws MathException {
public void testSinZero() throws MathException {
DifferentiableUnivariateRealFunction f = new SinFunction(); DifferentiableUnivariateRealFunction f = new SinFunction();
double result; double result;
@ -46,44 +45,63 @@ public final class NewtonSolverTest extends TestCase {
} }
/** /**
*
*/
public void testSinZero() throws MathException {
DifferentiableUnivariateRealFunction f = new SinFunction();
double result;
UnivariateRealSolver solver = new NewtonSolver();
result = solver.solve(f, 3, 4);
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
result = solver.solve(f, 1, 4);
assertEquals(result, Math.PI, solver.getAbsoluteAccuracy());
//TODO: create abstract solver test class, move these there
assertEquals(result, solver.getResult(), 0);
assertTrue(solver.getIterationCount() > 0);
}
/**
* *
*/ */
public void testQuinticZero() throws MathException { public void testQuinticZero() throws MathException {
DifferentiableUnivariateRealFunction f = new QuinticFunction(); DifferentiableUnivariateRealFunction f = new QuinticFunction();
double result; double result;
UnivariateRealSolver solver = new BisectionSolver(f); UnivariateRealSolver solver = new NewtonSolver();
result = solver.solve(-0.2, 0.2); result = solver.solve(f, -0.2, 0.2);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
result = solver.solve(-0.1, 0.3); result = solver.solve(f, -0.1, 0.3);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
result = solver.solve(-0.3, 0.45); result = solver.solve(f, -0.3, 0.45);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
result = solver.solve(0.3, 0.7); result = solver.solve(f, 0.3, 0.7);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
result = solver.solve(0.2, 0.6); result = solver.solve(f, 0.2, 0.6);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
result = solver.solve(0.05, 0.95); result = solver.solve(f, 0.05, 0.95);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.25); result = solver.solve(f, 0.85, 1.25);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.8, 1.2); result = solver.solve(f, 0.8, 1.2);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.75); result = solver.solve(f, 0.85, 1.75);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.55, 1.45); result = solver.solve(f, 0.55, 1.45);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
result = solver.solve(0.85, 5); result = solver.solve(f, 0.85, 5);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
} }
@ -94,57 +112,57 @@ public final class NewtonSolverTest extends TestCase {
DifferentiableUnivariateRealFunction f = new QuinticFunction(); DifferentiableUnivariateRealFunction f = new QuinticFunction();
double result; double result;
NewtonSolver solver = new NewtonSolver(f); NewtonSolver solver = new NewtonSolver();
NewtonSolver solver2 = (NewtonSolver)TestUtils.serializeAndRecover(solver); NewtonSolver solver2 = (NewtonSolver)TestUtils.serializeAndRecover(solver);
result = solver.solve(-0.2, 0.2); result = solver.solve(f, -0.2, 0.2);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(-0.2, 0.2), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, -0.2, 0.2), result, solver2.getAbsoluteAccuracy());
result = solver.solve(-0.1, 0.3); result = solver.solve(f, -0.1, 0.3);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(-0.1, 0.3), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, -0.1, 0.3), result, solver2.getAbsoluteAccuracy());
result = solver.solve(-0.3, 0.45); result = solver.solve(f, -0.3, 0.45);
assertEquals(result, 0, solver.getAbsoluteAccuracy()); assertEquals(result, 0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(-0.3, 0.45), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, -0.3, 0.45), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.3, 0.7); result = solver.solve(f, 0.3, 0.7);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.3, 0.7), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.3, 0.7), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.2, 0.6); result = solver.solve(f, 0.2, 0.6);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.2, 0.6), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.2, 0.6), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.05, 0.95); result = solver.solve(f, 0.05, 0.95);
assertEquals(result, 0.5, solver.getAbsoluteAccuracy()); assertEquals(result, 0.5, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.05, 0.95), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.05, 0.95), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.25); result = solver.solve(f, 0.85, 1.25);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.85, 1.25), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.85, 1.25), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.8, 1.2); result = solver.solve(f, 0.8, 1.2);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.8, 1.2), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.8, 1.2), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.85, 1.75); result = solver.solve(f, 0.85, 1.75);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.85, 1.75), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.85, 1.75), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.55, 1.45); result = solver.solve(f, 0.55, 1.45);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.55, 1.45), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.55, 1.45), result, solver2.getAbsoluteAccuracy());
result = solver.solve(0.85, 5); result = solver.solve(f, 0.85, 5);
assertEquals(result, 1.0, solver.getAbsoluteAccuracy()); assertEquals(result, 1.0, solver.getAbsoluteAccuracy());
assertEquals(solver2.solve(0.85, 5), result, solver2.getAbsoluteAccuracy()); assertEquals(solver2.solve(f, 0.85, 5), result, solver2.getAbsoluteAccuracy());
/* Test Reset */ /* Test Reset */
double newValue = 1.0e-2; double newValue = 1.0e-2;
f = new QuinticFunction(); f = new QuinticFunction();
solver = new NewtonSolver(f); solver = new NewtonSolver();
double oldValue = solver.getRelativeAccuracy(); double oldValue = solver.getRelativeAccuracy();
solver.setRelativeAccuracy(newValue); solver.setRelativeAccuracy(newValue);

View File

@ -33,9 +33,10 @@ import junit.framework.TestCase;
public final class RiddersSolverTest extends TestCase { public final class RiddersSolverTest extends TestCase {
/** /**
* Test of solver for the sine function. * Test the deprecated APIs.
*/ */
public void testSinFunction() throws MathException { @Deprecated
public void testDeprecated() throws MathException {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver(f); UnivariateRealSolver solver = new RiddersSolver(f);
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
@ -53,30 +54,51 @@ public final class RiddersSolverTest extends TestCase {
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
/**
* Test of solver for the sine function.
*/
public void testSinFunction() throws MathException {
UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver();
double min, max, expected, result, tolerance;
min = 3.0; max = 4.0; expected = Math.PI;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance);
min = -1.0; max = 1.5; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance);
}
/** /**
* Test of solver for the quintic function. * Test of solver for the quintic function.
*/ */
public void testQuinticFunction() throws MathException { public void testQuinticFunction() throws MathException {
UnivariateRealFunction f = new QuinticFunction(); UnivariateRealFunction f = new QuinticFunction();
UnivariateRealSolver solver = new RiddersSolver(f); UnivariateRealSolver solver = new RiddersSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = -0.4; max = 0.2; expected = 0.0; min = -0.4; max = 0.2; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = 0.75; max = 1.5; expected = 1.0; min = 0.75; max = 1.5; expected = 1.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -0.9; max = -0.2; expected = -0.5; min = -0.9; max = -0.2; expected = -0.5;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -85,25 +107,25 @@ public final class RiddersSolverTest extends TestCase {
*/ */
public void testExpm1Function() throws MathException { public void testExpm1Function() throws MathException {
UnivariateRealFunction f = new Expm1Function(); UnivariateRealFunction f = new Expm1Function();
UnivariateRealSolver solver = new RiddersSolver(f); UnivariateRealSolver solver = new RiddersSolver();
double min, max, expected, result, tolerance; double min, max, expected, result, tolerance;
min = -1.0; max = 2.0; expected = 0.0; min = -1.0; max = 2.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -20.0; max = 10.0; expected = 0.0; min = -20.0; max = 10.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
min = -50.0; max = 100.0; expected = 0.0; min = -50.0; max = 100.0; expected = 0.0;
tolerance = Math.max(solver.getAbsoluteAccuracy(), tolerance = Math.max(solver.getAbsoluteAccuracy(),
Math.abs(expected * solver.getRelativeAccuracy())); Math.abs(expected * solver.getRelativeAccuracy()));
result = solver.solve(min, max); result = solver.solve(f, min, max);
assertEquals(expected, result, tolerance); assertEquals(expected, result, tolerance);
} }
@ -112,18 +134,18 @@ public final class RiddersSolverTest extends TestCase {
*/ */
public void testParameters() throws Exception { public void testParameters() throws Exception {
UnivariateRealFunction f = new SinFunction(); UnivariateRealFunction f = new SinFunction();
UnivariateRealSolver solver = new RiddersSolver(f); UnivariateRealSolver solver = new RiddersSolver();
try { try {
// bad interval // bad interval
solver.solve(1, -1); solver.solve(f, 1, -1);
fail("Expecting IllegalArgumentException - bad interval"); fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected
} }
try { try {
// no bracketing // no bracketing
solver.solve(2, 3); solver.solve(f, 2, 3);
fail("Expecting IllegalArgumentException - no bracketing"); fail("Expecting IllegalArgumentException - no bracketing");
} catch (IllegalArgumentException ex) { } catch (IllegalArgumentException ex) {
// expected // expected

View File

@ -28,8 +28,6 @@ public class UnivariateRealSolverFactoryImplTest extends TestCase {
/** solver factory */ /** solver factory */
private UnivariateRealSolverFactory factory; private UnivariateRealSolverFactory factory;
/** function */
private DifferentiableUnivariateRealFunction function;
/** /**
* @throws java.lang.Exception * @throws java.lang.Exception
* @see junit.framework.TestCase#tearDown() * @see junit.framework.TestCase#tearDown()
@ -37,7 +35,6 @@ public class UnivariateRealSolverFactoryImplTest extends TestCase {
protected void setUp() throws Exception { protected void setUp() throws Exception {
super.setUp(); super.setUp();
factory = new UnivariateRealSolverFactoryImpl(); factory = new UnivariateRealSolverFactoryImpl();
function = new SinFunction();
} }
/** /**
@ -46,67 +43,31 @@ public class UnivariateRealSolverFactoryImplTest extends TestCase {
*/ */
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
factory = null; factory = null;
function = null;
super.tearDown(); super.tearDown();
} }
public void testNewBisectionSolverNull() {
try {
factory.newBisectionSolver(null);
fail();
} catch(IllegalArgumentException ex) {
// success
}
}
public void testNewBisectionSolverValid() { public void testNewBisectionSolverValid() {
UnivariateRealSolver solver = factory.newBisectionSolver(function); UnivariateRealSolver solver = factory.newBisectionSolver();
assertNotNull(solver); assertNotNull(solver);
assertTrue(solver instanceof BisectionSolver); assertTrue(solver instanceof BisectionSolver);
} }
public void testNewNewtonSolverNull() {
try {
factory.newNewtonSolver(null);
fail();
} catch(IllegalArgumentException ex) {
// success
}
}
public void testNewNewtonSolverValid() { public void testNewNewtonSolverValid() {
UnivariateRealSolver solver = factory.newNewtonSolver(function); UnivariateRealSolver solver = factory.newNewtonSolver();
assertNotNull(solver); assertNotNull(solver);
assertTrue(solver instanceof NewtonSolver); assertTrue(solver instanceof NewtonSolver);
} }
public void testNewBrentSolverNull() {
try {
factory.newBrentSolver(null);
fail();
} catch(IllegalArgumentException ex) {
// success
}
}
public void testNewBrentSolverValid() { public void testNewBrentSolverValid() {
UnivariateRealSolver solver = factory.newBrentSolver(function); UnivariateRealSolver solver = factory.newBrentSolver();
assertNotNull(solver); assertNotNull(solver);
assertTrue(solver instanceof BrentSolver); assertTrue(solver instanceof BrentSolver);
} }
public void testNewSecantSolverNull() {
try {
factory.newSecantSolver(null);
fail();
} catch(IllegalArgumentException ex) {
// success
}
}
public void testNewSecantSolverValid() { public void testNewSecantSolverValid() {
UnivariateRealSolver solver = factory.newSecantSolver(function); UnivariateRealSolver solver = factory.newSecantSolver();
assertNotNull(solver); assertNotNull(solver);
assertTrue(solver instanceof SecantSolver); assertTrue(solver instanceof SecantSolver);
} }
} }