001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math.transform; 018 019 import org.apache.commons.math.analysis.*; 020 import org.apache.commons.math.complex.*; 021 import org.apache.commons.math.MathException; 022 import junit.framework.TestCase; 023 024 /** 025 * Testcase for fast Fourier transformer. 026 * <p> 027 * FFT algorithm is exact, the small tolerance number is used only 028 * to account for round-off errors. 029 * 030 * @version $Revision: 762118 $ $Date: 2009-04-05 12:55:59 -0400 (Sun, 05 Apr 2009) $ 031 */ 032 public final class FastFourierTransformerTest extends TestCase { 033 034 /** 035 * Test of transformer for the ad hoc data taken from Mathematica. 036 */ 037 public void testAdHocData() { 038 FastFourierTransformer transformer = new FastFourierTransformer(); 039 Complex result[]; double tolerance = 1E-12; 040 041 double x[] = {1.3, 2.4, 1.7, 4.1, 2.9, 1.7, 5.1, 2.7}; 042 Complex y[] = { 043 new Complex(21.9, 0.0), 044 new Complex(-2.09497474683058, 1.91507575950825), 045 new Complex(-2.6, 2.7), 046 new Complex(-1.10502525316942, -4.88492424049175), 047 new Complex(0.1, 0.0), 048 new Complex(-1.10502525316942, 4.88492424049175), 049 new Complex(-2.6, -2.7), 050 new Complex(-2.09497474683058, -1.91507575950825)}; 051 052 result = transformer.transform(x); 053 for (int i = 0; i < result.length; i++) { 054 assertEquals(y[i].getReal(), result[i].getReal(), tolerance); 055 assertEquals(y[i].getImaginary(), result[i].getImaginary(), tolerance); 056 } 057 058 result = transformer.inversetransform(y); 059 for (int i = 0; i < result.length; i++) { 060 assertEquals(x[i], result[i].getReal(), tolerance); 061 assertEquals(0.0, result[i].getImaginary(), tolerance); 062 } 063 064 double x2[] = {10.4, 21.6, 40.8, 13.6, 23.2, 32.8, 13.6, 19.2}; 065 FastFourierTransformer.scaleArray(x2, 1.0 / Math.sqrt(x2.length)); 066 Complex y2[] = y; 067 068 result = transformer.transform2(y2); 069 for (int i = 0; i < result.length; i++) { 070 assertEquals(x2[i], result[i].getReal(), tolerance); 071 assertEquals(0.0, result[i].getImaginary(), tolerance); 072 } 073 074 result = transformer.inversetransform2(x2); 075 for (int i = 0; i < result.length; i++) { 076 assertEquals(y2[i].getReal(), result[i].getReal(), tolerance); 077 assertEquals(y2[i].getImaginary(), result[i].getImaginary(), tolerance); 078 } 079 } 080 081 public void test2DData() { 082 FastFourierTransformer transformer = new FastFourierTransformer(); 083 double tolerance = 1E-12; 084 Complex[][] input = new Complex[][] {new Complex[] {new Complex(1, 0), 085 new Complex(2, 0)}, 086 new Complex[] {new Complex(3, 1), 087 new Complex(4, 2)}}; 088 Complex[][] goodOutput = new Complex[][] {new Complex[] {new Complex(5, 089 1.5), new Complex(-1, -.5)}, new Complex[] {new Complex(-2, 090 -1.5), new Complex(0, .5)}}; 091 Complex[][] output = (Complex[][])transformer.mdfft(input, true); 092 Complex[][] output2 = (Complex[][])transformer.mdfft(output, false); 093 094 assertEquals(input.length, output.length); 095 assertEquals(input.length, output2.length); 096 assertEquals(input[0].length, output[0].length); 097 assertEquals(input[0].length, output2[0].length); 098 assertEquals(input[1].length, output[1].length); 099 assertEquals(input[1].length, output2[1].length); 100 101 for (int i = 0; i < input.length; i++) { 102 for (int j = 0; j < input[0].length; j++) { 103 assertEquals(input[i][j].getImaginary(), output2[i][j].getImaginary(), 104 tolerance); 105 assertEquals(input[i][j].getReal(), output2[i][j].getReal(), tolerance); 106 assertEquals(goodOutput[i][j].getImaginary(), output[i][j].getImaginary(), 107 tolerance); 108 assertEquals(goodOutput[i][j].getReal(), output[i][j].getReal(), tolerance); 109 } 110 } 111 } 112 113 /** 114 * Test of transformer for the sine function. 115 */ 116 public void testSinFunction() throws MathException { 117 UnivariateRealFunction f = new SinFunction(); 118 FastFourierTransformer transformer = new FastFourierTransformer(); 119 Complex result[]; int N = 1 << 8; 120 double min, max, tolerance = 1E-12; 121 122 min = 0.0; max = 2.0 * Math.PI; 123 result = transformer.transform(f, min, max, N); 124 assertEquals(0.0, result[1].getReal(), tolerance); 125 assertEquals(-(N >> 1), result[1].getImaginary(), tolerance); 126 assertEquals(0.0, result[N-1].getReal(), tolerance); 127 assertEquals(N >> 1, result[N-1].getImaginary(), tolerance); 128 for (int i = 0; i < N-1; i += (i == 0 ? 2 : 1)) { 129 assertEquals(0.0, result[i].getReal(), tolerance); 130 assertEquals(0.0, result[i].getImaginary(), tolerance); 131 } 132 133 min = -Math.PI; max = Math.PI; 134 result = transformer.inversetransform(f, min, max, N); 135 assertEquals(0.0, result[1].getReal(), tolerance); 136 assertEquals(-0.5, result[1].getImaginary(), tolerance); 137 assertEquals(0.0, result[N-1].getReal(), tolerance); 138 assertEquals(0.5, result[N-1].getImaginary(), tolerance); 139 for (int i = 0; i < N-1; i += (i == 0 ? 2 : 1)) { 140 assertEquals(0.0, result[i].getReal(), tolerance); 141 assertEquals(0.0, result[i].getImaginary(), tolerance); 142 } 143 } 144 145 /** 146 * Test of parameters for the transformer. 147 */ 148 public void testParameters() throws Exception { 149 UnivariateRealFunction f = new SinFunction(); 150 FastFourierTransformer transformer = new FastFourierTransformer(); 151 152 try { 153 // bad interval 154 transformer.transform(f, 1, -1, 64); 155 fail("Expecting IllegalArgumentException - bad interval"); 156 } catch (IllegalArgumentException ex) { 157 // expected 158 } 159 try { 160 // bad samples number 161 transformer.transform(f, -1, 1, 0); 162 fail("Expecting IllegalArgumentException - bad samples number"); 163 } catch (IllegalArgumentException ex) { 164 // expected 165 } 166 try { 167 // bad samples number 168 transformer.transform(f, -1, 1, 100); 169 fail("Expecting IllegalArgumentException - bad samples number"); 170 } catch (IllegalArgumentException ex) { 171 // expected 172 } 173 } 174 }