Fail early on wrong derivation order.

If the user asks for a derivation order that is too large for the number
of points in the finite differences algorithm, we now detect it before
the first call to the underlying function.

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1387064 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2012-09-18 09:07:54 +00:00
parent 19c954cabc
commit 5259df5f91
2 changed files with 58 additions and 7 deletions

View File

@ -28,7 +28,7 @@ import org.apache.commons.math3.exception.NumberIsTooSmallException;
/** Univariate functions differentiator using finite differences.
* <p>
* This class creates some wrapper objetcs around regular
* This class creates some wrapper objects around regular
* {@link UnivariateFunction univariate functions} (or {@link
* UnivariateVectorFunction univariate vector functions} or {@link
* UnivariateMatrixFunction univariate matrix functions}). These
@ -136,12 +136,6 @@ public class FiniteDifferencesDifferentiator
private DerivativeStructure evaluate(final DerivativeStructure t, final double[] y)
throws NumberIsTooLargeException {
// check we can achieve the requested derivation order with the sample
final int order = t.getOrder();
if (order >= nbPoints) {
throw new NumberIsTooLargeException(order, nbPoints, false);
}
// create divided differences diagonal arrays
final double[] top = new double[nbPoints];
final double[] bottom = new double[nbPoints];
@ -160,6 +154,7 @@ public class FiniteDifferencesDifferentiator
}
// evaluate interpolation polynomial (represented by top diagonal) at t
final int order = t.getOrder();
final int parameters = t.getFreeParameters();
final double[] derivatives = t.getAllDerivatives();
DerivativeStructure interpolation = new DerivativeStructure(parameters, order, 0.0);
@ -193,6 +188,11 @@ public class FiniteDifferencesDifferentiator
public DerivativeStructure value(final DerivativeStructure t)
throws MathIllegalArgumentException {
// check we can achieve the requested derivation order with the sample
if (t.getOrder() >= nbPoints) {
throw new NumberIsTooLargeException(t.getOrder(), nbPoints, false);
}
// get sample points centered around t value
final double t0 = t.getValue();
final double[] y = new double[nbPoints];
@ -227,6 +227,11 @@ public class FiniteDifferencesDifferentiator
public DerivativeStructure[] value(final DerivativeStructure t)
throws MathIllegalArgumentException {
// check we can achieve the requested derivation order with the sample
if (t.getOrder() >= nbPoints) {
throw new NumberIsTooLargeException(t.getOrder(), nbPoints, false);
}
// get sample points centered around t value
final double t0 = t.getValue();
double[][] y = null;
@ -272,6 +277,11 @@ public class FiniteDifferencesDifferentiator
public DerivativeStructure[][] value(final DerivativeStructure t)
throws MathIllegalArgumentException {
// check we can achieve the requested derivation order with the sample
if (t.getOrder() >= nbPoints) {
throw new NumberIsTooLargeException(t.getOrder(), nbPoints, false);
}
// get sample points centered around t value
final double t0 = t.getValue();
double[][][] y = null;

View File

@ -24,7 +24,9 @@ import org.apache.commons.math3.analysis.UnivariateMatrixFunction;
import org.apache.commons.math3.analysis.UnivariateVectorFunction;
import org.apache.commons.math3.analysis.function.Gaussian;
import org.apache.commons.math3.analysis.function.Sin;
import org.apache.commons.math3.exception.MathInternalError;
import org.apache.commons.math3.exception.NotPositiveException;
import org.apache.commons.math3.exception.NumberIsTooLargeException;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.util.FastMath;
import org.junit.Assert;
@ -160,6 +162,45 @@ public class FiniteDifferencesDifferentiatorTest {
}
@Test(expected=NumberIsTooLargeException.class)
public void testWrongOrder() {
UnivariateDifferentiableFunction f =
new FiniteDifferencesDifferentiator(3, 0.01).differentiate(new UnivariateFunction() {
public double value(double x) {
// this exception should not be thrown because wrong order
// should be detected before function call
throw new MathInternalError();
}
});
f.value(new DerivativeStructure(1, 3, 0, 1.0));
}
@Test(expected=NumberIsTooLargeException.class)
public void testWrongOrderVector() {
UnivariateDifferentiableVectorFunction f =
new FiniteDifferencesDifferentiator(3, 0.01).differentiate(new UnivariateVectorFunction() {
public double[] value(double x) {
// this exception should not be thrown because wrong order
// should be detected before function call
throw new MathInternalError();
}
});
f.value(new DerivativeStructure(1, 3, 0, 1.0));
}
@Test(expected=NumberIsTooLargeException.class)
public void testWrongOrderMatrix() {
UnivariateDifferentiableMatrixFunction f =
new FiniteDifferencesDifferentiator(3, 0.01).differentiate(new UnivariateMatrixFunction() {
public double[][] value(double x) {
// this exception should not be thrown because wrong order
// should be detected before function call
throw new MathInternalError();
}
});
f.value(new DerivativeStructure(1, 3, 0, 1.0));
}
@Test
public void testVectorFunction() {