FastFourierTransformer implements Serializable { 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, normalization, type); return TransformUtils.createComplexArray(dataRI); } FastFourierTransformer(final DftNormalization normalization); static void transformInPlace(final double[][] dataRI,
        final DftNormalization normalization, final TransformType type); Complex[] transform(final double[] f, final TransformType type); Complex[] transform(final UnivariateFunction f,
                               final double min, final double max, final int n,
                               final TransformType type); Complex[] transform(final Complex[] f, final TransformType type); @Deprecated Object mdfft(Object mdca, TransformType type);  }
@Test public void testTransformComplexSizeNotAPowerOfTwo() { final int n = 127; final Complex[] x = createComplexData(n); final DftNormalization[] norm; norm = 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) { } } } }
@Test public void testTransformRealSizeNotAPowerOfTwo() { final int n = 127; final double[] x = createRealData(n); final DftNormalization[] norm; norm = 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) { } } } }
@Test public void testTransformFunctionSizeNotAPowerOfTwo() { final int n = 127; final UnivariateFunction f = new Sin(); final DftNormalization[] norm; norm = 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) { } } } }
@Test public void testTransformFunctionNotStrictlyPositiveNumberOfSamples() { final int n = -128; final UnivariateFunction f = new Sin(); final DftNormalization[] norm; norm = 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) { } } } }
@Test public void testTransformFunctionInvalidBounds() { final int n = 128; final UnivariateFunction f = new Sin(); final DftNormalization[] norm; norm = 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) { } } } }
@Test public void testAdHocData() { FastFourierTransformer transformer; 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}; Complex y[] = { new Complex(21.9, 0.0), new Complex(-2.09497474683058, 1.91507575950825), new Complex(-2.6, 2.7), new Complex(-1.10502525316942, -4.88492424049175), new Complex(0.1, 0.0), new Complex(-1.10502525316942, 4.88492424049175), new Complex(-2.6, -2.7), new Complex(-2.09497474683058, -1.91507575950825)}; 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.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); } double x2[] = {10.4, 21.6, 40.8, 13.6, 23.2, 32.8, 13.6, 19.2}; TransformUtils.scaleArray(x2, 1.0 / FastMath.sqrt(x2.length)); Complex y2[] = y; 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.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); } }
@Test public void testSinFunction() { UnivariateFunction f = new Sin(); FastFourierTransformer transformer; 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, 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); Assert.assertEquals(N >> 1, result[N-1].getImaginary(), tolerance); for (int i = 0; i < N-1; i += (i == 0 ? 2 : 1)) { Assert.assertEquals(0.0, result[i].getReal(), tolerance); Assert.assertEquals(0.0, result[i].getImaginary(), tolerance); } min = -FastMath.PI; max = FastMath.PI; 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); Assert.assertEquals(0.5, result[N-1].getImaginary(), tolerance); for (int i = 0; i < N-1; i += (i == 0 ? 2 : 1)) { Assert.assertEquals(0.0, result[i].getReal(), tolerance); Assert.assertEquals(0.0, result[i].getImaginary(), tolerance); } }