In package o.a.c.m.transform

- replaced RealTransformer.transform(double[]) and RealTransformer.inverseTransform(double[]) with RealTransformer.transform(double[], TransformType)
  - replaced RealTransformer.transform(UnivariateFunction, double, double, int) and RealTransformer.inverseTransform(UnivariateFunction, double, double, int) with RealTransformer.transform(UnivariateFunction, double, double, int, TransformType).

See MATH-743

git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1243110 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sebastien Brisard 2012-02-11 17:38:30 +00:00
parent 29e6359399
commit fb761ffb51
9 changed files with 160 additions and 401 deletions

View File

@ -22,8 +22,6 @@ import org.apache.commons.math.analysis.FunctionUtils;
import org.apache.commons.math.analysis.UnivariateFunction;
import org.apache.commons.math.complex.Complex;
import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.NonMonotonicSequenceException;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath;
@ -115,7 +113,7 @@ import org.apache.commons.math.util.FastMath;
public class FastCosineTransformer implements RealTransformer, Serializable {
/** Serializable version identifier. */
static final long serialVersionUID = 20120501L;
static final long serialVersionUID = 20120211L;
/**
* {@code true} if the orthogonal version of the DCT should be used.
@ -169,44 +167,14 @@ public class FastCosineTransformer implements RealTransformer, Serializable {
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two plus one
*/
public double[] transform(double[] f) throws MathIllegalArgumentException {
if (orthogonal) {
final double s = FastMath.sqrt(2.0 / (f.length - 1));
return TransformUtils.scaleArray(fct(f), s);
public double[] transform(final double[] f, final TransformType type) {
if (type == TransformType.FORWARD) {
if (orthogonal) {
final double s = FastMath.sqrt(2.0 / (f.length - 1));
return TransformUtils.scaleArray(fct(f), s);
}
return fct(f);
}
return fct(f);
}
/**
* {@inheritDoc}
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two plus one
*/
public double[] transform(UnivariateFunction f,
double min, double max, int n) throws
NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
final double[] data = FunctionUtils.sample(f, min, max, n);
return transform(data);
}
/**
* {@inheritDoc}
*
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two plus one
*/
public double[] inverseTransform(double[] f) throws
MathIllegalArgumentException {
final double s2 = 2.0 / (f.length - 1);
final double s1 = orthogonal ? FastMath.sqrt(s2) : s2;
return TransformUtils.scaleArray(fct(f), s1);
@ -215,21 +183,19 @@ public class FastCosineTransformer implements RealTransformer, Serializable {
/**
* {@inheritDoc}
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws org.apache.commons.math.exception.NonMonotonicSequenceException
* if the lower bound is greater than, or equal to the upper bound
* @throws org.apache.commons.math.exception.NotStrictlyPositiveException
* if the number of sample points is negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two plus one
*/
public double[] inverseTransform(UnivariateFunction f,
double min, double max, int n) throws
NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
public double[] transform(final UnivariateFunction f,
final double min, final double max, final int n,
final TransformType type) {
final double[] data = FunctionUtils.sample(f, min, max, n);
return inverseTransform(data);
return transform(data, type);
}
/**

View File

@ -21,8 +21,6 @@ import java.io.Serializable;
import org.apache.commons.math.analysis.FunctionUtils;
import org.apache.commons.math.analysis.UnivariateFunction;
import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.NonMonotonicSequenceException;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.ArithmeticUtils;
@ -40,7 +38,7 @@ import org.apache.commons.math.util.ArithmeticUtils;
public class FastHadamardTransformer implements RealTransformer, Serializable {
/** Serializable version identifier. */
static final long serialVersionUID = 20120501L;
static final long serialVersionUID = 20120211L;
/**
* {@inheritDoc}
@ -48,60 +46,28 @@ public class FastHadamardTransformer implements RealTransformer, Serializable {
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/
public double[] transform(double[] f) throws MathIllegalArgumentException {
return fht(f);
}
/**
* {@inheritDoc}
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two
*/
public double[] transform(UnivariateFunction f,
double min, double max, int n) throws
NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
return fht(FunctionUtils.sample(f, min, max, n));
}
/**
* {@inheritDoc}
*
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/
public double[] inverseTransform(double[] f)
throws IllegalArgumentException {
public double[] transform(final double[] f, final TransformType type) {
if (type == TransformType.FORWARD) {
return fht(f);
}
return TransformUtils.scaleArray(fht(f), 1.0 / f.length);
}
}
/**
* {@inheritDoc}
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws org.apache.commons.math.exception.NonMonotonicSequenceException
* if the lower bound is greater than, or equal to the upper bound
* @throws org.apache.commons.math.exception.NotStrictlyPositiveException
* if the number of sample points is negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two
*/
public double[] inverseTransform(UnivariateFunction f,
double min, double max, int n) throws
NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
public double[] transform(final UnivariateFunction f,
final double min, final double max, final int n,
final TransformType type) {
final double[] unscaled =
fht(FunctionUtils.sample(f, min, max, n));
return TransformUtils.scaleArray(unscaled, 1.0 / n);
return transform(FunctionUtils.sample(f, min, max, n), type);
}
/**
@ -114,7 +80,7 @@ public class FastHadamardTransformer implements RealTransformer, Serializable {
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two
*/
public int[] transform(int[] f) throws MathIllegalArgumentException {
public int[] transform(final int[] f) {
return fht(f);
}

View File

@ -22,8 +22,6 @@ import org.apache.commons.math.analysis.FunctionUtils;
import org.apache.commons.math.analysis.UnivariateFunction;
import org.apache.commons.math.complex.Complex;
import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.NonMonotonicSequenceException;
import org.apache.commons.math.exception.NotStrictlyPositiveException;
import org.apache.commons.math.exception.util.LocalizedFormats;
import org.apache.commons.math.util.ArithmeticUtils;
import org.apache.commons.math.util.FastMath;
@ -105,9 +103,6 @@ import org.apache.commons.math.util.FastMath;
* {@link #inverseTransform(UnivariateFunction, double, double, int)}, after
* sampling.
* </p>
* <p>
* As of version 2.0 this no longer implements Serializable.
* </p>
*
* @version $Id: FastSineTransformer.java 1213157 2011-12-12 07:19:23Z celestin$
* @since 1.2
@ -115,7 +110,7 @@ import org.apache.commons.math.util.FastMath;
public class FastSineTransformer implements RealTransformer, Serializable {
/** Serializable version identifier. */
static final long serialVersionUID = 20120501L;
static final long serialVersionUID = 20120211L;
/**
* {@code true} if the orthogonal version of the DCT should be used.
@ -171,54 +166,13 @@ public class FastSineTransformer implements RealTransformer, Serializable {
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two, or the first element of the data array is not zero
*/
public double[] transform(double[] f) throws MathIllegalArgumentException {
public double[] transform(final double[] f, final TransformType type) {
if (orthogonal) {
final double s = FastMath.sqrt(2.0 / f.length);
return TransformUtils.scaleArray(fst(f), s);
}
return fst(f);
}
/**
* {@inheritDoc}
*
* This implementation enforces {@code f(x) = 0.0} at {@code x = 0.0}.
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two
*/
public double[] transform(UnivariateFunction f,
double min, double max, int n) throws
NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
final double[] data = FunctionUtils.sample(f, min, max, n);
data[0] = 0.0;
if (orthogonal) {
final double s = FastMath.sqrt(2.0 / n);
return TransformUtils.scaleArray(fst(data), s);
}
return fst(data);
}
/**
* {@inheritDoc}
*
* The first element of the specified data set is required to be {@code 0}.
*
* @throws MathIllegalArgumentException if the length of the data array is
* not a power of two, or the first element of the data array is not zero
*/
public double[] inverseTransform(double[] f)
throws IllegalArgumentException {
if (orthogonal) {
return transform(f);
if (type == TransformType.FORWARD) {
return fst(f);
}
final double s = 2.0 / f.length;
return TransformUtils.scaleArray(fst(f), s);
@ -229,28 +183,20 @@ public class FastSineTransformer implements RealTransformer, Serializable {
*
* This implementation enforces {@code f(x) = 0.0} at {@code x = 0.0}.
*
* @throws NonMonotonicSequenceException if the lower bound is greater
* than, or equal to the upper bound
* @throws NotStrictlyPositiveException if the number of sample points is
* negative
* @throws org.apache.commons.math.exception.NonMonotonicSequenceException
* if the lower bound is greater than, or equal to the upper bound
* @throws org.apache.commons.math.exception.NotStrictlyPositiveException
* if the number of sample points is negative
* @throws MathIllegalArgumentException if the number of sample points is
* not a power of two
*/
public double[] inverseTransform(UnivariateFunction f,
double min, double max, int n) throws
NonMonotonicSequenceException,
NotStrictlyPositiveException,
MathIllegalArgumentException {
if (orthogonal) {
return transform(f, min, max, n);
}
public double[] transform(final UnivariateFunction f,
final double min, final double max, final int n,
final TransformType type) {
final double[] data = FunctionUtils.sample(f, min, max, n);
data[0] = 0.0;
final double s = 2.0 / n;
return TransformUtils.scaleArray(fst(data), s);
return transform(data, type);
}
/**

View File

@ -34,42 +34,30 @@ import org.apache.commons.math.analysis.UnivariateFunction;
public interface RealTransformer {
/**
* Returns the forward transform of the specified real data set.
* Returns the (forward, inverse) transform of the specified real data set.
*
* @param f the real data array to be transformed (signal)
* @param type the type of transform (forward, inverse) to be performed
* @return the real transformed array (spectrum)
*/
double[] transform(double[] f);
double[] transform(double[] f, TransformType type);
/**
* Returns the forward transform of the specified real function, sampled on
* the specified interval.
* Returns the (forward, inverse) transform of the specified real function,
* sampled on the specified interval.
*
* @param f the function to be sampled and transformed
* @param min the (inclusive) lower bound for the interval
* @param max the (exclusive) upper bound for the interval
* @param n the number of sample points
* @param type the type of transform (forward, inverse) to be performed
* @return the real transformed array
* @throws org.apache.commons.math.exception.NonMonotonicSequenceException
* if the lower bound is greater than, or equal to the upper bound
* @throws org.apache.commons.math.exception.NotStrictlyPositiveException
* if the number of sample points is negative
*/
double[] transform(UnivariateFunction f, double min, double max, int n);
/**
* Returns the inverse transform of the specified real data set.
*
* @param f the real data array to be inversely transformed
* @return the real inversely transformed array
*/
double[] inverseTransform(double[] f);
/**
* Returns the inverse transform of the specified real function, sampled
* on the given interval.
*
* @param f the function to be sampled and inversely transformed
* @param min the (inclusive) lower bound for the interval
* @param max the (exclusive) upper bound for the interval
* @param n the number of sample points
* @return the real inversely transformed array
*/
double[] inverseTransform(UnivariateFunction f, double min, double max, int n);
double[] transform(UnivariateFunction f,
double min, double max, int n,
TransformType type);
}

View File

@ -22,6 +22,7 @@ import java.util.Collection;
import org.apache.commons.math.analysis.SinFunction;
import org.apache.commons.math.analysis.UnivariateFunction;
import org.apache.commons.math.analysis.function.Sinc;
import org.apache.commons.math.exception.MathIllegalStateException;
import org.apache.commons.math.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
@ -130,7 +131,7 @@ public final class FastCosineTransformerTest
}
@Override
double[] transform(final double[] x, final boolean forward) {
double[] transform(final double[] x, final TransformType type) {
final int n = x.length;
final double[] y = new double[n];
final double[] cos = new double[2 * (n - 1)];
@ -147,10 +148,16 @@ public final class FastCosineTransformerTest
sgn *= -1;
}
final double s;
if (forward) {
if (type == TransformType.FORWARD) {
s = standard ? 1.0 : FastMath.sqrt(2.0 / (n - 1.0));
} else {
} else if (type == TransformType.INVERSE) {
s = standard ? 2.0 / (n - 1.0) : FastMath.sqrt(2.0 / (n - 1.0));
} else {
/*
* Should never occur. This clause is a safeguard in case other
* types are used to TransformType (which should not be done).
*/
throw new MathIllegalStateException();
}
TransformUtils.scaleArray(y, s);
return y;
@ -176,12 +183,12 @@ public final class FastCosineTransformerTest
4.0
};
result = transformer.transform(x);
result = transformer.transform(x, TransformType.FORWARD);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(y[i], result[i], tolerance);
}
result = transformer.inverseTransform(y);
result = transformer.transform(y, TransformType.INVERSE);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(x[i], result[i], tolerance);
}
@ -189,12 +196,12 @@ public final class FastCosineTransformerTest
TransformUtils.scaleArray(x, FastMath.sqrt(0.5 * (x.length - 1)));
transformer = FastCosineTransformer.createOrthogonal();
result = transformer.transform(y);
result = transformer.transform(y, TransformType.FORWARD);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(x[i], result[i], tolerance);
}
result = transformer.inverseTransform(x);
result = transformer.transform(x, TransformType.INVERSE);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(y[i], result[i], tolerance);
}
@ -209,14 +216,14 @@ public final class FastCosineTransformerTest
try {
// bad interval
transformer.transform(f, 1, -1, 65);
transformer.transform(f, 1, -1, 65, TransformType.FORWARD);
Assert.fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// bad samples number
transformer.transform(f, -1, 1, 1);
transformer.transform(f, -1, 1, 1, TransformType.FORWARD);
Assert
.fail("Expecting IllegalArgumentException - bad samples number");
} catch (IllegalArgumentException ex) {
@ -224,7 +231,7 @@ public final class FastCosineTransformerTest
}
try {
// bad samples number
transformer.transform(f, -1, 1, 64);
transformer.transform(f, -1, 1, 64, TransformType.FORWARD);
Assert
.fail("Expecting IllegalArgumentException - bad samples number");
} catch (IllegalArgumentException ex) {
@ -247,14 +254,14 @@ public final class FastCosineTransformerTest
};
min = 0.0;
max = 2.0 * FastMath.PI * N / (N - 1);
result = transformer.transform(f, min, max, N);
result = transformer.transform(f, min, max, N, TransformType.FORWARD);
for (int i = 0; i < N; i++) {
Assert.assertEquals(expected[i], result[i], tolerance);
}
min = -FastMath.PI;
max = FastMath.PI * (N + 1) / (N - 1);
result = transformer.transform(f, min, max, N);
result = transformer.transform(f, min, max, N, TransformType.FORWARD);
for (int i = 0; i < N; i++) {
Assert.assertEquals(-expected[i], result[i], tolerance);
}

View File

@ -517,8 +517,6 @@ public final class FastFourierTransformerTest {
for (int i = 0; i < input.length; i++) {
for (int j = 0; j < input[0].length; j++) {
System.out.println(i + ", " + j + ", " + input[i][j] + ", " +
goodOutput[i][j] + ", " + output[i][j] + ", ");
Assert.assertEquals(input[i][j].getImaginary(), output2[i][j].getImaginary(),
tolerance);
Assert.assertEquals(input[i][j].getReal(), output2[i][j].getReal(), tolerance);

View File

@ -51,7 +51,7 @@ public final class FastHadamardTransformerTest {
@Test
public void testNoIntInverse() {
FastHadamardTransformer transformer = new FastHadamardTransformer();
double[] x = transformer.inverseTransform(new double[] { 0, 1, 0, 1});
double[] x = transformer.transform(new double[] { 0, 1, 0, 1}, TransformType.INVERSE);
Assert.assertEquals( 0.5, x[0], 0);
Assert.assertEquals(-0.5, x[1], 0);
Assert.assertEquals( 0.0, x[2], 0);
@ -64,7 +64,7 @@ public final class FastHadamardTransformerTest {
@Test
public void test3Points() {
try {
new FastHadamardTransformer().transform(new double[3]);
new FastHadamardTransformer().transform(new double[3], TransformType.FORWARD);
Assert.fail("an exception should have been thrown");
} catch (IllegalArgumentException iae) {
// expected
@ -86,7 +86,7 @@ public final class FastHadamardTransformerTest {
for (int i = 0; i < dX.length; ++i) {
dX[i] = x[i];
}
double dResult[] = transformer.transform(dX);
double dResult[] = transformer.transform(dX, TransformType.FORWARD);
for (int i = 0; i < dResult.length; i++) {
// compare computed results to precomputed results
Assert.assertTrue(Precision.equals(y[i], dResult[i], 1));
@ -115,7 +115,7 @@ public final class FastHadamardTransformerTest {
for (int i = 0; i < dY.length; ++i) {
dY[i] = y[i];
}
double dResult[] = transformer.inverseTransform(dY);
double dResult[] = transformer.transform(dY, TransformType.INVERSE);
for (int i = 0; i < dResult.length; i++) {
// compare computed results to precomputed results
Assert.assertTrue(Precision.equals(x[i], dResult[i], 1));

View File

@ -23,6 +23,7 @@ import org.apache.commons.math.analysis.SinFunction;
import org.apache.commons.math.analysis.UnivariateFunction;
import org.apache.commons.math.analysis.function.Sinc;
import org.apache.commons.math.exception.MathIllegalArgumentException;
import org.apache.commons.math.exception.MathIllegalStateException;
import org.apache.commons.math.util.FastMath;
import org.junit.Assert;
import org.junit.Test;
@ -143,7 +144,7 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
}
@Override
double[] transform(final double[] x, final boolean forward) {
double[] transform(final double[] x, final TransformType type) {
final int n = x.length;
final double[] y = new double[n];
final double[] sin = new double[2 * n];
@ -158,10 +159,16 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
y[j] = yj;
}
final double s;
if (forward) {
if (type == TransformType.FORWARD) {
s = standard ? 1.0 : FastMath.sqrt(2.0 / (double) n);
} else {
} else if (type == TransformType.INVERSE){
s = standard ? 2.0 / n : FastMath.sqrt(2.0 / (double) n);
} else {
/*
* Should never occur. This clause is a safeguard in case other
* types are used to TransformType (which should not be done).
*/
throw new MathIllegalStateException();
}
TransformUtils.scaleArray(y, s);
return y;
@ -170,22 +177,21 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
/*
* Additional tests.
*/
@Test(expected = MathIllegalArgumentException.class)
@Test
public void testTransformRealFirstElementNotZero() {
final TransformType[] type = TransformType.values();
final double[] data = new double[] {
1.0, 1.0, 1.0, 1.0
};
final RealTransformer transformer = createRealTransformer();
transformer.transform(data);
}
@Test(expected = MathIllegalArgumentException.class)
public void testInverseTransformRealFirstElementNotZero() {
final double[] data = new double[] {
1.0, 1.0, 1.0, 1.0
};
final RealTransformer transformer = createRealTransformer();
transformer.inverseTransform(data);
for (int j = 0; j < type.length; j++) {
try {
transformer.transform(data, type[j]);
Assert.fail(type[j].toString());
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
}
}
}
/*
@ -205,12 +211,12 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
5.98642305066196, -4.0, 2.67271455167720,
-1.65685424949238, 0.795649469518633 };
result = transformer.transform(x);
result = transformer.transform(x, TransformType.FORWARD);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(y[i], result[i], tolerance);
}
result = transformer.inverseTransform(y);
result = transformer.transform(y, TransformType.INVERSE);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(x[i], result[i], tolerance);
}
@ -218,12 +224,12 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
TransformUtils.scaleArray(x, FastMath.sqrt(x.length / 2.0));
transformer = FastSineTransformer.createOrthogonal();
result = transformer.transform(y);
result = transformer.transform(y, TransformType.FORWARD);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(x[i], result[i], tolerance);
}
result = transformer.inverseTransform(x);
result = transformer.transform(x, TransformType.INVERSE);
for (int i = 0; i < result.length; i++) {
Assert.assertEquals(y[i], result[i], tolerance);
}
@ -239,14 +245,14 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
double min, max, result[], tolerance = 1E-12; int N = 1 << 8;
min = 0.0; max = 2.0 * FastMath.PI;
result = transformer.transform(f, min, max, N);
result = transformer.transform(f, min, max, N, TransformType.FORWARD);
Assert.assertEquals(N >> 1, result[2], tolerance);
for (int i = 0; i < N; i += (i == 1 ? 2 : 1)) {
Assert.assertEquals(0.0, result[i], tolerance);
}
min = -FastMath.PI; max = FastMath.PI;
result = transformer.transform(f, min, max, N);
result = transformer.transform(f, min, max, N, TransformType.FORWARD);
Assert.assertEquals(-(N >> 1), result[2], tolerance);
for (int i = 0; i < N; i += (i == 1 ? 2 : 1)) {
Assert.assertEquals(0.0, result[i], tolerance);
@ -263,21 +269,21 @@ public final class FastSineTransformerTest extends RealTransformerAbstractTest {
try {
// bad interval
transformer.transform(f, 1, -1, 64);
transformer.transform(f, 1, -1, 64, TransformType.FORWARD);
Assert.fail("Expecting IllegalArgumentException - bad interval");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// bad samples number
transformer.transform(f, -1, 1, 0);
transformer.transform(f, -1, 1, 0, TransformType.FORWARD);
Assert.fail("Expecting IllegalArgumentException - bad samples number");
} catch (IllegalArgumentException ex) {
// expected
}
try {
// bad samples number
transformer.transform(f, -1, 1, 100);
transformer.transform(f, -1, 1, 100, TransformType.FORWARD);
Assert.fail("Expecting IllegalArgumentException - bad samples number");
} catch (IllegalArgumentException ex) {
// expected

View File

@ -137,181 +137,107 @@ public abstract class RealTransformerAbstractTest {
* Returns the expected transform of the specified real data array.
*
* @param x the real data array to be transformed
* @param forward {@code true} (resp. {@code false}) if the forward (resp.
* inverse) transform is to be performed
* @param type the type of transform (forward, inverse) to be performed
* @return the expected transform
*/
abstract double[] transform(double[] x, boolean forward);
abstract double[] transform(double[] x, TransformType type);
/*
* Check of preconditions.
*/
/**
* {@link RealTransformer#transform(double[])} should throw a
* {@link RealTransformer#transform(double[], TransformType))} should throw a
* {@link MathIllegalArgumentException} if data size is invalid.
*/
@Test
public void testTransformRealInvalidDataSize() {
final TransformType[] type = TransformType.values();
final RealTransformer transformer = createRealTransformer();
for (int i = 0; i < getNumberOfInvalidDataSizes(); i++) {
final int n = getInvalidDataSize(i);
try {
transformer.transform(createRealData(n));
Assert.fail(Integer.toString(n));
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
for (int j = 0; j < type.length; j++) {
try {
transformer.transform(createRealData(n), type[j]);
Assert.fail(type[j] + ", " + n);
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
}
}
}
}
/**
* {@link RealTransformer#transform(UnivariateFunction, double, double, int)}
* {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}
* should throw a {@link MathIllegalArgumentException} if number of samples
* is invalid.
*/
@Test
public void testTransformFunctionInvalidDataSize() {
final TransformType[] type = TransformType.values();
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
final double b = getValidUpperBound();
for (int i = 0; i < getNumberOfInvalidDataSizes(); i++) {
final int n = getInvalidDataSize(i);
try {
transformer.transform(f, a, b, n);
Assert.fail(Integer.toString(n));
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
for (int j = 0; j < type.length; j++) {
try {
transformer.transform(f, a, b, n, type[j]);
Assert.fail(type[j] + ", " + n);
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
}
}
}
}
/**
* {@link RealTransformer#transform(UnivariateFunction, double, double, int)}
* {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}
* should throw a {@link NotStrictlyPositiveException} if number of samples
* is not strictly positive.
*/
@Test
public void testTransformFunctionNotStrictlyPositiveNumberOfSamples() {
final TransformType[] type = TransformType.values();
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
final double b = getValidUpperBound();
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
try {
transformer.transform(f, a, b, -n);
Assert.fail(Integer.toString(-n));
} catch (NotStrictlyPositiveException e) {
// Expected: do nothing
for (int j = 0; j < type.length; j++) {
try {
transformer.transform(f, a, b, -n, type[j]);
Assert.fail(type[j] + ", " + (-n));
} catch (NotStrictlyPositiveException e) {
// Expected: do nothing
}
}
}
}
/**
* {@link RealTransformer#transform(UnivariateFunction, double, double, int)}
* {@link RealTransformer#transform(UnivariateFunction, double, double, int, TransformType)}
* should throw a {@link NumberIsTooLargeException} if sampling bounds are
* not correctly ordered.
*/
@Test
public void testTransformFunctionInvalidBounds() {
final TransformType[] type = TransformType.values();
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
final double b = getValidUpperBound();
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
try {
transformer.transform(f, b, a, n);
Assert.fail(Double.toString(b) + ", " + Double.toString(a));
} catch (NumberIsTooLargeException e) {
// Expected: do nothing
}
}
}
/**
* {@link RealTransformer#inverseTransform(double[])} should throw a
* {@link MathIllegalArgumentException} if data size is invalid.
*/
@Test
public void testInverseTransformRealInvalidDataSize() {
final RealTransformer transformer = createRealTransformer();
for (int i = 0; i < getNumberOfInvalidDataSizes(); i++) {
final int n = getInvalidDataSize(i);
try {
transformer.inverseTransform(createRealData(n));
Assert.fail(Integer.toString(n));
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
}
}
}
/**
* {@link RealTransformer#inverseTransform(UnivariateFunction, double, double, int)}
* should throw a {@link MathIllegalArgumentException} if number of samples
* is invalid.
*/
@Test
public void testInverseTransformFunctionInvalidDataSize() {
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
final double b = getValidUpperBound();
for (int i = 0; i < getNumberOfInvalidDataSizes(); i++) {
final int n = getInvalidDataSize(i);
try {
transformer.inverseTransform(f, a, b, n);
Assert.fail(Integer.toString(n));
} catch (MathIllegalArgumentException e) {
// Expected: do nothing
}
}
}
/**
* {@link RealTransformer#inverseTransform(UnivariateFunction, double, double, int)}
* should throw a {@link NotStrictlyPositiveException} if number of samples
* is not strictly positive.
*/
@Test
public void
testInverseTransformFunctionNotStrictlyPositiveNumberOfSamples() {
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
final double b = getValidUpperBound();
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
try {
transformer.inverseTransform(f, a, b, -n);
Assert.fail(Integer.toString(-n));
} catch (NotStrictlyPositiveException e) {
// Expected: do nothing
}
}
}
/**
* {@link RealTransformer#inverseTransform(UnivariateFunction, double, double, int)}
* should throw a {@link NumberIsTooLargeException} if sampling bounds are
* not correctly ordered.
*/
@Test
public void testInverseTransformFunctionInvalidBounds() {
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
final double b = getValidUpperBound();
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
try {
transformer.inverseTransform(f, b, a, n);
Assert.fail(Double.toString(b) + ", " + Double.toString(a));
} catch (NumberIsTooLargeException e) {
// Expected: do nothing
for (int j = 0; j < type.length; j++) {
try {
transformer.transform(f, b, a, n, type[j]);
Assert.fail(type[j] + ", " + b + ", " + a);
} catch (NumberIsTooLargeException e) {
// Expected: do nothing
}
}
}
}
@ -333,10 +259,13 @@ public abstract class RealTransformerAbstractTest {
*/
@Test
public void testTransformReal() {
final TransformType[] type = TransformType.values();
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
final double tol = getRelativeTolerance(i);
doTestTransformReal(n, tol, true);
for (int j = 0; j < type.length; j++) {
doTestTransformReal(n, tol, type[j]);
}
}
}
@ -353,50 +282,13 @@ public abstract class RealTransformerAbstractTest {
*/
@Test
public void testTransformFunction() {
final TransformType[] type = TransformType.values();
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
final double tol = getRelativeTolerance(i);
doTestTransformFunction(n, tol, true);
}
}
/**
* Accuracy check of {@link RealTransformer#inverseTransform(double[])}. For
* each valid data size returned by
* {@link #getValidDataSize(int) getValidDataSize(i)},
* a random data array is generated with
* {@link RealTransformerAbstractTest#createRealData(int)}. The actual
* transform is computed and compared to the expected transform, return by
* {@link #transform(double[], boolean)}. Actual and expected values should
* be equal to within the relative error returned by
* {@link #getRelativeTolerance(int) getRelativeTolerance(i)}.
*/
@Test
public void testInverseTransformReal() {
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
final double tol = getRelativeTolerance(i);
doTestTransformReal(n, tol, false);
}
}
/**
* Accuracy check of
* {@link RealTransformer#inverseTransform(UnivariateFunction, double, double, int)}.
* For each valid data size returned by
* {@link #getValidDataSize(int) getValidDataSize(i)},
* the {@link UnivariateFunction} returned by {@link #getValidFunction()} is
* sampled. The actual transform is computed and compared to the expected
* transform, return by {@link #transform(double[], boolean)}. Actual and
* expected values should be equal to within the relative error returned by
* {@link #getRelativeTolerance(int) getRelativeTolerance(i)}.
*/
@Test
public void testInverseTransformFunction() {
for (int i = 0; i < getNumberOfValidDataSizes(); i++) {
final int n = getValidDataSize(i);
final double tol = getRelativeTolerance(i);
doTestTransformFunction(n, tol, false);
for (int j = 0; j < type.length; j++) {
doTestTransformFunction(n, tol, type[j]);
}
}
}
@ -425,16 +317,11 @@ public abstract class RealTransformerAbstractTest {
*/
private void doTestTransformReal(final int n, final double tol,
final boolean forward) {
final TransformType type) {
final RealTransformer transformer = createRealTransformer();
final double[] x = createRealData(n);
final double[] expected = transform(x, forward);
final double[] actual;
if (forward) {
actual = transformer.transform(x);
} else {
actual = transformer.inverseTransform(x);
}
final double[] expected = transform(x, type);
final double[] actual = transformer.transform(x, type);
for (int i = 0; i < n; i++) {
final String msg = String.format("%d, %d", n, i);
final double delta = tol * FastMath.abs(expected[i]);
@ -443,7 +330,7 @@ public abstract class RealTransformerAbstractTest {
}
private void doTestTransformFunction(final int n, final double tol,
final boolean forward) {
final TransformType type) {
final RealTransformer transformer = createRealTransformer();
final UnivariateFunction f = getValidFunction();
final double a = getValidLowerBound();
@ -453,13 +340,8 @@ public abstract class RealTransformerAbstractTest {
final double t = a + i * (b - a) / n;
x[i] = f.value(t);
}
final double[] expected = transform(x, forward);
final double[] actual;
if (forward) {
actual = transformer.transform(f, a, b, n);
} else {
actual = transformer.inverseTransform(f, a, b, n);
}
final double[] expected = transform(x, type);
final double[] actual = transformer.transform(f, a, b, n, type);
for (int i = 0; i < n; i++) {
final String msg = String.format("%d, %d", n, i);
final double delta = tol * FastMath.abs(expected[i]);