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