Created an unchecked "FunctionEvaluationException" in package "exception".
Removed "throws" clause from interface "UnivariateRealFunction".
"PolynomialFunctionLagrangeForm": Added early check on the interpolating
array having distinct points; removed redundant test in methods "evaluate"
and "computeCoefficients".
"DividedDifferenceInerpolator": Removed redundant check.
"Mathutils": Added method "sortInPlace". Removed (most) references to the
deprecated "MathRuntimeException" class.
"optimization.direct": Removed deprecated classes.
Javadoc clean up.



git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1030464 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2010-11-03 13:46:04 +00:00
parent 826fc64e96
commit 634e51b50e
112 changed files with 800 additions and 1820 deletions

View File

@ -22,6 +22,8 @@ package org.apache.commons.math;
*
* @since 1.2
* @version $Revision$ $Date$
* @deprecated in 2.2 (to be removed in 3.0). Please use
* {@link org.apache.commons.math.exception.OutOfRangeException} instead.
*/
public class ArgumentOutsideDomainException extends FunctionEvaluationException {

View File

@ -23,6 +23,7 @@ import org.apache.commons.math.exception.util.LocalizedFormats;
*
* @since 1.2
* @version $Revision$ $Date$
* @deprecated in 2.2 (to be removed in 3.0).
*/
public class DuplicateSampleAbscissaException extends MathException {

View File

@ -28,6 +28,8 @@ import org.apache.commons.math.linear.ArrayRealVector;
* caused the function evaluation to fail.
*
* @version $Revision$ $Date$
* @deprecated in 2.2 (to be removed in 3.0). Please use
* {@link org.apache.commons.math.exception.FunctionEvaluationException} instead.
*/
public class FunctionEvaluationException extends MathException {

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a bivariate real function.

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;

View File

@ -18,7 +18,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a multivariate matrix function.

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a multivariate real function.

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a multivariate vectorial function.

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a trivariate real function.

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a univariate matrix function.

View File

@ -16,21 +16,17 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
/**
* An interface representing a univariate real function.
*
* @version $Revision$ $Date$
*/
public interface UnivariateRealFunction {
/**
* Compute the value for the function.
* @param x the point for which the function value should be computed
* @return the value
* @throws FunctionEvaluationException if the function evaluation fails
* Compute the value of the function.
*
* @param x Point at which the function value should be computed.
* @return the value.
*/
double value(double x) throws FunctionEvaluationException;
double value(double x);
}

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a univariate vectorial function.

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -18,7 +18,7 @@ package org.apache.commons.math.analysis.integration;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.ConvergingAlgorithm;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
/**

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.interpolation;
import org.apache.commons.math.DimensionMismatchException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.BivariateRealFunction;
import org.apache.commons.math.exception.NoDataException;
import org.apache.commons.math.exception.OutOfRangeException;

View File

@ -17,8 +17,6 @@
package org.apache.commons.math.analysis.interpolation;
import java.io.Serializable;
import org.apache.commons.math.DuplicateSampleAbscissaException;
import org.apache.commons.math.analysis.polynomials.PolynomialFunctionLagrangeForm;
import org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm;
@ -35,29 +33,31 @@ import org.apache.commons.math.analysis.polynomials.PolynomialFunctionNewtonForm
* @version $Revision$ $Date$
* @since 1.2
*/
public class DividedDifferenceInterpolator implements UnivariateRealInterpolator,
Serializable {
public class DividedDifferenceInterpolator
implements UnivariateRealInterpolator, Serializable {
/** serializable version identifier */
private static final long serialVersionUID = 107049519551235069L;
/**
* Computes an interpolating function for the data set.
* Compute an interpolating function for the dataset.
*
* @param x the interpolating points array
* @param y the interpolating values array
* @return a function which interpolates the data set
* @throws DuplicateSampleAbscissaException if arguments are invalid
* @param x Interpolating points array.
* @param y Interpolating values array.
* @return a function which interpolates the dataset.
* @throws org.apache.commons.math.exception.DimensionMismatchException
* if the array lengths are different.
* @throws org.apache.commons.math.exception.NumberIsTooSmallException
* if the number of points is less than 2.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException
* if {@code x} is not sorted in strictly increasing order.
*/
public PolynomialFunctionNewtonForm interpolate(double x[], double y[]) throws
DuplicateSampleAbscissaException {
public PolynomialFunctionNewtonForm interpolate(double x[], double y[]) {
/**
* a[] and c[] are defined in the general formula of Newton form:
* p(x) = a[0] + a[1](x-c[0]) + a[2](x-c[0])(x-c[1]) + ... +
* a[n](x-c[0])(x-c[1])...(x-c[n-1])
*/
PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y);
PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y, true);
/**
* When used for interpolation, the Newton form formula becomes
@ -72,11 +72,10 @@ public class DividedDifferenceInterpolator implements UnivariateRealInterpolator
final double[] a = computeDividedDifference(x, y);
return new PolynomialFunctionNewtonForm(a, c);
}
/**
* Returns a copy of the divided difference array.
* Return a copy of the divided difference array.
* <p>
* The divided difference array is defined recursively by <pre>
* f[x0] = f(x0)
@ -85,15 +84,18 @@ public class DividedDifferenceInterpolator implements UnivariateRealInterpolator
* <p>
* The computational complexity is O(N^2).</p>
*
* @param x the interpolating points array
* @param y the interpolating values array
* @return a fresh copy of the divided difference array
* @throws DuplicateSampleAbscissaException if any abscissas coincide
* @param x Interpolating points array.
* @param y Interpolating values array.
* @return a fresh copy of the divided difference array.
* @throws org.apache.commons.math.exception.DimensionMismatchException
* if the array lengths are different.
* @throws org.apache.commons.math.exception.NumberIsTooSmallException
* if the number of points is less than 2.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException
* if {@code x} is not sorted in strictly increasing order.
*/
protected static double[] computeDividedDifference(final double x[], final double y[])
throws DuplicateSampleAbscissaException {
PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y);
protected static double[] computeDividedDifference(final double x[], final double y[]) {
PolynomialFunctionLagrangeForm.verifyInterpolationArray(x, y, true);
final double[] divdiff = y.clone(); // initialization
@ -103,10 +105,6 @@ public class DividedDifferenceInterpolator implements UnivariateRealInterpolator
for (int i = 1; i < n; i++) {
for (int j = 0; j < n-i; j++) {
final double denominator = x[j+i] - x[j];
if (denominator == 0.0) {
// This happens only when two abscissas are identical.
throw new DuplicateSampleAbscissaException(x[j], j, j+i);
}
divdiff[j] = (divdiff[j+1] - divdiff[j]) / denominator;
}
a[i] = divdiff[0];

View File

@ -16,12 +16,12 @@
*/
package org.apache.commons.math.analysis.polynomials;
import org.apache.commons.math.DuplicateSampleAbscissaException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.util.MathUtils;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.NumberIsTooSmallException;
import org.apache.commons.math.exception.util.LocalizedFormats;
/**
* Implements the representation of a real polynomial function in
@ -36,24 +36,20 @@ import org.apache.commons.math.util.FastMath;
* @since 1.2
*/
public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
/**
* The coefficients of the polynomial, ordered by degree -- i.e.
* coefficients[0] is the constant term and coefficients[n] is the
* coefficient of x^n where n is the degree of the polynomial.
*/
private double coefficients[];
/**
* Interpolating points (abscissas).
*/
private final double x[];
/**
* Function values at interpolating points.
*/
private final double y[];
/**
* Whether the polynomial coefficients are available.
*/
@ -69,31 +65,34 @@ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
* @param y function values at interpolating points
* @throws IllegalArgumentException if input arrays are not valid
*/
public PolynomialFunctionLagrangeForm(double x[], double y[])
throws IllegalArgumentException {
verifyInterpolationArray(x, y);
public PolynomialFunctionLagrangeForm(double x[], double y[]) {
this.x = new double[x.length];
this.y = new double[y.length];
System.arraycopy(x, 0, this.x, 0, x.length);
System.arraycopy(y, 0, this.y, 0, y.length);
coefficientsComputed = false;
if (!verifyInterpolationArray(x, y, false)) {
MathUtils.sortInPlace(this.x, this.y);
// Second check in case some abscissa is duplicated.
verifyInterpolationArray(this.x, this.y, true);
}
}
/**
* Calculate the function value at the given point.
*
* @param z the point at which the function value is to be computed
* @return the function value
* @throws FunctionEvaluationException if a runtime error occurs
* @see UnivariateRealFunction#value(double)
* @param z Point at which the function value is to be computed.
* @return the function value.
* @throws DimensionMismatchException if {@code x} and {@code y} have
* different lengths.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException
* if {@code x} is not sorted in strictly increasing order.
* @throws NumberIsTooSmallException if the size of {@code x} is less
* than 2.
*/
public double value(double z) throws FunctionEvaluationException {
try {
return evaluate(x, y, z);
} catch (DuplicateSampleAbscissaException e) {
throw new FunctionEvaluationException(e, z, e.getLocalizablePattern(), e.getArguments());
}
public double value(double z) {
return evaluateInternal(x, y, z);
}
/**
@ -153,23 +152,53 @@ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
/**
* Evaluate the Lagrange polynomial using
* <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html">
* Neville's Algorithm</a>. It takes O(N^2) time.
* <p>
* This function is made public static so that users can call it directly
* without instantiating PolynomialFunctionLagrangeForm object.</p>
* Neville's Algorithm</a>. It takes O(n^2) time.
*
* @param x the interpolating points array
* @param y the interpolating values array
* @param z the point at which the function value is to be computed
* @return the function value
* @throws DuplicateSampleAbscissaException if the sample has duplicate abscissas
* @throws IllegalArgumentException if inputs are not valid
* @param x Interpolating points array.
* @param y Interpolating values array.
* @param z Point at which the function value is to be computed.
* @return the function value.
* @throws DimensionMismatchException if {@code x} and {@code y} have
* different lengths.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException
* if {@code x} is not sorted in strictly increasing order.
* @throws NumberIsTooSmallException if the size of {@code x} is less
* than 2.
*/
public static double evaluate(double x[], double y[], double z) throws
DuplicateSampleAbscissaException, IllegalArgumentException {
public static double evaluate(double x[], double y[], double z) {
if (verifyInterpolationArray(x, y, false)) {
return evaluateInternal(x, y, z);
}
verifyInterpolationArray(x, y);
// Array is not sorted.
final double[] xNew = new double[x.length];
final double[] yNew = new double[y.length];
System.arraycopy(x, 0, xNew, 0, x.length);
System.arraycopy(y, 0, yNew, 0, y.length);
MathUtils.sortInPlace(xNew, yNew);
// Second check in case some abscissa is duplicated.
verifyInterpolationArray(xNew, yNew, true);
return evaluateInternal(xNew, yNew, z);
}
/**
* Evaluate the Lagrange polynomial using
* <a href="http://mathworld.wolfram.com/NevillesAlgorithm.html">
* Neville's Algorithm</a>. It takes O(n^2) time.
*
* @param x Interpolating points array.
* @param y Interpolating values array.
* @param z Point at which the function value is to be computed.
* @return the function value.
* @throws DimensionMismatchException if {@code x} and {@code y} have
* different lengths.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException
* if {@code x} is not sorted in strictly increasing order.
* @throws NumberIsTooSmallException if the size of {@code x} is less
* than 2.
*/
private static double evaluateInternal(double x[], double y[], double z) {
int nearest = 0;
final int n = x.length;
final double[] c = new double[n];
@ -195,10 +224,6 @@ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
final double tc = x[j] - z;
final double td = x[i+j] - z;
final double divider = x[j] - x[i+j];
if (divider == 0.0) {
// This happens only when two abscissas are identical.
throw new DuplicateSampleAbscissaException(x[i], i, i+j);
}
// update the difference arrays
final double w = (c[j+1] - d[j]) / divider;
c[j] = tc * w;
@ -218,15 +243,11 @@ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
/**
* Calculate the coefficients of Lagrange polynomial from the
* interpolation data. It takes O(N^2) time.
* <p>
* Note this computation can be ill-conditioned. Use with caution
* and only when it is necessary.</p>
*
* @throws ArithmeticException if any abscissas coincide
* interpolation data. It takes O(n^2) time.
* Note that this computation can be ill-conditioned: Use with caution
* and only when it is necessary.
*/
protected void computeCoefficients() throws ArithmeticException {
protected void computeCoefficients() {
final int n = degree() + 1;
coefficients = new double[n];
for (int i = 0; i < n; i++) {
@ -253,16 +274,6 @@ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
d *= x[i] - x[j];
}
}
if (d == 0.0) {
// This happens only when two abscissas are identical.
for (int k = 0; k < n; ++k) {
if ((i != k) && (x[i] == x[k])) {
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.IDENTICAL_ABSCISSAS_DIVISION_BY_ZERO,
i, k, x[i]);
}
}
}
final double t = y[i] / d;
// Lagrange polynomial is the sum of n terms, each of which is a
// polynomial of degree n-1. tc[] are the coefficients of the i-th
@ -279,34 +290,31 @@ public class PolynomialFunctionLagrangeForm implements UnivariateRealFunction {
}
/**
* Verifies that the interpolation arrays are valid.
* <p>
* Check that the interpolation arrays are valid.
* The arrays features checked by this method are that both arrays have the
* same length and this length is at least 2.
* </p>
* <p>
* The interpolating points must be distinct. However it is not
* verified here, it is checked in evaluate() and computeCoefficients().
* </p>
*
* @param x the interpolating points array
* @param y the interpolating values array
* @throws IllegalArgumentException if not valid
* @param x Interpolating points array.
* @param y Interpolating values array.
* @param abort Whether to throw an exception if {@code x} is not sorted.
* @throws DimensionMismatchException if the array lengths are different.
* @throws NumberIsTooSmallException if the number of points is less than 2.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException
* if {@code x} is not sorted in strictly increasing order and {@code abort}
* is {@code true}.
* @return {@code false} if the {@code x} is not sorted in increasing order,
* {@code true} otherwise.
* @see #evaluate(double[], double[], double)
* @see #computeCoefficients()
*/
public static void verifyInterpolationArray(double x[], double y[])
throws IllegalArgumentException {
public static boolean verifyInterpolationArray(double x[], double y[], boolean abort) {
if (x.length != y.length) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.DIMENSIONS_MISMATCH_SIMPLE, x.length, y.length);
throw new DimensionMismatchException(x.length, y.length);
}
if (x.length < 2) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2, x.length);
throw new NumberIsTooSmallException(LocalizedFormats.WRONG_NUMBER_OF_POINTS, 2, x.length, true);
}
return MathUtils.checkOrder(x, MathUtils.OrderDirection.INCREASING, true, abort);
}
}

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis.polynomials;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;

View File

@ -18,10 +18,13 @@ package org.apache.commons.math.analysis.polynomials;
import java.util.Arrays;
import org.apache.commons.math.ArgumentOutsideDomainException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.util.MathUtils;
import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.OutOfRangeException;
import org.apache.commons.math.exception.NumberIsTooSmallException;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.exception.util.LocalizedFormats;
/**
@ -58,24 +61,23 @@ import org.apache.commons.math.exception.util.LocalizedFormats;
*
* @version $Revision$ $Date$
*/
public class PolynomialSplineFunction
implements DifferentiableUnivariateRealFunction {
/** Spline segment interval delimiters (knots). Size is n+1 for n segments. */
public class PolynomialSplineFunction implements DifferentiableUnivariateRealFunction {
/**
* Spline segment interval delimiters (knots).
* Size is n + 1 for n segments.
*/
private final double knots[];
/**
* The polynomial functions that make up the spline. The first element
* determines the value of the spline over the first subinterval, the
* second over the second, etc. Spline function values are determined by
* evaluating these functions at <code>(x - knot[i])</code> where i is the
* evaluating these functions at {@code (x - knot[i])} where i is the
* knot segment to which x belongs.
*/
private final PolynomialFunction polynomials[];
/**
* Number of spline segments = number of polynomials
* = number of partition points - 1
* Number of spline segments. It is equal to the number of polynomials and
* to the number of partition points - 1.
*/
private final int n;
@ -83,33 +85,31 @@ public class PolynomialSplineFunction
/**
* Construct a polynomial spline function with the given segment delimiters
* and interpolating polynomials.
* <p>
* The constructor copies both arrays and assigns the copies to the knots
* and polynomials properties, respectively.</p>
* and polynomials properties, respectively.
*
* @param knots spline segment interval delimiters
* @param polynomials polynomial functions that make up the spline
* @throws NullPointerException if either of the input arrays is null
* @throws IllegalArgumentException if knots has length less than 2,
* <code>polynomials.length != knots.length - 1 </code>, or the knots array
* is not strictly increasing.
* @param knots Spline segment interval delimiters.
* @param polynomials Polynomial functions that make up the spline.
* @throws NullArgumentException if either of the input arrays is {@code null}.
* @throws NumberIsTooSmallException if knots has length less than 2.
* @throws DimensionMismatchException if {@code polynomials.length != knots.length - 1}.
* @throws org.apache.commons.math.exception.NonMonotonousSequenceException if
* the {@code knots} array is not strictly increasing.
*
*/
public PolynomialSplineFunction(double knots[], PolynomialFunction polynomials[]) {
if (knots == null ||
polynomials == null) {
throw new NullArgumentException();
}
if (knots.length < 2) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION,
2, knots.length);
throw new NumberIsTooSmallException(LocalizedFormats.NOT_ENOUGH_POINTS_IN_SPLINE_PARTITION,
2, knots.length, false);
}
if (knots.length - 1 != polynomials.length) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POLYNOMIAL_INTERPOLANTS_MISMATCH_SEGMENTS,
polynomials.length, knots.length);
}
if (!isStrictlyIncreasing(knots)) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.NOT_STRICTLY_INCREASING_KNOT_VALUES);
throw new DimensionMismatchException(polynomials.length, knots.length);
}
MathUtils.checkOrder(knots);
this.n = knots.length -1;
this.knots = new double[n + 1];
@ -120,30 +120,26 @@ public class PolynomialSplineFunction
/**
* Compute the value for the function.
* <p>
* Throws FunctionEvaluationException if v is outside of the domain of the
* function. The domain is [smallest knot, largest knot].</p>
* <p>
* See {@link PolynomialSplineFunction} for details on the algorithm for
* computing the value of the function.</p>
* computing the value of the function.
*
* @param v the point for which the function value should be computed
* @return the value
* @throws ArgumentOutsideDomainException if v is outside of the domain of
* of the spline function (less than the smallest knot point or greater
* than the largest knot point)
* @param v Point for which the function value should be computed.
* @return the value.
* @throws OutOfRangeException if {@code v} is outside of the domain of the
* spline function (smaller than the smallest knot point or larger than the
* largest knot point).
*/
public double value(double v) throws ArgumentOutsideDomainException {
public double value(double v) {
if (v < knots[0] || v > knots[n]) {
throw new ArgumentOutsideDomainException(v, knots[0], knots[n]);
throw new OutOfRangeException(v, knots[0], knots[n]);
}
int i = Arrays.binarySearch(knots, v);
if (i < 0) {
i = -i - 2;
}
//This will handle the case where v is the last knot value
//There are only n-1 polynomials, so if v is the last knot
//then we will use the last polynomial to calculate the value.
// This will handle the case where v is the last knot value
// There are only n-1 polynomials, so if v is the last knot
// then we will use the last polynomial to calculate the value.
if ( i >= polynomials.length ) {
i--;
}
@ -151,17 +147,18 @@ public class PolynomialSplineFunction
}
/**
* Returns the derivative of the polynomial spline function as a UnivariateRealFunction
* @return the derivative function
* Get the derivative of the polynomial spline function.
*
* @return the derivative function.
*/
public UnivariateRealFunction derivative() {
return polynomialSplineDerivative();
}
/**
* Returns the derivative of the polynomial spline function as a PolynomialSplineFunction
* Get the derivative of the polynomial spline function.
*
* @return the derivative function
* @return the derivative function.
*/
public PolynomialSplineFunction polynomialSplineDerivative() {
PolynomialFunction derivativePolynomials[] = new PolynomialFunction[n];
@ -172,22 +169,21 @@ public class PolynomialSplineFunction
}
/**
* Returns the number of spline segments = the number of polynomials
* = the number of knot points - 1.
* Get the number of spline segments.
* It is also the number of polynomials and the number of knot points - 1.
*
* @return the number of spline segments
* @return the number of spline segments.
*/
public int getN() {
return n;
}
/**
* Returns a copy of the interpolating polynomials array.
* <p>
* Returns a fresh copy of the array. Changes made to the copy will
* not affect the polynomials property.</p>
* Get a copy of the interpolating polynomials array.
* It returns a fresh copy of the array. Changes made to the copy will
* not affect the polynomials property.
*
* @return the interpolating polynomials
* @return the interpolating polynomials.
*/
public PolynomialFunction[] getPolynomials() {
PolynomialFunction p[] = new PolynomialFunction[n];
@ -196,33 +192,15 @@ public class PolynomialSplineFunction
}
/**
* Returns an array copy of the knot points.
* <p>
* Returns a fresh copy of the array. Changes made to the copy
* will not affect the knots property.</p>
* Get an array copy of the knot points.
* It returns a fresh copy of the array. Changes made to the copy
* will not affect the knots property.
*
* @return the knot points
* @return the knot points.
*/
public double[] getKnots() {
double out[] = new double[n + 1];
System.arraycopy(knots, 0, out, 0, n + 1);
return out;
}
/**
* Determines if the given array is ordered in a strictly increasing
* fashion.
*
* @param x the array to examine.
* @return <code>true</code> if the elements in <code>x</code> are ordered
* in a stricly increasing manner. <code>false</code>, otherwise.
*/
private static boolean isStrictlyIncreasing(double[] x) {
for (int i = 1; i < x.length; ++i) {
if (x[i - 1] >= x[i]) {
return false;
}
}
return true;
}
}

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.util.FastMath;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.util.FastMath;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.util.FastMath;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -18,7 +18,7 @@ package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.ConvergingAlgorithm;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -18,7 +18,7 @@
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.ConvergingAlgorithmImpl;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.distribution;
import java.io.Serializable;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.solvers.BrentSolver;

View File

@ -18,7 +18,7 @@ package org.apache.commons.math.distribution;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathException;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.NumberIsTooSmallException;

View File

@ -0,0 +1,96 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.exception;
import java.util.Locale;
import org.apache.commons.math.exception.util.ArgUtils;
import org.apache.commons.math.exception.util.MessageFactory;
import org.apache.commons.math.exception.util.Localizable;
import org.apache.commons.math.exception.util.LocalizedFormats;
/**
* Exception for signalling that a function object could not return
* a valid result.
*
* @since 3.0
* @version $Revision$ $Date$
*/
public class FunctionEvaluationException extends RuntimeException {
/** Serializable version Id. */
private static final long serialVersionUID = -6024911025449780478L;
/**
* Pattern used to build the message.
*/
private final Localizable specific;
/**
* Arguments used to build the message.
*/
private final Object[] arguments;
/**
* @param specific Message pattern providing the specific context of
* the error.
* @param args Arguments.
*/
public FunctionEvaluationException(Localizable specific,
Object ... args) {
this.specific = specific;
arguments = ArgUtils.flatten(args);
}
/**
* @param args Arguments.
*/
public FunctionEvaluationException(Object ... args) {
this(null, args);
}
/**
* Get the arguments.
*
* @return a (shallow) copy of the arguments.
*/
public Object[] getArguments() {
return arguments.clone();
}
/**
* Get the message in a specified locale.
*
* @param locale Locale in which the message should be translated.
*
* @return the localized message.
*/
public String getMessage(final Locale locale) {
return MessageFactory.buildMessage(locale,
specific,
LocalizedFormats.EVALUATION,
arguments);
}
/** {@inheritDoc} */
@Override
public String getMessage() {
return getMessage(Locale.US);
}
/** {@inheritDoc} */
@Override
public String getLocalizedMessage() {
return getMessage(Locale.getDefault());
}
}

View File

@ -48,8 +48,8 @@ public enum LocalizedFormats implements Localizable {
AT_LEAST_ONE_COLUMN("matrix must have at least one column"),
AT_LEAST_ONE_ROW("matrix must have at least one row"),
BANDWIDTH_OUT_OF_INTERVAL("bandwidth must be in the interval [0,1], but got {0}"),
BINOMIAL_INVALID_PARAMETERS_ORDER("must have n >= k for binomial coefficient (n,k), got n = {0}, k = {1}"),
BINOMIAL_NEGATIVE_PARAMETER("must have n >= 0 for binomial coefficient (n,k), got n = {0}"),
BINOMIAL_INVALID_PARAMETERS_ORDER("must have n >= k for binomial coefficient (n, k), got k = {0}, n = {1}"),
BINOMIAL_NEGATIVE_PARAMETER("must have n >= 0 for binomial coefficient (n, k), got n = {0}"),
CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS("statistics constructed from external moments cannot be cleared"),
CANNOT_COMPUTE_0TH_ROOT_OF_UNITY("cannot compute 0-th root of unity, indefinite result"),
CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA("cannot compute beta density at 0 when alpha = {0,number}"),
@ -95,6 +95,7 @@ public enum LocalizedFormats implements Localizable {
EQUAL_VERTICES_IN_SIMPLEX("equal vertices {0} and {1} in simplex configuration"),
EULER_ANGLES_SINGULARITY("Euler angles singularity"),
EVALUATION_FAILED("evaluation failed for argument = {0}"),
EVALUATION("evaluation"), /* keep */
EXPANSION_FACTOR_SMALLER_THAN_ONE("expansion factor smaller than one ({0})"),
FACTORIAL_NEGATIVE_PARAMETER("must have n >= 0 for n!, got n = {0}"),
FAILED_BRACKETING("number of iterations={0}, maximum iterations={1}, initial={2}, lower bound={3}, upper bound={4}, final a value={5}, final b value={6}, f(a)={7}, f(b)={8}"),

View File

@ -20,7 +20,7 @@ package org.apache.commons.math.linear;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.MathUnsupportedOperationException;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.OutOfRangeException;

View File

@ -18,7 +18,7 @@ package org.apache.commons.math.linear;
import java.util.Iterator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -18,7 +18,7 @@
package org.apache.commons.math.ode.events;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.solvers.BrentSolver;

View File

@ -20,7 +20,7 @@ package org.apache.commons.math.optimization;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.MathIllegalStateException;
import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.analysis.MultivariateRealFunction;

View File

@ -20,7 +20,7 @@ package org.apache.commons.math.optimization;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.MathIllegalStateException;
import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.analysis.MultivariateVectorialFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
/**
@ -45,7 +45,7 @@ public interface BaseMultivariateRealOptimizer<FUNC extends MultivariateRealFunc
* @param startPoint Start point for optimization.
* @return the point/value pair giving the optimal value for objective
* function.
* @throws org.apache.commons.math.FunctionEvaluationException if the
* @throws org.apache.commons.math.exception.FunctionEvaluationException if the
* objective function throws one during the search.
* @throws org.apache.commons.math.exception.DimensionMismatchException
* if the start point dimension is wrong.

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateVectorialFunction;
/**

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.analysis.MultivariateVectorialFunction;

View File

@ -20,7 +20,7 @@ package org.apache.commons.math.optimization.direct;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.DimensionMismatchException;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.direct;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.Incrementor;
import org.apache.commons.math.exception.MaxCountExceededException;
import org.apache.commons.math.exception.TooManyEvaluationsException;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.direct;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.Incrementor;
import org.apache.commons.math.exception.MaxCountExceededException;
import org.apache.commons.math.exception.TooManyEvaluationsException;

View File

@ -1,331 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.optimization.direct;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.optimization.GoalType;
import org.apache.commons.math.optimization.ConvergenceChecker;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.SimpleScalarValueChecker;
/**
* This class implements simplex-based direct search optimization
* algorithms.
*
* <p>Direct search methods only use objective function values, they don't
* need derivatives and don't either try to compute approximation of
* the derivatives. According to a 1996 paper by Margaret H. Wright
* (<a href="http://cm.bell-labs.com/cm/cs/doc/96/4-02.ps.gz">Direct
* Search Methods: Once Scorned, Now Respectable</a>), they are used
* when either the computation of the derivative is impossible (noisy
* functions, unpredictable discontinuities) or difficult (complexity,
* computation cost). In the first cases, rather than an optimum, a
* <em>not too bad</em> point is desired. In the latter cases, an
* optimum is desired but cannot be reasonably found. In all cases
* direct search methods can be useful.</p>
*
* <p>Simplex-based direct search methods are based on comparison of
* the objective function values at the vertices of a simplex (which is a
* set of n+1 points in dimension n) that is updated by the algorithms
* steps.<p>
*
* <p>The initial configuration of the simplex can be set using either
* {@link #setStartConfiguration(double[])} or {@link
* #setStartConfiguration(double[][])}. If neither method has been called
* before optimization is attempted, an explicit call to the first method
* with all steps set to +1 is triggered, thus building a default
* configuration from a unit hypercube. Each call to {@link
* #optimize(MultivariateRealFunction, GoalType, double[]) optimize} will reuse
* the current start configuration and move it such that its first vertex
* is at the provided start point of the optimization. If the {@code optimize}
* method is called to solve a different problem and the number of parameters
* change, the start configuration will be reset to a default one with the
* appropriate dimensions.</p>
*
* <p>If {@link #setConvergenceChecker(ConvergenceChecker)} is not called,
* a default {@link SimpleScalarValueChecker} is used.</p>
*
* <p>Convergence is checked by providing the <em>worst</em> points of
* previous and current simplex to the convergence checker, not the best ones.</p>
*
* <p>This class is the base class performing the boilerplate simplex
* initialization and handling. The simplex update by itself is
* performed by the derived classes according to the implemented
* algorithms.</p>
*
* @see MultivariateRealFunction
* @see NelderMead
* @see MultiDirectional
* @version $Revision$ $Date$
* @since 1.2
* @deprecated in 2.2 (to be removed in 3.0). Please use {@link SimplexOptimizer} instead.
*/
public abstract class DirectSearchOptimizer
extends BaseAbstractScalarOptimizer<MultivariateRealFunction> {
/** Simplex. */
protected RealPointValuePair[] simplex;
/** Start simplex configuration. */
private double[][] startConfiguration;
/**
* Default constructor.
*/
protected DirectSearchOptimizer() {
setConvergenceChecker(new SimpleScalarValueChecker());
}
/**
* Set start configuration for simplex.
*
* <p>The start configuration for simplex is built from a box parallel to
* the canonical axes of the space. The simplex is the subset of vertices
* of a box parallel to the canonical axes. It is built as the path followed
* while traveling from one vertex of the box to the diagonally opposite
* vertex moving only along the box edges. The first vertex of the box will
* be located at the start point of the optimization.</p>
* <p>As an example, in dimension 3 a simplex has 4 vertices. Setting the
* steps to (1, 10, 2) and the start point to (1, 1, 1) would imply the
* start simplex would be: { (1, 1, 1), (2, 1, 1), (2, 11, 1), (2, 11, 3) }.
* The first vertex would be set to the start point at (1, 1, 1) and the
* last vertex would be set to the diagonally opposite vertex at (2, 11, 3).</p>
*
* @param steps Steps along the canonical axes representing box edges. They
* may be negative but not zero.
* @throws IllegalArgumentException if one step is zero.
*/
public void setStartConfiguration(final double[] steps)
throws IllegalArgumentException {
// only the relative position of the n final vertices with respect
// to the first one are stored
final int n = steps.length;
startConfiguration = new double[n][n];
for (int i = 0; i < n; ++i) {
final double[] vertexI = startConfiguration[i];
for (int j = 0; j < i + 1; ++j) {
if (steps[j] == 0.0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.EQUAL_VERTICES_IN_SIMPLEX, j, j + 1);
}
System.arraycopy(steps, 0, vertexI, 0, j + 1);
}
}
}
/**
* Set start configuration for simplex.
* The real initial simplex will be set up by moving the reference
* simplex such that its first point is located at the start point of the
* optimization.
*
* @param referenceSimplex Reference simplex.
* @throws IllegalArgumentException if the reference simplex does not
* contain at least one point, or if there is a dimension mismatch
* in the reference simplex or if one of its vertices is duplicated.
*/
public void setStartConfiguration(final double[][] referenceSimplex)
throws IllegalArgumentException {
// only the relative position of the n final vertices with respect
// to the first one are stored
final int n = referenceSimplex.length - 1;
if (n < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.SIMPLEX_NEED_ONE_POINT);
}
startConfiguration = new double[n][n];
final double[] ref0 = referenceSimplex[0];
// vertices loop
for (int i = 0; i < n + 1; ++i) {
final double[] refI = referenceSimplex[i];
// safety checks
if (refI.length != n) {
throw new DimensionMismatchException(refI.length, n);
}
for (int j = 0; j < i; ++j) {
final double[] refJ = referenceSimplex[j];
boolean allEquals = true;
for (int k = 0; k < n; ++k) {
if (refI[k] != refJ[k]) {
allEquals = false;
break;
}
}
if (allEquals) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.EQUAL_VERTICES_IN_SIMPLEX, i, j);
}
}
// store vertex i position relative to vertex 0 position
if (i > 0) {
final double[] confI = startConfiguration[i - 1];
for (int k = 0; k < n; ++k) {
confI[k] = refI[k] - ref0[k];
}
}
}
}
/** {@inheritDoc} */
@Override
protected RealPointValuePair doOptimize()
throws FunctionEvaluationException {
final double[] startPoint = getStartPoint();
if ((startConfiguration == null) ||
(startConfiguration.length != startPoint.length)) {
// No initial configuration has been set up for simplex
// build a default one from a unit hypercube.
final double[] unit = new double[startPoint.length];
Arrays.fill(unit, 1.0);
setStartConfiguration(unit);
}
final boolean isMinim = getGoalType() == GoalType.MINIMIZE;
final Comparator<RealPointValuePair> comparator
= new Comparator<RealPointValuePair>() {
public int compare(final RealPointValuePair o1,
final RealPointValuePair o2) {
final double v1 = o1.getValue();
final double v2 = o2.getValue();
return isMinim ? Double.compare(v1, v2) : Double.compare(v2, v1);
}
};
// Initialize search.
buildSimplex(startPoint);
evaluateSimplex(comparator);
RealPointValuePair[] previous = new RealPointValuePair[simplex.length];
int iteration = 0;
final ConvergenceChecker<RealPointValuePair> checker = getConvergenceChecker();
while (true) {
if (iteration > 0) {
boolean converged = true;
for (int i = 0; i < simplex.length; ++i) {
converged &= checker.converged(iteration, previous[i], simplex[i]);
}
if (converged) {
// we have found an optimum
return simplex[0];
}
}
// We still need to search.
System.arraycopy(simplex, 0, previous, 0, simplex.length);
iterateSimplex(comparator);
++iteration;
}
}
/**
* Compute the next simplex of the algorithm.
*
* @param comparator Comparator to use to sort simplex vertices from best to worst.
* @throws FunctionEvaluationException if the function cannot be evaluated at
* some point.
* @throws org.apache.commons.math.exception.TooManyEvaluationsException if
* the algorithm fails to converge.
* @throws org.apache.commons.math.exception.DimensionMismatchException if
* the start point dimension is wrong.
*/
protected abstract void iterateSimplex(final Comparator<RealPointValuePair> comparator)
throws FunctionEvaluationException;
/**
* Build an initial simplex.
*
* @param startPoint Start point for optimization.
* @throws DimensionMismatchException if the start point does not match
* simplex dimension.
*/
private void buildSimplex(final double[] startPoint) {
final int n = startPoint.length;
if (n != startConfiguration.length) {
throw new DimensionMismatchException(n, startConfiguration.length);
}
// set first vertex
simplex = new RealPointValuePair[n + 1];
simplex[0] = new RealPointValuePair(startPoint, Double.NaN);
// set remaining vertices
for (int i = 0; i < n; ++i) {
final double[] confI = startConfiguration[i];
final double[] vertexI = new double[n];
for (int k = 0; k < n; ++k) {
vertexI[k] = startPoint[k] + confI[k];
}
simplex[i + 1] = new RealPointValuePair(vertexI, Double.NaN);
}
}
/**
* Evaluate all the non-evaluated points of the simplex.
*
* @param comparator Comparator to use to sort simplex vertices from best to worst.
* @throws FunctionEvaluationException if no value can be computed for the parameters.
* @throws org.apache.commons.math.exception.TooManyEvaluationsException
* if the maximal number of evaluations is exceeded.
*/
protected void evaluateSimplex(final Comparator<RealPointValuePair> comparator)
throws FunctionEvaluationException {
// Evaluate the objective function at all non-evaluated simplex points.
for (int i = 0; i < simplex.length; ++i) {
final RealPointValuePair vertex = simplex[i];
final double[] point = vertex.getPointRef();
if (Double.isNaN(vertex.getValue())) {
simplex[i] = new RealPointValuePair(point, computeObjectiveValue(point), false);
}
}
// Sort the simplex from best to worst.
Arrays.sort(simplex, comparator);
}
/**
* Replace the worst point of the simplex by a new point.
*
* @param pointValuePair Point to insert.
* @param comparator Comparator to use to sort simplex vertices from best to worst.
*/
protected void replaceWorstPoint(RealPointValuePair pointValuePair,
final Comparator<RealPointValuePair> comparator) {
int n = simplex.length - 1;
for (int i = 0; i < n; ++i) {
if (comparator.compare(simplex[i], pointValuePair) > 0) {
RealPointValuePair tmp = simplex[i];
simplex[i] = pointValuePair;
pointValuePair = tmp;
}
}
simplex[n] = pointValuePair;
}
}

View File

@ -1,146 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.optimization.direct;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.optimization.ConvergenceChecker;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.MultivariateRealOptimizer;
/**
* This class implements the multi-directional direct search method.
*
* @version $Revision$ $Date$
* @see NelderMead
* @deprecated in 2.2 (to be removed in 3.0). Please use {@link MultiDirectionalSimplex} instead.
* @since 1.2
*/
public class MultiDirectional extends DirectSearchOptimizer
implements MultivariateRealOptimizer {
/** Expansion coefficient. */
private final double khi;
/** Contraction coefficient. */
private final double gamma;
/**
* Build a multi-directional optimizer with default coefficients.
* The default values are 2.0 for khi and 0.5 for gamma.
*/
public MultiDirectional() {
this.khi = 2.0;
this.gamma = 0.5;
}
/**
* Build a multi-directional optimizer with specified coefficients.
*
* @param khi Expansion coefficient.
* @param gamma Contraction coefficient.
*/
public MultiDirectional(final double khi, final double gamma) {
this.khi = khi;
this.gamma = gamma;
}
/** {@inheritDoc} */
@Override
protected void iterateSimplex(final Comparator<RealPointValuePair> comparator)
throws FunctionEvaluationException {
final ConvergenceChecker<RealPointValuePair> checker = getConvergenceChecker();
int iteration = 0;
while (true) {
++iteration;
// Save the original vertex.
final RealPointValuePair[] original = simplex;
final RealPointValuePair best = original[0];
// Perform a reflection step.
final RealPointValuePair reflected = evaluateNewSimplex(original, 1.0, comparator);
if (comparator.compare(reflected, best) < 0) {
// Compute the expanded simplex.
final RealPointValuePair[] reflectedSimplex = simplex;
final RealPointValuePair expanded = evaluateNewSimplex(original, khi, comparator);
if (comparator.compare(reflected, expanded) <= 0) {
// Accept the reflected simplex.
simplex = reflectedSimplex;
}
return;
}
// Compute the contracted simplex.
final RealPointValuePair contracted = evaluateNewSimplex(original, gamma, comparator);
if (comparator.compare(contracted, best) < 0) {
// Accept the contracted simplex.
return;
}
// Check convergence.
boolean converged = true;
for (int i = 0; i < simplex.length; ++i) {
converged &= checker.converged(iteration, original[i], simplex[i]);
}
if (converged) {
return;
}
}
}
/**
* Compute and evaluate a new simplex.
*
* @param original Original simplex (to be preserved).
* @param coeff Linear coefficient.
* @param comparator Comparator to use to sort simplex vertices from best
* to poorest.
* @return the best point in the transformed simplex.
* @throws FunctionEvaluationException if the function cannot be
* evaluated at some point.
* @throws org.apache.commons.math.exception.TooManyEvaluationsException
* if the maximal number of evaluations is exceeded.
*/
private RealPointValuePair evaluateNewSimplex(final RealPointValuePair[] original,
final double coeff,
final Comparator<RealPointValuePair> comparator)
throws FunctionEvaluationException {
final double[] xSmallest = original[0].getPointRef();
final int n = xSmallest.length;
// Create the linearly transformed simplex.
simplex = new RealPointValuePair[n + 1];
simplex[0] = original[0];
for (int i = 1; i <= n; ++i) {
final double[] xOriginal = original[i].getPointRef();
final double[] xTransformed = new double[n];
for (int j = 0; j < n; ++j) {
xTransformed[j] = xSmallest[j] + coeff * (xSmallest[j] - xOriginal[j]);
}
simplex[i] = new RealPointValuePair(xTransformed, Double.NaN, false);
}
// Evaluate the simplex.
evaluateSimplex(comparator);
return simplex[0];
}
}

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.optimization.direct;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.optimization.RealPointValuePair;

View File

@ -1,181 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.optimization.direct;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.MultivariateRealOptimizer;
/**
* This class implements the Nelder-Mead direct search method.
*
* @version $Revision$ $Date$
* @see MultiDirectional
* @since 1.2
* @deprecated in 2.2 (to be removed in 3.0). Please use {@link NelderMeadSimplex} instead.
*/
public class NelderMead extends DirectSearchOptimizer
implements MultivariateRealOptimizer {
/** Reflection coefficient. */
private final double rho;
/** Expansion coefficient. */
private final double khi;
/** Contraction coefficient. */
private final double gamma;
/** Shrinkage coefficient. */
private final double sigma;
/**
* Build a Nelder-Mead optimizer with default coefficients.
* The default coefficients are 1.0 for rho, 2.0 for khi and 0.5
* for both gamma and sigma.
*/
public NelderMead() {
this.rho = 1.0;
this.khi = 2.0;
this.gamma = 0.5;
this.sigma = 0.5;
}
/**
* Build a Nelder-Mead optimizer with specified coefficients.
*
* @param rho Reflection coefficient.
* @param khi Expansion coefficient.
* @param gamma Contraction coefficient.
* @param sigma Shrinkage coefficient.
*/
public NelderMead(final double rho, final double khi,
final double gamma, final double sigma) {
this.rho = rho;
this.khi = khi;
this.gamma = gamma;
this.sigma = sigma;
}
/** {@inheritDoc} */
@Override
protected void iterateSimplex(final Comparator<RealPointValuePair> comparator)
throws FunctionEvaluationException {
// the simplex has n+1 point if dimension is n
final int n = simplex.length - 1;
// interesting values
final RealPointValuePair best = simplex[0];
final RealPointValuePair secondBest = simplex[n-1];
final RealPointValuePair worst = simplex[n];
final double[] xWorst = worst.getPointRef();
// compute the centroid of the best vertices
// (dismissing the worst point at index n)
final double[] centroid = new double[n];
for (int i = 0; i < n; ++i) {
final double[] x = simplex[i].getPointRef();
for (int j = 0; j < n; ++j) {
centroid[j] += x[j];
}
}
final double scaling = 1.0 / n;
for (int j = 0; j < n; ++j) {
centroid[j] *= scaling;
}
// compute the reflection point
final double[] xR = new double[n];
for (int j = 0; j < n; ++j) {
xR[j] = centroid[j] + rho * (centroid[j] - xWorst[j]);
}
final RealPointValuePair reflected
= new RealPointValuePair(xR, computeObjectiveValue(xR), false);
if ((comparator.compare(best, reflected) <= 0) &&
(comparator.compare(reflected, secondBest) < 0)) {
// accept the reflected point
replaceWorstPoint(reflected, comparator);
} else if (comparator.compare(reflected, best) < 0) {
// compute the expansion point
final double[] xE = new double[n];
for (int j = 0; j < n; ++j) {
xE[j] = centroid[j] + khi * (xR[j] - centroid[j]);
}
final RealPointValuePair expanded
= new RealPointValuePair(xE, computeObjectiveValue(xE), false);
if (comparator.compare(expanded, reflected) < 0) {
// accept the expansion point
replaceWorstPoint(expanded, comparator);
} else {
// accept the reflected point
replaceWorstPoint(reflected, comparator);
}
} else {
if (comparator.compare(reflected, worst) < 0) {
// perform an outside contraction
final double[] xC = new double[n];
for (int j = 0; j < n; ++j) {
xC[j] = centroid[j] + gamma * (xR[j] - centroid[j]);
}
final RealPointValuePair outContracted
= new RealPointValuePair(xC, computeObjectiveValue(xC), false);
if (comparator.compare(outContracted, reflected) <= 0) {
// accept the contraction point
replaceWorstPoint(outContracted, comparator);
return;
}
} else {
// perform an inside contraction
final double[] xC = new double[n];
for (int j = 0; j < n; ++j) {
xC[j] = centroid[j] - gamma * (centroid[j] - xWorst[j]);
}
final RealPointValuePair inContracted
= new RealPointValuePair(xC, computeObjectiveValue(xC), false);
if (comparator.compare(inContracted, worst) < 0) {
// accept the contraction point
replaceWorstPoint(inContracted, comparator);
return;
}
}
// perform a shrink
final double[] xSmallest = simplex[0].getPointRef();
for (int i = 1; i < simplex.length; ++i) {
final double[] x = simplex[i].getPoint();
for (int j = 0; j < n; ++j) {
x[j] = xSmallest[j] + sigma * (x[j] - xSmallest[j]);
}
simplex[i] = new RealPointValuePair(x, Double.NaN, false);
}
evaluateSimplex(comparator);
}
}
}

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.optimization.direct;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.analysis.MultivariateRealFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.direct;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.analysis.MultivariateRealFunction;

View File

@ -19,13 +19,14 @@ package org.apache.commons.math.optimization.direct;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.optimization.GoalType;
import org.apache.commons.math.optimization.ConvergenceChecker;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.SimpleScalarValueChecker;
import org.apache.commons.math.optimization.MultivariateRealOptimizer;
/**
* This class implements simplex-based direct search optimization.
@ -76,7 +77,8 @@ import org.apache.commons.math.optimization.SimpleScalarValueChecker;
* @since 3.0
*/
public class SimplexOptimizer
extends BaseAbstractScalarOptimizer<MultivariateRealFunction> {
extends BaseAbstractScalarOptimizer<MultivariateRealFunction>
implements MultivariateRealOptimizer {
/** Simplex. */
private AbstractSimplex simplex;

View File

@ -20,7 +20,7 @@ package org.apache.commons.math.optimization.fitting;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
import org.apache.commons.math.analysis.MultivariateMatrixFunction;
import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.optimization.fitting;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.util.LocalizedFormats;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.fitting;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;
import org.apache.commons.math.optimization.OptimizationException;
import org.apache.commons.math.optimization.fitting.CurveFitter;

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.optimization.fitting;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.DifferentiableUnivariateRealFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.DimensionMismatchException;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.fitting;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.optimization.fitting;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.exception.ZeroException;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.fitting;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* An interface representing a real function that depends on one independent

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.fitting;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.polynomials.PolynomialFunction;
import org.apache.commons.math.optimization.DifferentiableMultivariateVectorialOptimizer;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.general;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
import org.apache.commons.math.analysis.MultivariateMatrixFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.general;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
import org.apache.commons.math.analysis.MultivariateVectorialFunction;
import org.apache.commons.math.optimization.DifferentiableMultivariateRealOptimizer;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.general;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.linear.BlockRealMatrix;
import org.apache.commons.math.linear.DecompositionSolver;

View File

@ -18,7 +18,7 @@ package org.apache.commons.math.optimization.general;
import java.util.Arrays;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.optimization.VectorialPointValuePair;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.general;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.MathIllegalStateException;
import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.analysis.UnivariateRealFunction;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.general;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* This interface represents a preconditioner for differentiable scalar

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.univariate;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.Incrementor;
import org.apache.commons.math.exception.MaxCountExceededException;
import org.apache.commons.math.exception.TooManyEvaluationsException;

View File

@ -17,7 +17,7 @@
package org.apache.commons.math.optimization.univariate;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.optimization.BaseOptimizer;
import org.apache.commons.math.optimization.GoalType;

View File

@ -20,7 +20,7 @@ import org.apache.commons.math.util.Incrementor;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.TooManyEvaluationsException;
import org.apache.commons.math.exception.MaxCountExceededException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.optimization.GoalType;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.optimization.univariate;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.MathUtils;
import org.apache.commons.math.util.FastMath;
import org.apache.commons.math.exception.NumberIsTooSmallException;

View File

@ -20,7 +20,7 @@ package org.apache.commons.math.optimization.univariate;
import java.util.Arrays;
import java.util.Comparator;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.MathIllegalStateException;
import org.apache.commons.math.exception.ConvergenceException;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.transform;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.complex.Complex;

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.transform;
import java.io.Serializable;
import java.lang.reflect.Array;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.complex.Complex;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.transform;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.exception.util.LocalizedFormats;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.transform;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.complex.Complex;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.transform;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
/**

View File

@ -20,11 +20,23 @@ package org.apache.commons.math.util;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Map;
import java.util.AbstractMap;
import java.util.Collections;
import org.apache.commons.math.MathRuntimeException;
import org.apache.commons.math.exception.util.Localizable;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.exception.NonMonotonousSequenceException;
import org.apache.commons.math.exception.DimensionMismatchException;
import org.apache.commons.math.exception.NullArgumentException;
import org.apache.commons.math.exception.NotPositiveException;
import org.apache.commons.math.exception.MathArithmeticException;
import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.NumberIsTooLargeException;
/**
* Some useful additions to the built-in functions in {@link Math}.
@ -94,14 +106,14 @@ public final class MathUtils {
* @param x an addend
* @param y an addend
* @return the sum <code>x+y</code>
* @throws ArithmeticException if the result can not be represented as an
* int
* @throws MathArithmeticException if the result can not be represented
* as an {@code int}.
* @since 1.1
*/
public static int addAndCheck(int x, int y) {
long s = (long)x + (long)y;
if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y);
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_ADDITION, x, y);
}
return (int)s;
}
@ -123,12 +135,12 @@ public final class MathUtils {
/**
* Add two long integers, checking for overflow.
*
* @param a an addend
* @param b an addend
* @param pattern the pattern to use for any thrown exception.
* @return the sum <code>a+b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @param a Addend.
* @param b Addend.
* @param pattern Pattern to use for any thrown exception.
* @return the sum {@code a + b}.
* @throws MathArithmeticException if the result cannot be represented
* as a {@code long}.
* @since 1.2
*/
private static long addAndCheck(long a, long b, Localizable pattern) {
@ -145,7 +157,7 @@ public final class MathUtils {
if (Long.MIN_VALUE - b <= a) {
ret = a + b;
} else {
throw MathRuntimeException.createArithmeticException(pattern, a, b);
throw new MathArithmeticException(pattern, a, b);
}
} else {
// opposite sign addition is always safe
@ -159,7 +171,7 @@ public final class MathUtils {
if (a <= Long.MAX_VALUE - b) {
ret = a + b;
} else {
throw MathRuntimeException.createArithmeticException(pattern, a, b);
throw new MathArithmeticException(pattern, a, b);
}
}
}
@ -357,21 +369,19 @@ public final class MathUtils {
/**
* Check binomial preconditions.
* @param n the size of the set
* @param k the size of the subsets to be counted
* @exception IllegalArgumentException if preconditions are not met.
*
* @param n Size of the set.
* @param k Size of the subsets to be counted.
* @throws NotPositiveException if {@code n < 0}.
* @throws NumberIsTooLargeException if {@code k > n}.
*/
private static void checkBinomial(final int n, final int k)
throws IllegalArgumentException {
private static void checkBinomial(final int n, final int k) {
if (n < k) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.BINOMIAL_INVALID_PARAMETERS_ORDER,
n, k);
throw new NumberIsTooLargeException(LocalizedFormats.BINOMIAL_INVALID_PARAMETERS_ORDER,
k, n, true);
}
if (n < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.BINOMIAL_NEGATIVE_PARAMETER,
n);
throw new NotPositiveException(LocalizedFormats.BINOMIAL_NEGATIVE_PARAMETER, n);
}
}
@ -577,48 +587,40 @@ public final class MathUtils {
*
* @param n argument
* @return <code>n!</code>
* @throws ArithmeticException if the result is too large to be represented
* by a long integer.
* @throws IllegalArgumentException if n < 0
* @throws MathArithmeticException if the result is too large to be represented
* by a {@code long}.
* @throws NotPositiveException if {@code n < 0}.
* @throws MathArithmeticException if {@code n > 20}: The factorial value is too
* large to fit in a {@code long}.
*/
public static long factorial(final int n) {
if (n < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
n);
throw new NotPositiveException(LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
n);
}
if (n > 20) {
throw new ArithmeticException(
"factorial value is too large to fit in a long");
throw new MathArithmeticException();
}
return FACTORIALS[n];
}
/**
* Returns n!. Shorthand for <code>n</code> <a
* href="http://mathworld.wolfram.com/Factorial.html"> Factorial</a>, the
* product of the numbers <code>1,...,n</code> as a <code>double</code>.
* <p>
* <Strong>Preconditions</strong>:
* <ul>
* <li> <code>n >= 0</code> (otherwise
* <code>IllegalArgumentException</code> is thrown)</li>
* <li> The result is small enough to fit into a <code>double</code>. The
* largest value of <code>n</code> for which <code>n!</code> <
* Double.MAX_VALUE</code> is 170. If the computed value exceeds
* Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned</li>
* </ul>
* </p>
* Compute n!, the<a href="http://mathworld.wolfram.com/Factorial.html">
* factorial</a> of {@code n} (the product of the numbers 1 to n), as a
* {@code double}.
* The result should be small enough to fit into a {@code double}: The
* largest {@code n} for which {@code n! < Double.MAX_VALUE} is 170.
* If the computed value exceeds {@code Double.MAX_VALUE},
* {@code Double.POSITIVE_INFINITY} is returned.
*
* @param n argument
* @return <code>n!</code>
* @throws IllegalArgumentException if n < 0
* @param n Argument.
* @return {@code n!}
* @throws NotPositiveException if {@code n < 0}.
*/
public static double factorialDouble(final int n) {
if (n < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
n);
throw new NotPositiveException(LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
n);
}
if (n < 21) {
return factorial(n);
@ -627,23 +629,16 @@ public final class MathUtils {
}
/**
* Returns the natural logarithm of n!.
* <p>
* <Strong>Preconditions</strong>:
* <ul>
* <li> <code>n >= 0</code> (otherwise
* <code>IllegalArgumentException</code> is thrown)</li>
* </ul></p>
* Compute the natural logarithm of the factorial of {@code n}.
*
* @param n argument
* @return <code>n!</code>
* @throws IllegalArgumentException if preconditions are not met.
* @param n Argument.
* @return {@code n!}
* @throws NotPositiveException if {@code n < 0}.
*/
public static double factorialLog(final int n) {
if (n < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
n);
throw new NotPositiveException(LocalizedFormats.FACTORIAL_NEGATIVE_PARAMETER,
n);
}
if (n < 21) {
return FastMath.log(factorial(n));
@ -677,11 +672,11 @@ public final class MathUtils {
* <code>0</code>.</li>
* </ul>
*
* @param p any number
* @param q any number
* @return the greatest common divisor, never negative
* @throws ArithmeticException if the result cannot be represented as a
* nonnegative int value
* @param p Number.
* @param q Number.
* @return the greatest common divisor, never negative.
* @throws MathArithmeticException if the result cannot be represented as
* a non-negative {@code int} value.
* @since 1.1
*/
public static int gcd(final int p, final int q) {
@ -689,9 +684,8 @@ public final class MathUtils {
int v = q;
if ((u == 0) || (v == 0)) {
if ((u == Integer.MIN_VALUE) || (v == Integer.MIN_VALUE)) {
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.GCD_OVERFLOW_32_BITS,
p, q);
throw new MathArithmeticException(LocalizedFormats.GCD_OVERFLOW_32_BITS,
p, q);
}
return FastMath.abs(u) + FastMath.abs(v);
}
@ -715,9 +709,8 @@ public final class MathUtils {
k++; // cast out twos.
}
if (k == 31) {
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.GCD_OVERFLOW_32_BITS,
p, q);
throw new MathArithmeticException(LocalizedFormats.GCD_OVERFLOW_32_BITS,
p, q);
}
// B2. Initialize: u and v have been divided by 2^k and at least
// one is odd.
@ -766,11 +759,11 @@ public final class MathUtils {
* <code>0L</code>.</li>
* </ul>
*
* @param p any number
* @param q any number
* @return the greatest common divisor, never negative
* @throws ArithmeticException if the result cannot be represented as a nonnegative long
* value
* @param p Number.
* @param q Number.
* @return the greatest common divisor, never negative.
* @throws MathArithmeticException if the result cannot be represented as
* a non-negative {@code long} value.
* @since 2.1
*/
public static long gcd(final long p, final long q) {
@ -778,9 +771,8 @@ public final class MathUtils {
long v = q;
if ((u == 0) || (v == 0)) {
if ((u == Long.MIN_VALUE) || (v == Long.MIN_VALUE)){
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.GCD_OVERFLOW_64_BITS,
p, q);
throw new MathArithmeticException(LocalizedFormats.GCD_OVERFLOW_64_BITS,
p, q);
}
return FastMath.abs(u) + FastMath.abs(v);
}
@ -804,9 +796,8 @@ public final class MathUtils {
k++; // cast out twos.
}
if (k == 63) {
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.GCD_OVERFLOW_64_BITS,
p, q);
throw new MathArithmeticException(LocalizedFormats.GCD_OVERFLOW_64_BITS,
p, q);
}
// B2. Initialize: u and v have been divided by 2^k and at least
// one is odd.
@ -940,23 +931,21 @@ public final class MathUtils {
* <code>0</code> for any <code>x</code>.
* </ul>
*
* @param a any number
* @param b any number
* @return the least common multiple, never negative
* @throws ArithmeticException
* if the result cannot be represented as a nonnegative int
* value
* @param a Number.
* @param b Number.
* @return the least common multiple, never negative.
* @throws MathArithmeticException if the result cannot be represented as
* a non-negative {@code int} value.
* @since 1.1
*/
public static int lcm(int a, int b) {
if (a==0 || b==0){
if (a == 0 || b == 0){
return 0;
}
int lcm = FastMath.abs(mulAndCheck(a / gcd(a, b), b));
if (lcm == Integer.MIN_VALUE) {
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.LCM_OVERFLOW_32_BITS,
a, b);
throw new MathArithmeticException(LocalizedFormats.LCM_OVERFLOW_32_BITS,
a, b);
}
return lcm;
}
@ -976,22 +965,21 @@ public final class MathUtils {
* <code>0L</code> for any <code>x</code>.
* </ul>
*
* @param a any number
* @param b any number
* @return the least common multiple, never negative
* @throws ArithmeticException if the result cannot be represented as a nonnegative long
* value
* @param a Number.
* @param b Number.
* @return the least common multiple, never negative.
* @throws MathArithmeticException if the result cannot be represented
* as a non-negative {@code long} value.
* @since 2.1
*/
public static long lcm(long a, long b) {
if (a==0 || b==0){
if (a == 0 || b == 0){
return 0;
}
long lcm = FastMath.abs(mulAndCheck(a / gcd(a, b), b));
if (lcm == Long.MIN_VALUE){
throw MathRuntimeException.createArithmeticException(
LocalizedFormats.LCM_OVERFLOW_64_BITS,
a, b);
throw new MathArithmeticException(LocalizedFormats.LCM_OVERFLOW_64_BITS,
a, b);
}
return lcm;
}
@ -1019,17 +1007,17 @@ public final class MathUtils {
/**
* Multiply two integers, checking for overflow.
*
* @param x a factor
* @param y a factor
* @return the product <code>x*y</code>
* @throws ArithmeticException if the result can not be represented as an
* int
* @param x Factor.
* @param y Factor.
* @return the product {@code x * y}.
* @throws MathArithmeticException if the result can not be
* represented as an {@code int}.
* @since 1.1
*/
public static int mulAndCheck(int x, int y) {
long m = ((long)x) * ((long)y);
if (m < Integer.MIN_VALUE || m > Integer.MAX_VALUE) {
throw new ArithmeticException("overflow: mul");
throw new MathArithmeticException();
}
return (int)m;
}
@ -1037,16 +1025,15 @@ public final class MathUtils {
/**
* Multiply two long integers, checking for overflow.
*
* @param a first value
* @param b second value
* @return the product <code>a * b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @param a Factor.
* @param b Factor.
* @return the product {@code a * b}.
* @throws MathArithmeticException if the result can not be represented
* as a {@code long}.
* @since 1.2
*/
public static long mulAndCheck(long a, long b) {
long ret;
String msg = "overflow: multiply";
if (a > b) {
// use symmetry to reduce boundary cases
ret = mulAndCheck(b, a);
@ -1057,14 +1044,14 @@ public final class MathUtils {
if (a >= Long.MAX_VALUE / b) {
ret = a * b;
} else {
throw new ArithmeticException(msg);
throw new MathArithmeticException();
}
} else if (b > 0) {
// check for negative overflow with negative a, positive b
if (Long.MIN_VALUE / b <= a) {
ret = a * b;
} else {
throw new ArithmeticException(msg);
throw new MathArithmeticException();
}
} else {
@ -1079,7 +1066,7 @@ public final class MathUtils {
if (a <= Long.MAX_VALUE / b) {
ret = a * b;
} else {
throw new ArithmeticException(msg);
throw new MathArithmeticException();
}
} else {
// assert a == 0
@ -1160,8 +1147,7 @@ public final class MathUtils {
* @throws IllegalArgumentException if the target sum is infinite or NaN
* @since 2.1
*/
public static double[] normalizeArray(double[] values, double normalizedSum)
throws ArithmeticException, IllegalArgumentException {
public static double[] normalizeArray(double[] values, double normalizedSum) {
if (Double.isInfinite(normalizedSum)) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.NORMALIZE_INFINITE);
@ -1271,15 +1257,15 @@ public final class MathUtils {
* determined by the rounding method specified. Rounding methods are defined
* in {@link BigDecimal}.
*
* @param unscaled the value to round.
* @param sign the sign of the original, scaled value.
* @param roundingMethod the rounding method as defined in
* {@link BigDecimal}.
* @param unscaled Value to round.
* @param sign Sign of the original, scaled value.
* @param roundingMethod Rounding method, as defined in {@link BigDecimal}.
* @return the rounded value.
* @since 1.1
*/
private static double roundUnscaled(double unscaled, double sign,
int roundingMethod) {
private static double roundUnscaled(double unscaled,
double sign,
int roundingMethod) {
switch (roundingMethod) {
case BigDecimal.ROUND_CEILING :
if (sign == -1) {
@ -1337,24 +1323,23 @@ public final class MathUtils {
}
case BigDecimal.ROUND_UNNECESSARY :
if (unscaled != FastMath.floor(unscaled)) {
throw new ArithmeticException("Inexact result from rounding");
throw new MathArithmeticException();
}
break;
case BigDecimal.ROUND_UP :
unscaled = FastMath.ceil(FastMath.nextAfter(unscaled, Double.POSITIVE_INFINITY));
break;
default :
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.INVALID_ROUNDING_METHOD,
roundingMethod,
"ROUND_CEILING", BigDecimal.ROUND_CEILING,
"ROUND_DOWN", BigDecimal.ROUND_DOWN,
"ROUND_FLOOR", BigDecimal.ROUND_FLOOR,
"ROUND_HALF_DOWN", BigDecimal.ROUND_HALF_DOWN,
"ROUND_HALF_EVEN", BigDecimal.ROUND_HALF_EVEN,
"ROUND_HALF_UP", BigDecimal.ROUND_HALF_UP,
"ROUND_UNNECESSARY", BigDecimal.ROUND_UNNECESSARY,
"ROUND_UP", BigDecimal.ROUND_UP);
throw new MathIllegalArgumentException(LocalizedFormats.INVALID_ROUNDING_METHOD,
roundingMethod,
"ROUND_CEILING", BigDecimal.ROUND_CEILING,
"ROUND_DOWN", BigDecimal.ROUND_DOWN,
"ROUND_FLOOR", BigDecimal.ROUND_FLOOR,
"ROUND_HALF_DOWN", BigDecimal.ROUND_HALF_DOWN,
"ROUND_HALF_EVEN", BigDecimal.ROUND_HALF_EVEN,
"ROUND_HALF_UP", BigDecimal.ROUND_HALF_UP,
"ROUND_UNNECESSARY", BigDecimal.ROUND_UNNECESSARY,
"ROUND_UP", BigDecimal.ROUND_UP);
}
return unscaled;
}
@ -1439,26 +1424,22 @@ public final class MathUtils {
}
/**
* Returns the <a href="http://mathworld.wolfram.com/Sign.html"> sign</a>
* for short value <code>x</code>.
* <p>
* For a short value x, this method returns (short)(+1) if x > 0, (short)(0)
* if x = 0, and (short)(-1) if x < 0.</p>
* Compute the <a href="http://mathworld.wolfram.com/Sign.html">sign</a>
* of the argument.
*
* @param x the value, a short
* @return (short)(+1), (short)(0), or (short)(-1), depending on the sign of
* x
* @return 1 if {@code x > 0}, 0 if {@code x == 0}, and -1 if {@code x < 0}.
*/
public static short sign(final short x) {
return (x == ZS) ? ZS : (x > ZS) ? PS : NS;
}
/**
* Returns the <a href="http://mathworld.wolfram.com/HyperbolicSine.html">
* hyperbolic sine</a> of x.
* Compute the <a href="http://mathworld.wolfram.com/HyperbolicSine.html">
* hyperbolic sine</a> of the argument.
*
* @param x double value for which to find the hyperbolic sine
* @return hyperbolic sine of x
* @param x Value for which to find the hyperbolic sine.
* @return hyperbolic sine of {@code x}.
*/
public static double sinh(double x) {
return (FastMath.exp(x) - FastMath.exp(-x)) / 2.0;
@ -1467,17 +1448,17 @@ public final class MathUtils {
/**
* Subtract two integers, checking for overflow.
*
* @param x the minuend
* @param y the subtrahend
* @return the difference <code>x-y</code>
* @throws ArithmeticException if the result can not be represented as an
* int
* @param x Minuend.
* @param y Subtrahend.
* @return the difference {@code x - y}.
* @throws MathArithmeticException if the result can not be represented
* as an {@code int}.
* @since 1.1
*/
public static int subAndCheck(int x, int y) {
long s = (long)x - (long)y;
if (s < Integer.MIN_VALUE || s > Integer.MAX_VALUE) {
throw MathRuntimeException.createArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, x, y);
throw new MathArithmeticException(LocalizedFormats.OVERFLOW_IN_SUBTRACTION, x, y);
}
return (int)s;
}
@ -1485,11 +1466,11 @@ public final class MathUtils {
/**
* Subtract two long integers, checking for overflow.
*
* @param a first value
* @param b second value
* @return the difference <code>a-b</code>
* @throws ArithmeticException if the result can not be represented as an
* long
* @param a Value.
* @param b Value.
* @return the difference {@code a - b}.
* @throws MathArithmeticException if the result can not be represented as a
* {@code long}.
* @since 1.2
*/
public static long subAndCheck(long a, long b) {
@ -1510,18 +1491,15 @@ public final class MathUtils {
/**
* Raise an int to an int power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static int pow(final int k, int e)
throws IllegalArgumentException {
public static int pow(final int k, int e) {
if (e < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
int result = 1;
@ -1535,23 +1513,19 @@ public final class MathUtils {
}
return result;
}
/**
* Raise an int to a long power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static int pow(final int k, long e)
throws IllegalArgumentException {
public static int pow(final int k, long e) {
if (e < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
int result = 1;
@ -1565,23 +1539,19 @@ public final class MathUtils {
}
return result;
}
/**
* Raise a long to an int power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static long pow(final long k, int e)
throws IllegalArgumentException {
public static long pow(final long k, int e) {
if (e < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
long result = 1l;
@ -1595,23 +1565,19 @@ public final class MathUtils {
}
return result;
}
/**
* Raise a long to a long power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static long pow(final long k, long e)
throws IllegalArgumentException {
public static long pow(final long k, long e) {
if (e < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
long result = 1l;
@ -1625,43 +1591,35 @@ public final class MathUtils {
}
return result;
}
/**
* Raise a BigInteger to an int power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, int e)
throws IllegalArgumentException {
public static BigInteger pow(final BigInteger k, int e) {
if (e < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
return k.pow(e);
}
/**
* Raise a BigInteger to a long power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, long e)
throws IllegalArgumentException {
public static BigInteger pow(final BigInteger k, long e) {
if (e < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
BigInteger result = BigInteger.ONE;
@ -1680,18 +1638,15 @@ public final class MathUtils {
/**
* Raise a BigInteger to a BigInteger power.
* @param k number to raise
* @param e exponent (must be positive or null)
*
* @param k Number to raise.
* @param e Exponent (must be positive or zero).
* @return k<sup>e</sup>
* @exception IllegalArgumentException if e is negative
* @throws NotPositiveException if {@code e < 0}.
*/
public static BigInteger pow(final BigInteger k, BigInteger e)
throws IllegalArgumentException {
public static BigInteger pow(final BigInteger k, BigInteger e) {
if (e.compareTo(BigInteger.ZERO) < 0) {
throw MathRuntimeException.createIllegalArgumentException(
LocalizedFormats.POWER_NEGATIVE_PARAMETERS,
k, e);
throw new NotPositiveException(LocalizedFormats.EXPONENT, e);
}
BigInteger result = BigInteger.ONE;
@ -1705,7 +1660,6 @@ public final class MathUtils {
}
return result;
}
/**
@ -1816,9 +1770,13 @@ public final class MathUtils {
* @param val Values.
* @param dir Ordering direction.
* @param strict Whether the order should be strict.
* @throws NonMonotonousSequenceException if the array is not sorted.
* @param abort Whether to throw an exception if the check fails.
* @return {@code true} if the array is sorted.
* @throws NonMonotonousSequenceException if the array is not sorted
* and {@code abort} is {@code true}.
*/
public static void checkOrder(double[] val, OrderDirection dir, boolean strict) {
public static boolean checkOrder(double[] val, OrderDirection dir,
boolean strict, boolean abort) {
double previous = val[0];
boolean ok = true;
@ -1852,21 +1810,40 @@ public final class MathUtils {
throw new IllegalArgumentException();
}
if (!ok) {
if (!ok &&
abort) {
throw new NonMonotonousSequenceException(val[i], previous, i, dir, strict);
}
previous = val[i];
}
return ok;
}
/**
* Checks that the given array is sorted.
*
* @param val Values.
* @param dir Ordering direction.
* @param strict Whether the order should be strict.
* @return {@code true} if the array is sorted.
* @throws NonMonotonousSequenceException if the array is not sorted
* and {@code abort} is {@code true}.
*/
public static boolean checkOrder(double[] val, OrderDirection dir,
boolean strict) {
return checkOrder(val, dir, strict, true);
}
/**
* Checks that the given array is sorted in strictly increasing order.
*
* @param val Values.
* @return {@code true} if the array is sorted.
* @throws NonMonotonousSequenceException if the array is not sorted.
*/
public static void checkOrder(double[] val) {
checkOrder(val, OrderDirection.INCREASING, true);
public static boolean checkOrder(double[] val) {
return checkOrder(val, OrderDirection.INCREASING, true);
}
/**
@ -1929,58 +1906,139 @@ public final class MathUtils {
* @return the 2-norm of the vector
*/
public static double safeNorm(double[] v) {
double rdwarf = 3.834e-20;
double rgiant = 1.304e+19;
double s1=0.0;
double s2=0.0;
double s3=0.0;
double x1max = 0.0;
double x3max = 0.0;
double floatn = (double)v.length;
double agiant = rgiant/floatn;
for (int i=0;i<v.length;i++) {
double xabs = Math.abs(v[i]);
if (xabs<rdwarf || xabs>agiant) {
if (xabs>rdwarf) {
if (xabs>x1max) {
double r=x1max/xabs;
s1=1.0+s1*r*r;
x1max=xabs;
double rdwarf = 3.834e-20;
double rgiant = 1.304e+19;
double s1 = 0;
double s2 = 0;
double s3 = 0;
double x1max = 0;
double x3max = 0;
double floatn = (double) v.length;
double agiant = rgiant / floatn;
for (int i = 0; i < v.length; i++) {
double xabs = Math.abs(v[i]);
if (xabs < rdwarf || xabs > agiant) {
if (xabs > rdwarf) {
if (xabs > x1max) {
double r = x1max / xabs;
s1= 1 + s1 * r * r;
x1max = xabs;
} else {
double r = xabs / x1max;
s1 += r * r;
}
} else {
double r=xabs/x1max;
s1+=r*r;
}
} else {
if (xabs>x3max) {
double r=x3max/xabs;
s3=1.0+s3*r*r;
x3max=xabs;
} else {
if (xabs!=0.0) {
double r=xabs/x3max;
s3+=r*r;
if (xabs > x3max) {
double r = x3max / xabs;
s3= 1 + s3 * r * r;
x3max = xabs;
} else {
if (xabs != 0) {
double r = xabs / x3max;
s3 += r * r;
}
}
}
}
} else {
s2+=xabs*xabs;
}
}
double norm;
if (s1!=0.0) {
norm = x1max*Math.sqrt(s1+(s2/x1max)/x1max);
} else {
if (s2==0.0) {
norm = x3max*Math.sqrt(s3);
} else {
if (s2>=x3max) {
norm = Math.sqrt(s2*(1.0+(x3max/s2)*(x3max*s3)));
} else {
norm = Math.sqrt(x3max*((s2/x3max)+(x3max*s3)));
s2 += xabs * xabs;
}
}
double norm;
if (s1 != 0) {
norm = x1max * Math.sqrt(s1 + (s2 / x1max) / x1max);
} else {
if (s2 == 0) {
norm = x3max * Math.sqrt(s3);
} else {
if (s2 >= x3max) {
norm = Math.sqrt(s2 * (1 + (x3max / s2) * (x3max * s3)));
} else {
norm = Math.sqrt(x3max * ((s2 / x3max) + (x3max * s3)));
}
}
}
return norm;
}
/**
* Sort an array in increasing order, performing the same reordering of
* entries on other arrays.
*
* @param x Array to be sorted.
* @param yList Set of arrays whose permutations of entries must follow
* those performed on {@code x}.
* @throws DimensionMismatchException if any {@code y} has not the same
* size as {@code x}.
*/
public static void sortInPlace(double[] x,
double[] ... yList) {
sortInPlace(x, OrderDirection.INCREASING, yList);
}
/**
* Sort an array, performing the same reordering of entries on other arrays.
*
* @param x Array to be sorted.
* @param dir Order direction.
* @param yList Set of arrays whose permutations of entries must follow
* those performed on {@code x}.
* @throws DimensionMismatchException if any {@code y} has not the same
* size as {@code x}.
*/
public static void sortInPlace(double[] x,
final OrderDirection dir,
double[] ... yList) {
if (x == null ||
yList == null) {
throw new NullArgumentException();
}
final int len = x.length;
final List<Map.Entry<Double, double[]>> list
= new ArrayList<Map.Entry<Double, double[]>>(len);
final int yListLen = yList.length;
for (int i = 0; i < len; i++) {
final double[] yValues = new double[yListLen];
for (int j = 0; j < yListLen; j++) {
double[] y = yList[j];
if (y.length != len) {
throw new DimensionMismatchException(y.length, len);
}
yValues[j] = y[i];
}
list.add(new AbstractMap.SimpleEntry<Double, double[]>(x[i], yValues));
}
final Comparator<Map.Entry<Double, double[]>> comp
= new Comparator<Map.Entry<Double, double[]>>() {
public int compare(Map.Entry<Double, double[]> o1,
Map.Entry<Double, double[]> o2) {
int val;
switch (dir) {
case INCREASING:
val = o1.getKey().compareTo(o2.getKey());
break;
case DECREASING:
val = o2.getKey().compareTo(o1.getKey());
break;
default:
// Should never happen.
throw new IllegalArgumentException();
}
return val;
}
};
Collections.sort(list, comp);
for (int i = 0; i < len; i++) {
final Map.Entry<Double, double[]> e = list.get(i);
x[i] = e.getKey();
final double[] yValues = e.getValue();
for (int j = 0; j < yListLen; j++) {
yList[j][i] = yValues[j];
}
}
}
return norm;
}
}

View File

@ -20,8 +20,8 @@ ASSYMETRIC_EIGEN_NOT_SUPPORTED = la d\u00e9composition en valeurs/vecteurs propr
AT_LEAST_ONE_COLUMN = une matrice doit comporter au moins une colonne
AT_LEAST_ONE_ROW = une matrice doit comporter au moins une ligne
BANDWIDTH_OUT_OF_INTERVAL = la bande passante devrait \u00eatre dans l''intervalle [0,1], elle est de {0}
BINOMIAL_INVALID_PARAMETERS_ORDER = n doit \u00eatre sup\u00e9rieur ou \u00e9gal \u00e0 k pour le coefficient du bin\u00f4me (n,k), or n = {0}, k = {1}
BINOMIAL_NEGATIVE_PARAMETER = n doit \u00eatre positif pour le coefficient du bin\u00f4me (n,k), or n = {0}
BINOMIAL_INVALID_PARAMETERS_ORDER = n doit \u00eatre sup\u00e9rieur ou \u00e9gal \u00e0 k pour le coefficient du bin\u00f4me (n, k), or k = {0}, n = {1}
BINOMIAL_NEGATIVE_PARAMETER = n doit \u00eatre positif pour le coefficient du bin\u00f4me (n, k), or n = {0}
CANNOT_CLEAR_STATISTIC_CONSTRUCTED_FROM_EXTERNAL_MOMENTS = les statistiques bas\u00e9es sur des moments externes ne peuvent pas \u00eatre remises \u00e0 z\u00e9ro
CANNOT_COMPUTE_0TH_ROOT_OF_UNITY = impossible de calculer la racine z\u00e9roi\u00e8me de l''unit\u00e9,
CANNOT_COMPUTE_BETA_DENSITY_AT_0_FOR_SOME_ALPHA = impossible de calculer la densit\u00e9 beta en 0 lorsque alpha = {0,number}
@ -67,6 +67,7 @@ ENDPOINTS_NOT_AN_INTERVAL = les bornes ne d\u00e9finissent pas un intervalle : [
EQUAL_VERTICES_IN_SIMPLEX = sommets {0} et {1} \u00e9gaux dans la configuration du simplex
EULER_ANGLES_SINGULARITY = singularit\u00e9 d''angles d''Euler
EVALUATION_FAILED = erreur d''\u00e9valuation pour l''argument {0}
EVALUATION = \u00e9valuation
EXPANSION_FACTOR_SMALLER_THAN_ONE = facteur d''extension inf\u00e9rieur \u00e0 un ({0})
FACTORIAL_NEGATIVE_PARAMETER = n doit \u00eatre positif pour le calcul de n!, or n = {0}
FAILED_BRACKETING = nombre d''it\u00e9rations = {0}, it\u00e9rations maximum = {1}, valeur initiale = {2}, borne inf\u00e9rieure = {3}, borne sup\u00e9rieure = {4}, valeur a finale = {5}, valeur b finale = {6}, f(a) = {7}, f(b) = {8}

View File

@ -60,7 +60,11 @@ The <action> type attribute can be add,update,fix,remove.
classes were deprecated and removed.
</action>
<action dev="erans" type="update" issue="MATH-425">
Replaced old exceptions.
Created "MatrixDimensionMismatchException" to replace
"InvalidMatrixException" (when the latter is used to signal that
matrices are not compatible for some operation).
Replaced "MatrixIndexException" with "OutOfRangeException" (when the
former is used to signal a row or column dimension mismatch).
</action>
<action dev="erans" type="update" issue="MATH-310">
Made "sample" methods part of the "IntegerDistribution" and
@ -70,8 +74,9 @@ The <action> type attribute can be add,update,fix,remove.
All distribution classes (in package "distribution") are immutable.
</action>
<action dev="erans" type="update" issue="MATH-195">
Created "MatrixDimensionMismatch" to replace "InvalidMatrixException"
(when the latter is used to signal a row or column dimension mismatch).
Created an unchecked "FunctionEvaluationException".
Modified the "UnivariateRealFunction" interface: Removed the checked
"FunctionEvaluationException" from the signature of the "value" method.
</action>
<action dev="erans" type="update" issue="MATH-370">
Modified semantics: "equals" methods now consider that NaNs are not

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;
import org.junit.Assert;
import org.junit.Test;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;
import org.junit.Assert;
import org.junit.Test;

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;
/**

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* Wrapper class for counting functions calls.

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* Auxiliary class for testing solvers.

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.util.FastMath;
/**

View File

@ -16,7 +16,7 @@
*/
package org.apache.commons.math.analysis;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
/**
* Auxiliary class for testing optimizers.

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.analysis.integration;
import java.util.Random;
import org.apache.commons.math.ConvergenceException;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.MathException;
import org.apache.commons.math.analysis.QuinticFunction;
import org.apache.commons.math.analysis.SinFunction;

View File

@ -17,6 +17,7 @@
package org.apache.commons.math.analysis.interpolation;
import org.apache.commons.math.MathException;
import org.apache.commons.math.exception.NonMonotonousSequenceException;
import org.apache.commons.math.analysis.Expm1Function;
import org.apache.commons.math.analysis.SinFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;
@ -118,8 +119,8 @@ public final class DividedDifferenceInterpolatorTest extends TestCase {
double y[] = { 0.0, 4.0, 4.0, 2.5 };
UnivariateRealFunction p = interpolator.interpolate(x, y);
p.value(0.0);
fail("Expecting MathException - bad abscissas array");
} catch (MathException ex) {
fail("Expecting NonMonotonousSequenceException - bad abscissas array");
} catch (NonMonotonousSequenceException ex) {
// expected
}
}

View File

@ -17,6 +17,7 @@
package org.apache.commons.math.analysis.interpolation;
import org.apache.commons.math.MathException;
import org.apache.commons.math.exception.NonMonotonousSequenceException;
import org.apache.commons.math.analysis.Expm1Function;
import org.apache.commons.math.analysis.SinFunction;
import org.apache.commons.math.analysis.UnivariateRealFunction;
@ -118,8 +119,8 @@ public final class NevilleInterpolatorTest extends TestCase {
double y[] = { 0.0, 4.0, 4.0, 2.5 };
UnivariateRealFunction p = interpolator.interpolate(x, y);
p.value(0.0);
fail("Expecting MathException - bad abscissas array");
} catch (MathException ex) {
fail("Expecting NonMonotonousSequenceException - bad abscissas array");
} catch (NonMonotonousSequenceException ex) {
// expected
}
}

View File

@ -19,7 +19,7 @@ package org.apache.commons.math.analysis.polynomials;
import java.util.Arrays;
import junit.framework.TestCase;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.OutOfRangeException;
import org.apache.commons.math.analysis.UnivariateRealFunction;
/**
@ -116,15 +116,15 @@ public class PolynomialSplineFunctionTest extends TestCase {
try { //outside of domain -- under min
x = spline.value(-1.5);
fail("Expecting IllegalArgumentException");
} catch (FunctionEvaluationException ex) {
fail("Expecting OutOfRangeException");
} catch (OutOfRangeException ex) {
// expected
}
try { //outside of domain -- over max
x = spline.value(2.5);
fail("Expecting IllegalArgumentException");
} catch (FunctionEvaluationException ex) {
fail("Expecting OutOfRangeException");
} catch (OutOfRangeException ex) {
// expected
}
}

View File

@ -21,7 +21,7 @@ import java.util.Iterator;
import junit.framework.TestCase;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.TestUtils;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.util.FastMath;

View File

@ -21,7 +21,7 @@ import java.util.Iterator;
import junit.framework.TestCase;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.TestUtils;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.apache.commons.math.util.FastMath;

View File

@ -23,7 +23,7 @@ import static org.junit.Assert.assertTrue;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.DifferentiableMultivariateRealFunction;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.analysis.MultivariateVectorialFunction;

View File

@ -23,7 +23,7 @@ import static org.junit.Assert.fail;
import java.io.Serializable;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.exception.ConvergenceException;
import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
import org.apache.commons.math.analysis.MultivariateMatrixFunction;

View File

@ -20,9 +20,10 @@ package org.apache.commons.math.optimization;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.optimization.direct.NelderMead;
import org.apache.commons.math.optimization.direct.SimplexOptimizer;
import org.apache.commons.math.optimization.direct.NelderMeadSimplex;
import org.apache.commons.math.random.GaussianRandomGenerator;
import org.apache.commons.math.random.JDKRandomGenerator;
import org.apache.commons.math.random.RandomVectorGenerator;
@ -30,53 +31,47 @@ import org.apache.commons.math.random.UncorrelatedRandomVectorGenerator;
import org.junit.Test;
public class MultiStartMultivariateRealOptimizerTest {
@Test
public void testRosenbrock() {
Rosenbrock rosenbrock = new Rosenbrock();
SimplexOptimizer underlying = new SimplexOptimizer();
NelderMeadSimplex simplex = new NelderMeadSimplex(new double[][] {
{ -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 }
});
underlying.setSimplex(simplex);
JDKRandomGenerator g = new JDKRandomGenerator();
g.setSeed(16069223052l);
RandomVectorGenerator generator =
new UncorrelatedRandomVectorGenerator(2, new GaussianRandomGenerator(g));
MultiStartMultivariateRealOptimizer optimizer =
new MultiStartMultivariateRealOptimizer(underlying, 10, generator);
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3));
optimizer.setMaxEvaluations(1100);
RealPointValuePair optimum =
optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 });
@Test
public void testRosenbrock()
throws FunctionEvaluationException {
assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
assertTrue(optimizer.getEvaluations() > 900);
assertTrue(optimizer.getEvaluations() < 1200);
assertTrue(optimum.getValue() < 8.0e-4);
}
Rosenbrock rosenbrock = new Rosenbrock();
NelderMead underlying = new NelderMead();
underlying.setStartConfiguration(new double[][] {
{ -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 }
});
JDKRandomGenerator g = new JDKRandomGenerator();
g.setSeed(16069223052l);
RandomVectorGenerator generator =
new UncorrelatedRandomVectorGenerator(2, new GaussianRandomGenerator(g));
MultiStartMultivariateRealOptimizer optimizer =
new MultiStartMultivariateRealOptimizer(underlying, 10, generator);
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3));
optimizer.setMaxEvaluations(1100);
RealPointValuePair optimum =
optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 });
private static class Rosenbrock implements MultivariateRealFunction {
private int count;
assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
assertTrue(optimizer.getEvaluations() > 900);
assertTrue(optimizer.getEvaluations() < 1200);
assertTrue(optimum.getValue() < 8.0e-4);
public Rosenbrock() {
count = 0;
}
}
private static class Rosenbrock implements MultivariateRealFunction {
private int count;
public Rosenbrock() {
count = 0;
}
public double value(double[] x) throws FunctionEvaluationException {
++count;
double a = x[1] - x[0] * x[0];
double b = 1.0 - x[0];
return 100 * a * a + b * b;
}
public int getCount() {
return count;
}
}
public double value(double[] x) {
++count;
double a = x[1] - x[0] * x[0];
double b = 1.0 - x[0];
return 100 * a * a + b * b;
}
public int getCount() {
return count;
}
}
}

View File

@ -1,241 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.optimization.direct;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.optimization.GoalType;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.SimpleScalarValueChecker;
import org.apache.commons.math.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
public class MultiDirectionalTest {
@Test
public void testFunctionEvaluationExceptions() {
MultivariateRealFunction wrong =
new MultivariateRealFunction() {
private static final long serialVersionUID = 4751314470965489371L;
public double value(double[] x) throws FunctionEvaluationException {
if (x[0] < 0) {
throw new FunctionEvaluationException(x, "{0}", "oops");
} else if (x[0] > 1) {
throw new FunctionEvaluationException(new RuntimeException("oops"), x);
} else {
return x[0] * (1 - x[0]);
}
}
};
try {
MultiDirectional optimizer = new MultiDirectional(0.9, 1.9);
optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { -1.0 });
Assert.fail("an exception should have been thrown");
} catch (FunctionEvaluationException ce) {
// expected behavior
Assert.assertNull(ce.getCause());
}
try {
MultiDirectional optimizer = new MultiDirectional(0.9, 1.9);
optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { +2.0 });
Assert.fail("an exception should have been thrown");
} catch (FunctionEvaluationException ce) {
// expected behavior
Assert.assertNotNull(ce.getCause());
}
}
@Test
public void testMinimizeMaximize()
throws FunctionEvaluationException {
// the following function has 4 local extrema:
final double xM = -3.841947088256863675365;
final double yM = -1.391745200270734924416;
final double xP = 0.2286682237349059125691;
final double yP = -yM;
final double valueXmYm = 0.2373295333134216789769; // local maximum
final double valueXmYp = -valueXmYm; // local minimum
final double valueXpYm = -0.7290400707055187115322; // global minimum
final double valueXpYp = -valueXpYm; // global maximum
MultivariateRealFunction fourExtrema = new MultivariateRealFunction() {
private static final long serialVersionUID = -7039124064449091152L;
public double value(double[] variables) throws FunctionEvaluationException {
final double x = variables[0];
final double y = variables[1];
return ((x == 0) || (y == 0)) ? 0 : (FastMath.atan(x) * FastMath.atan(x + 2) * FastMath.atan(y) * FastMath.atan(y) / (x * y));
}
};
MultiDirectional optimizer = new MultiDirectional();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-11, 1.0e-30));
optimizer.setMaxEvaluations(200);
optimizer.setStartConfiguration(new double[] { 0.2, 0.2 });
RealPointValuePair optimum;
// minimization
optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { -3.0, 0 });
Assert.assertEquals(xM, optimum.getPoint()[0], 4.0e-6);
Assert.assertEquals(yP, optimum.getPoint()[1], 3.0e-6);
Assert.assertEquals(valueXmYp, optimum.getValue(), 8.0e-13);
Assert.assertTrue(optimizer.getEvaluations() > 120);
Assert.assertTrue(optimizer.getEvaluations() < 150);
optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { +1, 0 });
Assert.assertEquals(xP, optimum.getPoint()[0], 2.0e-8);
Assert.assertEquals(yM, optimum.getPoint()[1], 3.0e-6);
Assert.assertEquals(valueXpYm, optimum.getValue(), 2.0e-12);
Assert.assertTrue(optimizer.getEvaluations() > 120);
Assert.assertTrue(optimizer.getEvaluations() < 150);
// maximization
optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 });
Assert.assertEquals(xM, optimum.getPoint()[0], 7.0e-7);
Assert.assertEquals(yM, optimum.getPoint()[1], 3.0e-7);
Assert.assertEquals(valueXmYm, optimum.getValue(), 2.0e-14);
Assert.assertTrue(optimizer.getEvaluations() > 120);
Assert.assertTrue(optimizer.getEvaluations() < 150);
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-15, 1.0e-30));
optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { +1, 0 });
Assert.assertEquals(xP, optimum.getPoint()[0], 2.0e-8);
Assert.assertEquals(yP, optimum.getPoint()[1], 3.0e-6);
Assert.assertEquals(valueXpYp, optimum.getValue(), 2.0e-12);
Assert.assertTrue(optimizer.getEvaluations() > 180);
Assert.assertTrue(optimizer.getEvaluations() < 220);
}
@Test
public void testRosenbrock()
throws FunctionEvaluationException {
MultivariateRealFunction rosenbrock =
new MultivariateRealFunction() {
private static final long serialVersionUID = -9044950469615237490L;
public double value(double[] x) throws FunctionEvaluationException {
++count;
double a = x[1] - x[0] * x[0];
double b = 1.0 - x[0];
return 100 * a * a + b * b;
}
};
count = 0;
MultiDirectional optimizer = new MultiDirectional();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3));
optimizer.setMaxEvaluations(100);
optimizer.setStartConfiguration(new double[][] {
{ -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 }
});
RealPointValuePair optimum =
optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 });
Assert.assertEquals(count, optimizer.getEvaluations());
Assert.assertTrue(optimizer.getEvaluations() > 50);
Assert.assertTrue(optimizer.getEvaluations() < 100);
Assert.assertTrue(optimum.getValue() > 1.0e-2);
}
@Test
public void testPowell()
throws FunctionEvaluationException {
MultivariateRealFunction powell =
new MultivariateRealFunction() {
private static final long serialVersionUID = -832162886102041840L;
public double value(double[] x) throws FunctionEvaluationException {
++count;
double a = x[0] + 10 * x[1];
double b = x[2] - x[3];
double c = x[1] - 2 * x[2];
double d = x[0] - x[3];
return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
}
};
count = 0;
MultiDirectional optimizer = new MultiDirectional();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
optimizer.setMaxEvaluations(1000);
RealPointValuePair optimum =
optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
Assert.assertEquals(count, optimizer.getEvaluations());
Assert.assertTrue(optimizer.getEvaluations() > 800);
Assert.assertTrue(optimizer.getEvaluations() < 900);
Assert.assertTrue(optimum.getValue() > 1.0e-2);
}
@Test
public void testMath283()
throws FunctionEvaluationException {
// fails because MultiDirectional.iterateSimplex is looping forever
// the while(true) should be replaced with a convergence check
MultiDirectional multiDirectional = new MultiDirectional();
multiDirectional.setMaxEvaluations(1000);
final Gaussian2D function = new Gaussian2D(0.0, 0.0, 1.0);
RealPointValuePair estimate = multiDirectional.optimize(function,
GoalType.MAXIMIZE, function.getMaximumPosition());
final double EPSILON = 1e-5;
final double expectedMaximum = function.getMaximum();
final double actualMaximum = estimate.getValue();
Assert.assertEquals(expectedMaximum, actualMaximum, EPSILON);
final double[] expectedPosition = function.getMaximumPosition();
final double[] actualPosition = estimate.getPoint();
Assert.assertEquals(expectedPosition[0], actualPosition[0], EPSILON );
Assert.assertEquals(expectedPosition[1], actualPosition[1], EPSILON );
}
private static class Gaussian2D implements MultivariateRealFunction {
private final double[] maximumPosition;
private final double std;
public Gaussian2D(double xOpt, double yOpt, double std) {
maximumPosition = new double[] { xOpt, yOpt };
this.std = std;
}
public double getMaximum() {
return value(maximumPosition);
}
public double[] getMaximumPosition() {
return maximumPosition.clone();
}
public double value(double[] point) {
final double x = point[0], y = point[1];
final double twoS2 = 2.0 * std * std;
return 1.0 / (twoS2 * FastMath.PI) * FastMath.exp(-(x * x + y * y) / twoS2);
}
}
private int count;
}

View File

@ -1,295 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math.optimization.direct;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.apache.commons.math.FunctionEvaluationException;
import org.apache.commons.math.exception.TooManyEvaluationsException;
import org.apache.commons.math.analysis.MultivariateRealFunction;
import org.apache.commons.math.analysis.MultivariateVectorialFunction;
import org.apache.commons.math.linear.Array2DRowRealMatrix;
import org.apache.commons.math.linear.RealMatrix;
import org.apache.commons.math.optimization.GoalType;
import org.apache.commons.math.optimization.LeastSquaresConverter;
import org.apache.commons.math.optimization.RealPointValuePair;
import org.apache.commons.math.optimization.SimpleScalarValueChecker;
import org.junit.Test;
public class NelderMeadTest {
@Test
public void testFunctionEvaluationExceptions() {
MultivariateRealFunction wrong =
new MultivariateRealFunction() {
private static final long serialVersionUID = 4751314470965489371L;
public double value(double[] x) throws FunctionEvaluationException {
if (x[0] < 0) {
throw new FunctionEvaluationException(x, "{0}", "oops");
} else if (x[0] > 1) {
throw new FunctionEvaluationException(new RuntimeException("oops"), x);
} else {
return x[0] * (1 - x[0]);
}
}
};
try {
NelderMead optimizer = new NelderMead(0.9, 1.9, 0.4, 0.6);
optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { -1.0 });
fail("an exception should have been thrown");
} catch (FunctionEvaluationException ce) {
// expected behavior
assertNull(ce.getCause());
}
try {
NelderMead optimizer = new NelderMead(0.9, 1.9, 0.4, 0.6);
optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { +2.0 });
fail("an exception should have been thrown");
} catch (FunctionEvaluationException ce) {
// expected behavior
assertNotNull(ce.getCause());
}
}
@Test
public void testMinimizeMaximize()
throws FunctionEvaluationException {
// the following function has 4 local extrema:
final double xM = -3.841947088256863675365;
final double yM = -1.391745200270734924416;
final double xP = 0.2286682237349059125691;
final double yP = -yM;
final double valueXmYm = 0.2373295333134216789769; // local maximum
final double valueXmYp = -valueXmYm; // local minimum
final double valueXpYm = -0.7290400707055187115322; // global minimum
final double valueXpYp = -valueXpYm; // global maximum
MultivariateRealFunction fourExtrema = new MultivariateRealFunction() {
private static final long serialVersionUID = -7039124064449091152L;
public double value(double[] variables) throws FunctionEvaluationException {
final double x = variables[0];
final double y = variables[1];
return ((x == 0) || (y == 0)) ? 0 : (Math.atan(x) * Math.atan(x + 2) * Math.atan(y) * Math.atan(y) / (x * y));
}
};
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-10, 1.0e-30));
optimizer.setMaxEvaluations(100);
optimizer.setStartConfiguration(new double[] { 0.2, 0.2 });
RealPointValuePair optimum;
// minimization
optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { -3.0, 0 });
assertEquals(xM, optimum.getPoint()[0], 2.0e-7);
assertEquals(yP, optimum.getPoint()[1], 2.0e-5);
assertEquals(valueXmYp, optimum.getValue(), 6.0e-12);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 90);
optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { +1, 0 });
assertEquals(xP, optimum.getPoint()[0], 5.0e-6);
assertEquals(yM, optimum.getPoint()[1], 6.0e-6);
assertEquals(valueXpYm, optimum.getValue(), 1.0e-11);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 90);
// maximization
optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 });
assertEquals(xM, optimum.getPoint()[0], 1.0e-5);
assertEquals(yM, optimum.getPoint()[1], 3.0e-6);
assertEquals(valueXmYm, optimum.getValue(), 3.0e-12);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 90);
optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { +1, 0 });
assertEquals(xP, optimum.getPoint()[0], 4.0e-6);
assertEquals(yP, optimum.getPoint()[1], 5.0e-6);
assertEquals(valueXpYp, optimum.getValue(), 7.0e-12);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 90);
}
@Test
public void testRosenbrock()
throws FunctionEvaluationException {
Rosenbrock rosenbrock = new Rosenbrock();
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3));
optimizer.setMaxEvaluations(100);
optimizer.setStartConfiguration(new double[][] {
{ -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 }
});
RealPointValuePair optimum =
optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 });
assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
assertTrue(optimizer.getEvaluations() > 40);
assertTrue(optimizer.getEvaluations() < 50);
assertTrue(optimum.getValue() < 8.0e-4);
}
@Test
public void testPowell()
throws FunctionEvaluationException {
Powell powell = new Powell();
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
optimizer.setMaxEvaluations(200);
RealPointValuePair optimum =
optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
assertEquals(powell.getCount(), optimizer.getEvaluations());
assertTrue(optimizer.getEvaluations() > 110);
assertTrue(optimizer.getEvaluations() < 130);
assertTrue(optimum.getValue() < 2.0e-3);
}
@Test
public void testLeastSquares1()
throws FunctionEvaluationException {
final RealMatrix factors =
new Array2DRowRealMatrix(new double[][] {
{ 1.0, 0.0 },
{ 0.0, 1.0 }
}, false);
LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorialFunction() {
public double[] value(double[] variables) {
return factors.operate(variables);
}
}, new double[] { 2.0, -3.0 });
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-6));
optimizer.setMaxEvaluations(200);
RealPointValuePair optimum =
optimizer.optimize(ls, GoalType.MINIMIZE, new double[] { 10.0, 10.0 });
assertEquals( 2.0, optimum.getPointRef()[0], 3.0e-5);
assertEquals(-3.0, optimum.getPointRef()[1], 4.0e-4);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 80);
assertTrue(optimum.getValue() < 1.0e-6);
}
@Test
public void testLeastSquares2()
throws FunctionEvaluationException {
final RealMatrix factors =
new Array2DRowRealMatrix(new double[][] {
{ 1.0, 0.0 },
{ 0.0, 1.0 }
}, false);
LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorialFunction() {
public double[] value(double[] variables) {
return factors.operate(variables);
}
}, new double[] { 2.0, -3.0 }, new double[] { 10.0, 0.1 });
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-6));
optimizer.setMaxEvaluations(200);
RealPointValuePair optimum =
optimizer.optimize(ls, GoalType.MINIMIZE, new double[] { 10.0, 10.0 });
assertEquals( 2.0, optimum.getPointRef()[0], 5.0e-5);
assertEquals(-3.0, optimum.getPointRef()[1], 8.0e-4);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 80);
assertTrue(optimum.getValue() < 1.0e-6);
}
@Test
public void testLeastSquares3()
throws FunctionEvaluationException {
final RealMatrix factors =
new Array2DRowRealMatrix(new double[][] {
{ 1.0, 0.0 },
{ 0.0, 1.0 }
}, false);
LeastSquaresConverter ls = new LeastSquaresConverter(new MultivariateVectorialFunction() {
public double[] value(double[] variables) {
return factors.operate(variables);
}
}, new double[] { 2.0, -3.0 }, new Array2DRowRealMatrix(new double [][] {
{ 1.0, 1.2 }, { 1.2, 2.0 }
}));
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-6));
optimizer.setMaxEvaluations(200);
RealPointValuePair optimum =
optimizer.optimize(ls, GoalType.MINIMIZE, new double[] { 10.0, 10.0 });
assertEquals( 2.0, optimum.getPointRef()[0], 2.0e-3);
assertEquals(-3.0, optimum.getPointRef()[1], 8.0e-4);
assertTrue(optimizer.getEvaluations() > 60);
assertTrue(optimizer.getEvaluations() < 80);
assertTrue(optimum.getValue() < 1.0e-6);
}
@Test(expected = TooManyEvaluationsException.class)
public void testMaxIterations() throws FunctionEvaluationException {
Powell powell = new Powell();
NelderMead optimizer = new NelderMead();
optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
optimizer.setMaxEvaluations(20);
optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
}
private static class Rosenbrock implements MultivariateRealFunction {
private int count;
public Rosenbrock() {
count = 0;
}
public double value(double[] x) throws FunctionEvaluationException {
++count;
double a = x[1] - x[0] * x[0];
double b = 1.0 - x[0];
return 100 * a * a + b * b;
}
public int getCount() {
return count;
}
}
private static class Powell implements MultivariateRealFunction {
private int count;
public Powell() {
count = 0;
}
public double value(double[] x) throws FunctionEvaluationException {
++count;
double a = x[0] + 10 * x[1];
double b = x[2] - x[3];
double c = x[1] - 2 * x[2];
double d = x[0] - x[3];
return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
}
public int getCount() {
return count;
}
}
}

Some files were not shown because too many files have changed in this diff Show More