In o.a.c.m.transform, introduced an enumeration for the type (forward, inverse) of transform asked by the user (MATH-743).
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1242703 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
49c39e7d1c
commit
dee1c0d70b
|
@ -25,7 +25,7 @@ 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.transform.FastFourierTransformer.Normalization;
|
||||
import org.apache.commons.math.transform.FastFourierTransformer.DftNormalization;
|
||||
import org.apache.commons.math.util.ArithmeticUtils;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
|
||||
|
@ -273,8 +273,8 @@ public class FastCosineTransformer implements RealTransformer, Serializable {
|
|||
t1 += c;
|
||||
}
|
||||
FastFourierTransformer transformer;
|
||||
transformer = new FastFourierTransformer(Normalization.STANDARD);
|
||||
Complex[] y = transformer.transform(x);
|
||||
transformer = new FastFourierTransformer(DftNormalization.STANDARD);
|
||||
Complex[] y = transformer.transform(x, TransformType.FORWARD);
|
||||
|
||||
// reconstruct the FCT result for the original array
|
||||
transformed[0] = y[0].getReal();
|
||||
|
|
|
@ -85,17 +85,22 @@ import org.apache.commons.math.util.MathArrays;
|
|||
*/
|
||||
public class FastFourierTransformer implements Serializable {
|
||||
|
||||
/** The various types of normalizations that can be applied. */
|
||||
public static enum Normalization {
|
||||
/** Standard DFT. */
|
||||
/**
|
||||
* The various types of normalizations that can be applied to discrete
|
||||
* Fourier transforms.
|
||||
*
|
||||
* @see FastFourierTransformer
|
||||
*/
|
||||
public static enum DftNormalization {
|
||||
/** The normalization to be specified for standard DFT. */
|
||||
STANDARD,
|
||||
|
||||
/** Unitary DFT. */
|
||||
/** The normalization to be specified for unitary DFT. */
|
||||
UNITARY;
|
||||
}
|
||||
|
||||
/** Serializable version identifier. */
|
||||
static final long serialVersionUID = 20120902L;
|
||||
static final long serialVersionUID = 20120210L;
|
||||
|
||||
/**
|
||||
* {@code W_SUB_N_R[i]} is the real part of
|
||||
|
@ -143,19 +148,18 @@ public class FastFourierTransformer implements Serializable {
|
|||
, -0x1.921fb54442d18p-54, -0x1.921fb54442d18p-55, -0x1.921fb54442d18p-56, -0x1.921fb54442d18p-57
|
||||
, -0x1.921fb54442d18p-58, -0x1.921fb54442d18p-59, -0x1.921fb54442d18p-60 };
|
||||
|
||||
/**
|
||||
* The type of DFT to be performed.
|
||||
*/
|
||||
private final Normalization type;
|
||||
/** The type of DFT to be performed. */
|
||||
private final DftNormalization normalization;
|
||||
|
||||
/**
|
||||
* Creates a new instance of this class, with various normalization
|
||||
* conventions.
|
||||
*
|
||||
* @param type the type of transform to be computed
|
||||
* @param normalization the type of normalization to be applied to the
|
||||
* transformed data
|
||||
*/
|
||||
public FastFourierTransformer(final Normalization type) {
|
||||
this.type = type;
|
||||
public FastFourierTransformer(final DftNormalization normalization) {
|
||||
this.normalization = normalization;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,21 +203,21 @@ public class FastFourierTransformer implements Serializable {
|
|||
* Applies the proper normalization to the specified transformed data.
|
||||
*
|
||||
* @param dataRI the unscaled transformed data
|
||||
* @param type the type of transform
|
||||
* @param inverse {@code true} if normalization should be performed for the
|
||||
* inverse transform
|
||||
* @param normalization the normalization to be applied
|
||||
* @param type the type of transform (forward, inverse) which resulted in the
|
||||
* specified data
|
||||
*/
|
||||
private static void normalizeTransformedData(final double[][] dataRI,
|
||||
final Normalization type, final boolean inverse) {
|
||||
final DftNormalization normalization, final TransformType type) {
|
||||
|
||||
final double[] dataR = dataRI[0];
|
||||
final double[] dataI = dataRI[1];
|
||||
final int n = dataR.length;
|
||||
assert dataI.length == n;
|
||||
|
||||
switch (type) {
|
||||
switch (normalization) {
|
||||
case STANDARD:
|
||||
if (inverse) {
|
||||
if (type == TransformType.INVERSE) {
|
||||
final double scaleFactor = 1.0 / ((double) n);
|
||||
for (int i = 0; i < n; i++) {
|
||||
dataR[i] *= scaleFactor;
|
||||
|
@ -251,18 +255,16 @@ public class FastFourierTransformer implements Serializable {
|
|||
*
|
||||
* @param dataRI the two dimensional array of real and imaginary parts of
|
||||
* the data
|
||||
* @param type the type of normalization to be applied to the transformed
|
||||
* @param normalization the normalization to be applied to the transformed
|
||||
* data
|
||||
* @param inverse {@code true} if the inverse standard transform must be
|
||||
* performed
|
||||
* @param type the type of transform (forward, inverse) to be performed
|
||||
* @throws DimensionMismatchException if the number of rows of the specified
|
||||
* array is not two, or the array is not rectangular
|
||||
* @throws MathIllegalArgumentException if the number of data points is not
|
||||
* a power of two
|
||||
*/
|
||||
public static void transformInPlace(final double[][] dataRI,
|
||||
final Normalization type, final boolean inverse) throws
|
||||
DimensionMismatchException, MathIllegalArgumentException {
|
||||
final DftNormalization normalization, final TransformType type) {
|
||||
|
||||
if (dataRI.length != 2) {
|
||||
throw new DimensionMismatchException(dataRI.length, 2);
|
||||
|
@ -295,14 +297,14 @@ public class FastFourierTransformer implements Serializable {
|
|||
dataR[1] = srcR0 - srcR1;
|
||||
dataI[1] = srcI0 - srcI1;
|
||||
|
||||
normalizeTransformedData(dataRI, type, inverse);
|
||||
normalizeTransformedData(dataRI, normalization, type);
|
||||
return;
|
||||
}
|
||||
|
||||
bitReversalShuffle2(dataR, dataI);
|
||||
|
||||
// Do 4-term DFT.
|
||||
if (inverse) {
|
||||
if (type == TransformType.INVERSE) {
|
||||
for (int i0 = 0; i0 < n; i0 += 4) {
|
||||
final int i1 = i0 + 1;
|
||||
final int i2 = i0 + 2;
|
||||
|
@ -369,7 +371,7 @@ public class FastFourierTransformer implements Serializable {
|
|||
int logN0 = lastLogN0 + 1;
|
||||
double wSubN0R = W_SUB_N_R[logN0];
|
||||
double wSubN0I = W_SUB_N_I[logN0];
|
||||
if (inverse) {
|
||||
if (type == TransformType.INVERSE) {
|
||||
wSubN0I = -wSubN0I;
|
||||
}
|
||||
|
||||
|
@ -405,41 +407,37 @@ public class FastFourierTransformer implements Serializable {
|
|||
lastLogN0 = logN0;
|
||||
}
|
||||
|
||||
normalizeTransformedData(dataRI, type, inverse);
|
||||
normalizeTransformedData(dataRI, normalization, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param type the type of transform (forward, inverse) to be performed
|
||||
* @return the complex transformed array
|
||||
* @throws MathIllegalArgumentException if the length of the data array is
|
||||
* not a power of two
|
||||
*/
|
||||
public Complex[] transform(double[] f) {
|
||||
public Complex[] transform(final double[] f, final TransformType type) {
|
||||
final double[][] dataRI = new double[][] {
|
||||
MathArrays.copyOf(f, f.length), new double[f.length]
|
||||
};
|
||||
|
||||
transformInPlace(dataRI, type, false);
|
||||
|
||||
// if (unitary) {
|
||||
// final double s = 1.0 / FastMath.sqrt(f.length);
|
||||
// TransformUtils.scaleArray(dataRI[0], s);
|
||||
// TransformUtils.scaleArray(dataRI[1], s);
|
||||
// }
|
||||
transformInPlace(dataRI, normalization, type);
|
||||
|
||||
return TransformUtils.createComplexArray(dataRI);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 complex transformed array
|
||||
* @throws org.apache.commons.math.exception.NumberIsTooLargeException
|
||||
* if the lower bound is greater than, or equal to the upper bound
|
||||
|
@ -448,98 +446,28 @@ public class FastFourierTransformer implements Serializable {
|
|||
* @throws MathIllegalArgumentException if the number of sample points
|
||||
* {@code n} is not a power of two
|
||||
*/
|
||||
public Complex[] transform(UnivariateFunction f,
|
||||
double min, double max, int n) {
|
||||
public Complex[] 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 transform(data);
|
||||
return transform(data, type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the forward transform of the specified complex data set.
|
||||
* Returns the (forward, inverse) transform of the specified complex data
|
||||
* set.
|
||||
*
|
||||
* @param f the complex data array to be transformed
|
||||
* @param type the type of transform (forward, inverse) to be performed
|
||||
* @return the complex transformed array
|
||||
* @throws MathIllegalArgumentException if the length of the data array is
|
||||
* not a power of two
|
||||
*/
|
||||
public Complex[] transform(Complex[] f) {
|
||||
public Complex[] transform(final Complex[] f, final TransformType type) {
|
||||
final double[][] dataRI = TransformUtils.createRealImaginaryArray(f);
|
||||
|
||||
transformInPlace(dataRI, type, false);
|
||||
// if (unitary) {
|
||||
// final double s = 1.0 / FastMath.sqrt(f.length);
|
||||
// TransformUtils.scaleArray(dataRI[0], s);
|
||||
// TransformUtils.scaleArray(dataRI[1], s);
|
||||
// }
|
||||
|
||||
return TransformUtils.createComplexArray(dataRI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inverse transform of the specified real data set.
|
||||
*
|
||||
* @param f the real data array to be inversely transformed
|
||||
* @return the complex inversely transformed array
|
||||
* @throws MathIllegalArgumentException if the length of the data array is
|
||||
* not a power of two
|
||||
*/
|
||||
public Complex[] inverseTransform(double[] f) {
|
||||
final double[][] dataRI = new double[][] {
|
||||
MathArrays.copyOf(f, f.length), new double[f.length]
|
||||
};
|
||||
|
||||
transformInPlace(dataRI, type, true);
|
||||
// if (unitary) {
|
||||
// final double s = FastMath.sqrt(f.length);
|
||||
// TransformUtils.scaleArray(dataRI[0], s);
|
||||
// TransformUtils.scaleArray(dataRI[1], s);
|
||||
// }
|
||||
|
||||
return TransformUtils.createComplexArray(dataRI);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 complex inversely transformed array
|
||||
* @throws org.apache.commons.math.exception.NumberIsTooLargeException
|
||||
* 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 {@code n} is negative
|
||||
* @throws MathIllegalArgumentException if the number of sample points
|
||||
* {@code n} is not a power of two
|
||||
*/
|
||||
public Complex[] inverseTransform(UnivariateFunction f,
|
||||
double min, double max, int n) {
|
||||
final double[] data = FunctionUtils.sample(f, min, max, n);
|
||||
return inverseTransform(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inverse transform of the specified complex data set.
|
||||
*
|
||||
* @param f the complex data array to be inversely transformed
|
||||
* @return the complex inversely transformed array
|
||||
* @throws MathIllegalArgumentException if the length of the data array is
|
||||
* not a power of two
|
||||
*/
|
||||
public Complex[] inverseTransform(Complex[] f) {
|
||||
final double[][] dataRI = TransformUtils.createRealImaginaryArray(f);
|
||||
final double[] dataR = dataRI[0];
|
||||
final double[] dataI = dataRI[1];
|
||||
|
||||
transformInPlace(dataRI, type, true);
|
||||
// if (unitary) {
|
||||
// final double s = FastMath.sqrt(f.length);
|
||||
// TransformUtils.scaleArray(dataR, s);
|
||||
// TransformUtils.scaleArray(dataI, s);
|
||||
// }
|
||||
transformInPlace(dataRI, normalization, type);
|
||||
|
||||
return TransformUtils.createComplexArray(dataRI);
|
||||
}
|
||||
|
@ -555,19 +483,20 @@ public class FastFourierTransformer implements Serializable {
|
|||
*
|
||||
* @param mdca Multi-Dimensional Complex Array id est
|
||||
* {@code Complex[][][][]}
|
||||
* @param forward {@link #inverseTransform} is performed if this is
|
||||
* {@code false}
|
||||
* @param type the type of transform (forward, inverse) to be performed
|
||||
* @return transform of {@code mdca} as a Multi-Dimensional Complex Array
|
||||
* id est {@code Complex[][][][]}
|
||||
* @throws IllegalArgumentException if any dimension is not a power of two
|
||||
* @deprecated see MATH-736
|
||||
*/
|
||||
public Object mdfft(Object mdca, boolean forward) {
|
||||
@Deprecated
|
||||
public Object mdfft(Object mdca, TransformType type) {
|
||||
MultiDimensionalComplexMatrix mdcm = (MultiDimensionalComplexMatrix)
|
||||
new MultiDimensionalComplexMatrix(mdca).clone();
|
||||
int[] dimensionSize = mdcm.getDimensionSizes();
|
||||
//cycle through each dimension
|
||||
for (int i = 0; i < dimensionSize.length; i++) {
|
||||
mdfft(mdcm, forward, i, new int[0]);
|
||||
mdfft(mdcm, type, i, new int[0]);
|
||||
}
|
||||
return mdcm.getArray();
|
||||
}
|
||||
|
@ -576,14 +505,15 @@ public class FastFourierTransformer implements Serializable {
|
|||
* Performs one dimension of a multi-dimensional Fourier transform.
|
||||
*
|
||||
* @param mdcm input matrix
|
||||
* @param forward {@link #inverseTransform} is performed if this is
|
||||
* {@code false}
|
||||
* @param type the type of transform (forward, inverse) to be performed
|
||||
* @param d index of the dimension to process
|
||||
* @param subVector recursion subvector
|
||||
* @throws IllegalArgumentException if any dimension is not a power of two
|
||||
* @deprecated see MATH-736
|
||||
*/
|
||||
@Deprecated
|
||||
private void mdfft(MultiDimensionalComplexMatrix mdcm,
|
||||
boolean forward, int d, int[] subVector) {
|
||||
TransformType type, int d, int[] subVector) {
|
||||
|
||||
int[] dimensionSize = mdcm.getDimensionSizes();
|
||||
//if done
|
||||
|
@ -595,11 +525,7 @@ public class FastFourierTransformer implements Serializable {
|
|||
temp[i] = mdcm.get(subVector);
|
||||
}
|
||||
|
||||
if (forward) {
|
||||
temp = transform(temp);
|
||||
} else {
|
||||
temp = inverseTransform(temp);
|
||||
}
|
||||
temp = transform(temp, type);
|
||||
|
||||
for (int i = 0; i < dimensionSize[d]; i++) {
|
||||
subVector[d] = i;
|
||||
|
@ -612,12 +538,12 @@ public class FastFourierTransformer implements Serializable {
|
|||
//value is not important once the recursion is done.
|
||||
//then an fft will be applied along the dimension d.
|
||||
vector[d] = 0;
|
||||
mdfft(mdcm, forward, d, vector);
|
||||
mdfft(mdcm, type, d, vector);
|
||||
} else {
|
||||
for (int i = 0; i < dimensionSize[subVector.length]; i++) {
|
||||
vector[subVector.length] = i;
|
||||
//further split along the next dimension
|
||||
mdfft(mdcm, forward, d, vector);
|
||||
mdfft(mdcm, type, d, vector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -629,7 +555,10 @@ public class FastFourierTransformer implements Serializable {
|
|||
* eventually be replaced by jsr-83 of the java community process
|
||||
* http://jcp.org/en/jsr/detail?id=83
|
||||
* may require additional exception throws for other basic requirements.
|
||||
*
|
||||
* @deprecated see MATH-736
|
||||
*/
|
||||
@Deprecated
|
||||
private static class MultiDimensionalComplexMatrix
|
||||
implements Cloneable {
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ 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.transform.FastFourierTransformer.Normalization;
|
||||
import org.apache.commons.math.transform.FastFourierTransformer.DftNormalization;
|
||||
import org.apache.commons.math.util.ArithmeticUtils;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
|
||||
|
@ -294,8 +294,8 @@ public class FastSineTransformer implements RealTransformer, Serializable {
|
|||
x[n - i] = a - b;
|
||||
}
|
||||
FastFourierTransformer transformer;
|
||||
transformer = new FastFourierTransformer(Normalization.STANDARD);
|
||||
Complex[] y = transformer.transform(x);
|
||||
transformer = new FastFourierTransformer(DftNormalization.STANDARD);
|
||||
Complex[] y = transformer.transform(x, TransformType.FORWARD);
|
||||
|
||||
// reconstruct the FST result for the original array
|
||||
transformed[0] = 0.0;
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.transform;
|
||||
|
||||
/**
|
||||
* This enumeration defines the type of transform which is to be computed.
|
||||
*
|
||||
* @version $Id Revision$
|
||||
* @since 3.0
|
||||
*/
|
||||
public enum TransformType {
|
||||
/** The type to be specified for forward transforms. */
|
||||
FORWARD,
|
||||
|
||||
/** The type to be specified for inverse transforms. */
|
||||
INVERSE;
|
||||
}
|
|
@ -26,7 +26,7 @@ import org.apache.commons.math.complex.Complex;
|
|||
import org.apache.commons.math.exception.MathIllegalArgumentException;
|
||||
import org.apache.commons.math.exception.NotStrictlyPositiveException;
|
||||
import org.apache.commons.math.exception.NumberIsTooLargeException;
|
||||
import org.apache.commons.math.transform.FastFourierTransformer.Normalization;
|
||||
import org.apache.commons.math.transform.FastFourierTransformer.DftNormalization;
|
||||
import org.apache.commons.math.util.FastMath;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -44,191 +44,123 @@ public final class FastFourierTransformerTest {
|
|||
private final static long SEED = 20110111L;
|
||||
|
||||
/*
|
||||
* Precondition checks for standard transform.
|
||||
* Precondition checks.
|
||||
*/
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testStandardTransformComplexSizeNotAPowerOfTwo() {
|
||||
@Test
|
||||
public void testTransformComplexSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final Complex[] x = createComplexData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.transform(x);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(norm[i]);
|
||||
try {
|
||||
fft.transform(x, type[j]);
|
||||
Assert.fail(norm[i] + ", " + type[j] +
|
||||
": MathIllegalArgumentException was expected");
|
||||
} catch (MathIllegalArgumentException e) {
|
||||
// Expected behaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testStandardTransformRealSizeNotAPowerOfTwo() {
|
||||
@Test
|
||||
public void testTransformRealSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final double[] x = createRealData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.transform(x);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(norm[i]);
|
||||
try {
|
||||
fft.transform(x, type[j]);
|
||||
Assert.fail(norm[i] + ", " + type[j] +
|
||||
": MathIllegalArgumentException was expected");
|
||||
} catch (MathIllegalArgumentException e) {
|
||||
// Expected behaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testStandardTransformFunctionSizeNotAPowerOfTwo() {
|
||||
@Test
|
||||
public void testTransformFunctionSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.transform(f, 0.0, Math.PI, n);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(norm[i]);
|
||||
try {
|
||||
fft.transform(f, 0.0, Math.PI, n, type[j]);
|
||||
Assert.fail(norm[i] + ", " + type[j] +
|
||||
": MathIllegalArgumentException was expected");
|
||||
} catch (MathIllegalArgumentException e) {
|
||||
// Expected behaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = NotStrictlyPositiveException.class)
|
||||
public void testStandardTransformFunctionNotStrictlyPositiveNumberOfSamples() {
|
||||
@Test
|
||||
public void testTransformFunctionNotStrictlyPositiveNumberOfSamples() {
|
||||
final int n = -128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.transform(f, 0.0, Math.PI, n);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(norm[i]);
|
||||
try {
|
||||
fft.transform(f, 0.0, Math.PI, n, type[j]);
|
||||
fft.transform(f, 0.0, Math.PI, n, type[j]);
|
||||
Assert.fail(norm[i] + ", " + type[j] +
|
||||
": NotStrictlyPositiveException was expected");
|
||||
} catch (NotStrictlyPositiveException e) {
|
||||
// Expected behaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = NumberIsTooLargeException.class)
|
||||
public void testStandardTransformFunctionInvalidBounds() {
|
||||
@Test
|
||||
public void testTransformFunctionInvalidBounds() {
|
||||
final int n = 128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.transform(f, Math.PI, 0.0, n);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testStandardInverseTransformComplexSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final Complex[] x = createComplexData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.inverseTransform(x);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testStandardInverseTransformRealSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final double[] x = createRealData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.inverseTransform(x);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testStandardInverseTransformFunctionSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.inverseTransform(f, 0.0, Math.PI, n);
|
||||
}
|
||||
|
||||
@Test(expected = NotStrictlyPositiveException.class)
|
||||
public void testStandardInverseTransformFunctionNotStrictlyPositiveNumberOfSamples() {
|
||||
final int n = -128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.inverseTransform(f, 0.0, Math.PI, n);
|
||||
}
|
||||
|
||||
@Test(expected = NumberIsTooLargeException.class)
|
||||
public void testStandardInverseTransformFunctionInvalidBounds() {
|
||||
final int n = 128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
fft.transform(f, Math.PI, 0.0, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Precondition checks for unitary transform.
|
||||
*/
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testUnitaryTransformComplexSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final Complex[] x = createComplexData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.transform(x);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testUnitaryTransformRealSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final double[] x = createRealData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.transform(x);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testUnitaryTransformFunctionSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.transform(f, 0.0, Math.PI, n);
|
||||
}
|
||||
|
||||
@Test(expected = NotStrictlyPositiveException.class)
|
||||
public void testUnitaryTransformFunctionNotStrictlyPositiveNumberOfSamples() {
|
||||
final int n = -128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.transform(f, 0.0, Math.PI, n);
|
||||
}
|
||||
|
||||
@Test(expected = NumberIsTooLargeException.class)
|
||||
public void testUnitaryTransformFunctionInvalidBounds() {
|
||||
final int n = 128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.transform(f, Math.PI, 0.0, n);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testUnitaryInverseTransformComplexSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final Complex[] x = createComplexData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.inverseTransform(x);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testUnitaryInverseTransformRealSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final double[] x = createRealData(n);
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.inverseTransform(x);
|
||||
}
|
||||
|
||||
@Test(expected = MathIllegalArgumentException.class)
|
||||
public void testUnitaryInverseTransformFunctionSizeNotAPowerOfTwo() {
|
||||
final int n = 127;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.inverseTransform(f, 0.0, Math.PI, n);
|
||||
}
|
||||
|
||||
@Test(expected = NotStrictlyPositiveException.class)
|
||||
public void testUnitaryInverseTransformFunctionNotStrictlyPositiveNumberOfSamples() {
|
||||
final int n = -128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.inverseTransform(f, 0.0, Math.PI, n);
|
||||
}
|
||||
|
||||
@Test(expected = NumberIsTooLargeException.class)
|
||||
public void testUnitaryInverseTransformFunctionInvalidBounds() {
|
||||
final int n = 128;
|
||||
final UnivariateFunction f = new Sin();
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
fft.transform(f, Math.PI, 0.0, n);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
final FastFourierTransformer fft;
|
||||
fft = new FastFourierTransformer(norm[i]);
|
||||
try {
|
||||
fft.transform(f, Math.PI, 0.0, n, type[j]);
|
||||
Assert.fail(norm[i] + ", " + type[j] +
|
||||
": NumberIsTooLargeException was expected");
|
||||
} catch (NumberIsTooLargeException e) {
|
||||
// Expected behaviour
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -284,28 +216,32 @@ public final class FastFourierTransformerTest {
|
|||
}
|
||||
|
||||
private static void doTestTransformComplex(final int n, final double tol,
|
||||
final boolean forward, final boolean standard) {
|
||||
final FastFourierTransformer.DftNormalization normalization,
|
||||
final TransformType type) {
|
||||
final FastFourierTransformer fft;
|
||||
if (standard) {
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
} else {
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
}
|
||||
fft = new FastFourierTransformer(normalization);
|
||||
final Complex[] x = createComplexData(n);
|
||||
final Complex[] expected;
|
||||
final Complex[] actual;
|
||||
final double s;
|
||||
if (forward) {
|
||||
if (type==TransformType.FORWARD) {
|
||||
expected = dft(x, -1);
|
||||
s = standard ? 1.0 : 1.0 / FastMath.sqrt(n);
|
||||
actual = fft.transform(x);
|
||||
if (normalization == FastFourierTransformer.DftNormalization.STANDARD){
|
||||
s = 1.0;
|
||||
} else {
|
||||
s = 1.0 / FastMath.sqrt(n);
|
||||
}
|
||||
} else {
|
||||
expected = dft(x, 1);
|
||||
s = standard ? 1.0 / n : 1.0 / FastMath.sqrt(n);
|
||||
actual = fft.inverseTransform(x);
|
||||
if (normalization == FastFourierTransformer.DftNormalization.STANDARD) {
|
||||
s = 1.0 / n;
|
||||
} else {
|
||||
s = 1.0 / FastMath.sqrt(n);
|
||||
}
|
||||
}
|
||||
final Complex[] actual = fft.transform(x, type);
|
||||
for (int i = 0; i < n; i++) {
|
||||
final String msg = String.format("%d, %d", n, i);
|
||||
final String msg;
|
||||
msg = String.format("%s, %s, %d, %d", normalization, type, n, i);
|
||||
final double re = s * expected[i].getReal();
|
||||
Assert.assertEquals(msg, re, actual[i].getReal(),
|
||||
tol * FastMath.abs(re));
|
||||
|
@ -316,32 +252,36 @@ public final class FastFourierTransformerTest {
|
|||
}
|
||||
|
||||
private static void doTestTransformReal(final int n, final double tol,
|
||||
final boolean forward, final boolean standard) {
|
||||
final FastFourierTransformer.DftNormalization normalization,
|
||||
final TransformType type) {
|
||||
final FastFourierTransformer fft;
|
||||
if (standard) {
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
} else {
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
}
|
||||
fft = new FastFourierTransformer(normalization);
|
||||
final double[] x = createRealData(n);
|
||||
final Complex[] xc = new Complex[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
xc[i] = new Complex(x[i], 0.0);
|
||||
}
|
||||
final Complex[] expected;
|
||||
final Complex[] actual;
|
||||
final double s;
|
||||
if (forward) {
|
||||
if (type == TransformType.FORWARD) {
|
||||
expected = dft(xc, -1);
|
||||
s = standard ? 1.0 : 1.0 / FastMath.sqrt(n);
|
||||
actual = fft.transform(x);
|
||||
if (normalization == FastFourierTransformer.DftNormalization.STANDARD) {
|
||||
s = 1.0;
|
||||
} else {
|
||||
s = 1.0 / FastMath.sqrt(n);
|
||||
}
|
||||
} else {
|
||||
expected = dft(xc, 1);
|
||||
s = standard ? 1.0 / n : 1.0 / FastMath.sqrt(n);
|
||||
actual = fft.inverseTransform(x);
|
||||
if (normalization == FastFourierTransformer.DftNormalization.STANDARD) {
|
||||
s = 1.0 / n;
|
||||
} else {
|
||||
s = 1.0 / FastMath.sqrt(n);
|
||||
}
|
||||
}
|
||||
final Complex[] actual = fft.transform(x, type);
|
||||
for (int i = 0; i < n; i++) {
|
||||
final String msg = String.format("%d, %d", n, i);
|
||||
final String msg;
|
||||
msg = String.format("%s, %s, %d, %d", normalization, type, n, i);
|
||||
final double re = s * expected[i].getReal();
|
||||
Assert.assertEquals(msg, re, actual[i].getReal(),
|
||||
tol * FastMath.abs(re));
|
||||
|
@ -353,30 +293,33 @@ public final class FastFourierTransformerTest {
|
|||
|
||||
private static void doTestTransformFunction(final UnivariateFunction f,
|
||||
final double min, final double max, int n, final double tol,
|
||||
final boolean forward, final boolean standard) {
|
||||
final FastFourierTransformer.DftNormalization normalization,
|
||||
final TransformType type) {
|
||||
final FastFourierTransformer fft;
|
||||
if (standard) {
|
||||
fft = new FastFourierTransformer(Normalization.STANDARD);
|
||||
} else {
|
||||
fft = new FastFourierTransformer(Normalization.UNITARY);
|
||||
}
|
||||
fft = new FastFourierTransformer(normalization);
|
||||
final Complex[] x = new Complex[n];
|
||||
for (int i = 0; i < n; i++) {
|
||||
final double t = min + i * (max - min) / n;
|
||||
x[i] = new Complex(f.value(t));
|
||||
}
|
||||
final Complex[] expected;
|
||||
final Complex[] actual;
|
||||
final double s;
|
||||
if (forward) {
|
||||
if (type == TransformType.FORWARD) {
|
||||
expected = dft(x, -1);
|
||||
s = standard ? 1.0 : 1.0 / FastMath.sqrt(n);
|
||||
actual = fft.transform(f, min, max, n);
|
||||
if (normalization == FastFourierTransformer.DftNormalization.STANDARD) {
|
||||
s = 1.0;
|
||||
} else {
|
||||
s = 1.0 / FastMath.sqrt(n);
|
||||
}
|
||||
} else {
|
||||
expected = dft(x, 1);
|
||||
s = standard ? 1.0 / n : 1.0 / FastMath.sqrt(n);
|
||||
actual = fft.inverseTransform(f, min, max, n);
|
||||
if (normalization == FastFourierTransformer.DftNormalization.STANDARD) {
|
||||
s = 1.0 / n;
|
||||
} else {
|
||||
s = 1.0 / FastMath.sqrt(n);
|
||||
}
|
||||
}
|
||||
final Complex[] actual = fft.transform(f, min, max, n, type);
|
||||
for (int i = 0; i < n; i++) {
|
||||
final String msg = String.format("%d, %d", n, i);
|
||||
final double re = s * expected[i].getReal();
|
||||
|
@ -393,29 +336,41 @@ public final class FastFourierTransformerTest {
|
|||
*/
|
||||
|
||||
@Test
|
||||
public void testStandardTransformComplex() {
|
||||
final boolean forward = true;
|
||||
final boolean standard = true;
|
||||
doTestTransformComplex(2, 1.0E-15, forward, standard);
|
||||
doTestTransformComplex(4, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(8, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(16, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(32, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(64, 1.0E-12, forward, standard);
|
||||
doTestTransformComplex(128, 1.0E-12, forward, standard);
|
||||
public void testTransformComplex() {
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
doTestTransformComplex(2, 1.0E-15, norm[i], type[j]);
|
||||
doTestTransformComplex(4, 1.0E-14, norm[i], type[j]);
|
||||
doTestTransformComplex(8, 1.0E-14, norm[i], type[j]);
|
||||
doTestTransformComplex(16, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformComplex(32, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformComplex(64, 1.0E-12, norm[i], type[j]);
|
||||
doTestTransformComplex(128, 1.0E-12, norm[i], type[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardTransformReal() {
|
||||
final boolean forward = true;
|
||||
final boolean standard = true;
|
||||
doTestTransformReal(2, 1.0E-15, forward, standard);
|
||||
doTestTransformReal(4, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(8, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(16, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(32, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(64, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(128, 1.0E-11, forward, standard);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
doTestTransformReal(2, 1.0E-15, norm[i], type[j]);
|
||||
doTestTransformReal(4, 1.0E-14, norm[i], type[j]);
|
||||
doTestTransformReal(8, 1.0E-14, norm[i], type[j]);
|
||||
doTestTransformReal(16, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformReal(32, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformReal(64, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformReal(128, 1.0E-11, norm[i], type[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -423,145 +378,21 @@ public final class FastFourierTransformerTest {
|
|||
final UnivariateFunction f = new Sinc();
|
||||
final double min = -FastMath.PI;
|
||||
final double max = FastMath.PI;
|
||||
final boolean forward = true;
|
||||
final boolean standard = true;
|
||||
doTestTransformFunction(f, min, max, 2, 1.0E-15, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 4, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 8, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 16, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 32, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 64, 1.0E-12, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 128, 1.0E-11, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardInverseTransformComplex() {
|
||||
final boolean forward = false;
|
||||
final boolean standard = true;
|
||||
doTestTransformComplex(2, 1.0E-15, forward, standard);
|
||||
doTestTransformComplex(4, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(8, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(16, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(32, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(64, 1.0E-12, forward, standard);
|
||||
doTestTransformComplex(128, 1.0E-12, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardInverseTransformReal() {
|
||||
final boolean forward = false;
|
||||
final boolean standard = true;
|
||||
doTestTransformReal(2, 1.0E-15, forward, standard);
|
||||
doTestTransformReal(4, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(8, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(16, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(32, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(64, 1.0E-12, forward, standard);
|
||||
doTestTransformReal(128, 1.0E-11, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStandardInverseTransformFunction() {
|
||||
final UnivariateFunction f = new Sinc();
|
||||
final double min = -FastMath.PI;
|
||||
final double max = FastMath.PI;
|
||||
final boolean forward = false;
|
||||
final boolean standard = true;
|
||||
doTestTransformFunction(f, min, max, 2, 1.0E-15, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 4, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 8, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 16, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 32, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 64, 1.0E-12, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 128, 1.0E-11, forward, standard);
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests of unitary transform (when data is valid).
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void testUnitaryTransformComplex() {
|
||||
final boolean forward = true;
|
||||
final boolean standard = false;
|
||||
doTestTransformComplex(2, 1.0E-15, forward, standard);
|
||||
doTestTransformComplex(4, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(8, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(16, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(32, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(64, 1.0E-12, forward, standard);
|
||||
doTestTransformComplex(128, 1.0E-12, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnitaryTransformReal() {
|
||||
final boolean forward = true;
|
||||
final boolean standard = false;
|
||||
doTestTransformReal(2, 1.0E-15, forward, standard);
|
||||
doTestTransformReal(4, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(8, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(16, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(32, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(64, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(128, 1.0E-11, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnitaryTransformFunction() {
|
||||
final UnivariateFunction f = new Sinc();
|
||||
final double min = -FastMath.PI;
|
||||
final double max = FastMath.PI;
|
||||
final boolean forward = true;
|
||||
final boolean standard = false;
|
||||
doTestTransformFunction(f, min, max, 2, 1.0E-15, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 4, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 8, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 16, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 32, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 64, 1.0E-12, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 128, 1.0E-11, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnitaryInverseTransformComplex() {
|
||||
final boolean forward = false;
|
||||
final boolean standard = false;
|
||||
doTestTransformComplex(2, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(4, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(8, 1.0E-14, forward, standard);
|
||||
doTestTransformComplex(16, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(32, 1.0E-13, forward, standard);
|
||||
doTestTransformComplex(64, 1.0E-12, forward, standard);
|
||||
doTestTransformComplex(128, 1.0E-12, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnitaryInverseTransformReal() {
|
||||
final boolean forward = false;
|
||||
final boolean standard = false;
|
||||
doTestTransformReal(2, 1.0E-15, forward, standard);
|
||||
doTestTransformReal(4, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(8, 1.0E-14, forward, standard);
|
||||
doTestTransformReal(16, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(32, 1.0E-13, forward, standard);
|
||||
doTestTransformReal(64, 1.0E-12, forward, standard);
|
||||
doTestTransformReal(128, 1.0E-11, forward, standard);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnitaryInverseTransformFunction() {
|
||||
final UnivariateFunction f = new Sinc();
|
||||
final double min = -FastMath.PI;
|
||||
final double max = FastMath.PI;
|
||||
final boolean forward = false;
|
||||
final boolean standard = false;
|
||||
doTestTransformFunction(f, min, max, 2, 1.0E-15, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 4, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 8, 1.0E-14, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 16, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 32, 1.0E-13, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 64, 1.0E-12, forward, standard);
|
||||
doTestTransformFunction(f, min, max, 128, 1.0E-11, forward, standard);
|
||||
final FastFourierTransformer.DftNormalization[] norm;
|
||||
norm = FastFourierTransformer.DftNormalization.values();
|
||||
final TransformType[] type;
|
||||
type = TransformType.values();
|
||||
for (int i = 0; i < norm.length; i++) {
|
||||
for (int j = 0; j < type.length; j++) {
|
||||
doTestTransformFunction(f, min, max, 2, 1.0E-15, norm[i], type[j]);
|
||||
doTestTransformFunction(f, min, max, 4, 1.0E-14, norm[i], type[j]);
|
||||
doTestTransformFunction(f, min, max, 8, 1.0E-14, norm[i], type[j]);
|
||||
doTestTransformFunction(f, min, max, 16, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformFunction(f, min, max, 32, 1.0E-13, norm[i], type[j]);
|
||||
doTestTransformFunction(f, min, max, 64, 1.0E-12, norm[i], type[j]);
|
||||
doTestTransformFunction(f, min, max, 128, 1.0E-11, norm[i], type[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -574,7 +405,7 @@ public final class FastFourierTransformerTest {
|
|||
@Test
|
||||
public void testAdHocData() {
|
||||
FastFourierTransformer transformer;
|
||||
transformer = new FastFourierTransformer(Normalization.STANDARD);
|
||||
transformer = new FastFourierTransformer(DftNormalization.STANDARD);
|
||||
Complex result[]; double tolerance = 1E-12;
|
||||
|
||||
double x[] = {1.3, 2.4, 1.7, 4.1, 2.9, 1.7, 5.1, 2.7};
|
||||
|
@ -588,13 +419,13 @@ public final class FastFourierTransformerTest {
|
|||
new Complex(-2.6, -2.7),
|
||||
new Complex(-2.09497474683058, -1.91507575950825)};
|
||||
|
||||
result = transformer.transform(x);
|
||||
result = transformer.transform(x, TransformType.FORWARD);
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
Assert.assertEquals(y[i].getReal(), result[i].getReal(), tolerance);
|
||||
Assert.assertEquals(y[i].getImaginary(), result[i].getImaginary(), 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].getReal(), tolerance);
|
||||
Assert.assertEquals(0.0, result[i].getImaginary(), tolerance);
|
||||
|
@ -604,14 +435,14 @@ public final class FastFourierTransformerTest {
|
|||
TransformUtils.scaleArray(x2, 1.0 / FastMath.sqrt(x2.length));
|
||||
Complex y2[] = y;
|
||||
|
||||
transformer = new FastFourierTransformer(Normalization.UNITARY);
|
||||
result = transformer.transform(y2);
|
||||
transformer = new FastFourierTransformer(DftNormalization.UNITARY);
|
||||
result = transformer.transform(y2, TransformType.FORWARD);
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
Assert.assertEquals(x2[i], result[i].getReal(), tolerance);
|
||||
Assert.assertEquals(0.0, result[i].getImaginary(), tolerance);
|
||||
}
|
||||
|
||||
result = transformer.inverseTransform(x2);
|
||||
result = transformer.transform(x2, TransformType.INVERSE);
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
Assert.assertEquals(y2[i].getReal(), result[i].getReal(), tolerance);
|
||||
Assert.assertEquals(y2[i].getImaginary(), result[i].getImaginary(), tolerance);
|
||||
|
@ -625,12 +456,12 @@ public final class FastFourierTransformerTest {
|
|||
public void testSinFunction() {
|
||||
UnivariateFunction f = new SinFunction();
|
||||
FastFourierTransformer transformer;
|
||||
transformer = new FastFourierTransformer(Normalization.STANDARD);
|
||||
transformer = new FastFourierTransformer(DftNormalization.STANDARD);
|
||||
Complex result[]; int N = 1 << 8;
|
||||
double min, max, tolerance = 1E-12;
|
||||
|
||||
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(0.0, result[1].getReal(), tolerance);
|
||||
Assert.assertEquals(-(N >> 1), result[1].getImaginary(), tolerance);
|
||||
Assert.assertEquals(0.0, result[N-1].getReal(), tolerance);
|
||||
|
@ -641,7 +472,7 @@ public final class FastFourierTransformerTest {
|
|||
}
|
||||
|
||||
min = -FastMath.PI; max = FastMath.PI;
|
||||
result = transformer.inverseTransform(f, min, max, N);
|
||||
result = transformer.transform(f, min, max, N, TransformType.INVERSE);
|
||||
Assert.assertEquals(0.0, result[1].getReal(), tolerance);
|
||||
Assert.assertEquals(-0.5, result[1].getImaginary(), tolerance);
|
||||
Assert.assertEquals(0.0, result[N-1].getReal(), tolerance);
|
||||
|
@ -659,7 +490,7 @@ public final class FastFourierTransformerTest {
|
|||
@Test
|
||||
public void test2DData() {
|
||||
FastFourierTransformer transformer;
|
||||
transformer = new FastFourierTransformer(Normalization.STANDARD);
|
||||
transformer = new FastFourierTransformer(DftNormalization.STANDARD);
|
||||
|
||||
double tolerance = 1E-12;
|
||||
Complex[][] input = new Complex[][] {new Complex[] {new Complex(1, 0),
|
||||
|
@ -675,8 +506,8 @@ public final class FastFourierTransformerTest {
|
|||
FastMath.sqrt(goodOutput[i].length) *
|
||||
FastMath.sqrt(goodOutput.length));
|
||||
}
|
||||
Complex[][] output = (Complex[][])transformer.mdfft(input, true);
|
||||
Complex[][] output2 = (Complex[][])transformer.mdfft(output, false);
|
||||
Complex[][] output = (Complex[][])transformer.mdfft(input, TransformType.FORWARD);
|
||||
Complex[][] output2 = (Complex[][])transformer.mdfft(output, TransformType.INVERSE);
|
||||
|
||||
Assert.assertEquals(input.length, output.length);
|
||||
Assert.assertEquals(input.length, output2.length);
|
||||
|
@ -687,6 +518,8 @@ 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);
|
||||
|
@ -700,7 +533,7 @@ public final class FastFourierTransformerTest {
|
|||
@Test
|
||||
public void test2DDataUnitary() {
|
||||
FastFourierTransformer transformer;
|
||||
transformer = new FastFourierTransformer(Normalization.UNITARY);
|
||||
transformer = new FastFourierTransformer(DftNormalization.UNITARY);
|
||||
double tolerance = 1E-12;
|
||||
Complex[][] input = new Complex[][] {new Complex[] {new Complex(1, 0),
|
||||
new Complex(2, 0)},
|
||||
|
@ -709,8 +542,8 @@ public final class FastFourierTransformerTest {
|
|||
Complex[][] goodOutput = new Complex[][] {new Complex[] {new Complex(5,
|
||||
1.5), new Complex(-1, -.5)}, new Complex[] {new Complex(-2,
|
||||
-1.5), new Complex(0, .5)}};
|
||||
Complex[][] output = (Complex[][])transformer.mdfft(input, true);
|
||||
Complex[][] output2 = (Complex[][])transformer.mdfft(output, false);
|
||||
Complex[][] output = (Complex[][])transformer.mdfft(input, TransformType.FORWARD);
|
||||
Complex[][] output2 = (Complex[][])transformer.mdfft(output, TransformType.INVERSE);
|
||||
|
||||
Assert.assertEquals(input.length, output.length);
|
||||
Assert.assertEquals(input.length, output2.length);
|
||||
|
|
Loading…
Reference in New Issue