Chris@118
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@110
|
2
|
Chris@110
|
3 #include "dsp/transforms/FFT.h"
|
Chris@110
|
4
|
Chris@110
|
5 #define BOOST_TEST_DYN_LINK
|
Chris@110
|
6 #define BOOST_TEST_MAIN
|
Chris@110
|
7
|
Chris@110
|
8 #include <boost/test/unit_test.hpp>
|
Chris@110
|
9
|
Chris@129
|
10 #include <stdexcept>
|
Chris@129
|
11
|
Chris@110
|
12 BOOST_AUTO_TEST_SUITE(TestFFT)
|
Chris@110
|
13
|
Chris@110
|
14 #define COMPARE_CONST(a, n) \
|
Chris@110
|
15 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
|
Chris@110
|
16 BOOST_CHECK_SMALL(a[cmp_i] - n, 1e-14); \
|
Chris@110
|
17 }
|
Chris@110
|
18
|
Chris@110
|
19 #define COMPARE_ARRAY(a, b) \
|
Chris@110
|
20 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \
|
Chris@110
|
21 BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-14); \
|
Chris@110
|
22 }
|
Chris@110
|
23
|
Chris@114
|
24 //!!! need at least one test with complex time-domain signal
|
Chris@110
|
25
|
Chris@110
|
26 BOOST_AUTO_TEST_CASE(forwardArrayBounds)
|
Chris@110
|
27 {
|
Chris@110
|
28 // initialise bins to something recognisable, so we can tell
|
Chris@110
|
29 // if they haven't been written
|
Chris@110
|
30 double in[] = { 1, 1, -1, -1 };
|
Chris@110
|
31 double re[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@110
|
32 double im[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@110
|
33 FFT(4).process(false, in, 0, re+1, im+1);
|
Chris@110
|
34 // And check we haven't overrun the arrays
|
Chris@110
|
35 BOOST_CHECK_EQUAL(re[0], 999.0);
|
Chris@110
|
36 BOOST_CHECK_EQUAL(im[0], 999.0);
|
Chris@110
|
37 BOOST_CHECK_EQUAL(re[5], 999.0);
|
Chris@110
|
38 BOOST_CHECK_EQUAL(im[5], 999.0);
|
Chris@110
|
39 }
|
Chris@110
|
40
|
Chris@114
|
41 BOOST_AUTO_TEST_CASE(r_forwardArrayBounds)
|
Chris@114
|
42 {
|
Chris@114
|
43 // initialise bins to something recognisable, so we can tell
|
Chris@114
|
44 // if they haven't been written
|
Chris@114
|
45 double in[] = { 1, 1, -1, -1 };
|
Chris@114
|
46 double re[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@114
|
47 double im[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@114
|
48 FFTReal(4).forward(in, re+1, im+1);
|
Chris@114
|
49 // And check we haven't overrun the arrays
|
Chris@114
|
50 BOOST_CHECK_EQUAL(re[0], 999.0);
|
Chris@114
|
51 BOOST_CHECK_EQUAL(im[0], 999.0);
|
Chris@114
|
52 BOOST_CHECK_EQUAL(re[5], 999.0);
|
Chris@114
|
53 BOOST_CHECK_EQUAL(im[5], 999.0);
|
Chris@114
|
54 }
|
Chris@114
|
55
|
Chris@110
|
56 BOOST_AUTO_TEST_CASE(inverseArrayBounds)
|
Chris@110
|
57 {
|
Chris@110
|
58 // initialise bins to something recognisable, so we can tell
|
Chris@110
|
59 // if they haven't been written
|
Chris@114
|
60 double re[] = { 0, 1, 0, 1 };
|
Chris@114
|
61 double im[] = { 0, -2, 0, 2 };
|
Chris@110
|
62 double outre[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@110
|
63 double outim[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@114
|
64 FFT(4).process(true, re, im, outre+1, outim+1);
|
Chris@110
|
65 // And check we haven't overrun the arrays
|
Chris@110
|
66 BOOST_CHECK_EQUAL(outre[0], 999.0);
|
Chris@110
|
67 BOOST_CHECK_EQUAL(outim[0], 999.0);
|
Chris@110
|
68 BOOST_CHECK_EQUAL(outre[5], 999.0);
|
Chris@110
|
69 BOOST_CHECK_EQUAL(outim[5], 999.0);
|
Chris@110
|
70 }
|
Chris@110
|
71
|
Chris@114
|
72 BOOST_AUTO_TEST_CASE(r_inverseArrayBounds)
|
Chris@114
|
73 {
|
Chris@114
|
74 // initialise bins to something recognisable, so we can tell
|
Chris@114
|
75 // if they haven't been written
|
Chris@114
|
76 double re[] = { 0, 1, 0 };
|
Chris@114
|
77 double im[] = { 0, -2, 0 };
|
Chris@114
|
78 double outre[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@114
|
79 FFTReal(4).inverse(re, im, outre+1);
|
Chris@114
|
80 // And check we haven't overrun the arrays
|
Chris@114
|
81 BOOST_CHECK_EQUAL(outre[0], 999.0);
|
Chris@114
|
82 BOOST_CHECK_EQUAL(outre[5], 999.0);
|
Chris@114
|
83 }
|
Chris@114
|
84
|
Chris@114
|
85 BOOST_AUTO_TEST_CASE(dc)
|
Chris@114
|
86 {
|
Chris@114
|
87 // DC-only signal. The DC bin is purely real
|
Chris@114
|
88 double in[] = { 1, 1, 1, 1 };
|
Chris@114
|
89 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
90 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
91 FFT(4).process(false, in, 0, re, im);
|
Chris@114
|
92 BOOST_CHECK_EQUAL(re[0], 4.0);
|
Chris@114
|
93 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@114
|
94 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@114
|
95 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@114
|
96 COMPARE_CONST(im, 0.0);
|
Chris@114
|
97 double back[4];
|
Chris@114
|
98 double backim[4];
|
Chris@114
|
99 FFT(4).process(true, re, im, back, backim);
|
Chris@114
|
100 COMPARE_ARRAY(back, in);
|
Chris@114
|
101 COMPARE_CONST(backim, 0.0);
|
Chris@114
|
102 }
|
Chris@114
|
103
|
Chris@114
|
104 BOOST_AUTO_TEST_CASE(r_dc)
|
Chris@114
|
105 {
|
Chris@114
|
106 // DC-only signal. The DC bin is purely real
|
Chris@114
|
107 double in[] = { 1, 1, 1, 1 };
|
Chris@114
|
108 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
109 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
110 FFTReal(4).forward(in, re, im);
|
Chris@114
|
111 BOOST_CHECK_EQUAL(re[0], 4.0);
|
Chris@114
|
112 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@114
|
113 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@114
|
114 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@114
|
115 COMPARE_CONST(im, 0.0);
|
Chris@114
|
116 double back[4];
|
Chris@114
|
117 // check conjugates are reconstructed
|
Chris@114
|
118 re[3] = 999;
|
Chris@114
|
119 im[3] = 999;
|
Chris@114
|
120 FFTReal(4).inverse(re, im, back);
|
Chris@114
|
121 COMPARE_ARRAY(back, in);
|
Chris@114
|
122 }
|
Chris@114
|
123
|
Chris@159
|
124 BOOST_AUTO_TEST_CASE(c_dc)
|
Chris@159
|
125 {
|
Chris@159
|
126 // DC-only signal. The DC bin is purely real
|
Chris@159
|
127 double rin[] = { 1, 1, 1, 1 };
|
Chris@159
|
128 double iin[] = { 1, 1, 1, 1 };
|
Chris@159
|
129 double re[] = { 999, 999, 999, 999 };
|
Chris@159
|
130 double im[] = { 999, 999, 999, 999 };
|
Chris@159
|
131 FFT(4).process(false, rin, iin, re, im);
|
Chris@159
|
132 BOOST_CHECK_EQUAL(re[0], 4.0);
|
Chris@159
|
133 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@159
|
134 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@159
|
135 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@159
|
136 BOOST_CHECK_EQUAL(im[0], 4.0);
|
Chris@159
|
137 BOOST_CHECK_EQUAL(im[1], 0.0);
|
Chris@159
|
138 BOOST_CHECK_EQUAL(im[2], 0.0);
|
Chris@159
|
139 BOOST_CHECK_EQUAL(im[3], 0.0);
|
Chris@159
|
140 double back[4];
|
Chris@159
|
141 double backim[4];
|
Chris@159
|
142 FFT(4).process(true, re, im, back, backim);
|
Chris@159
|
143 COMPARE_ARRAY(back, rin);
|
Chris@159
|
144 COMPARE_ARRAY(backim, iin);
|
Chris@159
|
145 }
|
Chris@159
|
146
|
Chris@114
|
147 BOOST_AUTO_TEST_CASE(sine)
|
Chris@114
|
148 {
|
Chris@114
|
149 // Sine. Output is purely imaginary
|
Chris@114
|
150 double in[] = { 0, 1, 0, -1 };
|
Chris@114
|
151 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
152 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
153 FFT(4).process(false, in, 0, re, im);
|
Chris@114
|
154 COMPARE_CONST(re, 0.0);
|
Chris@114
|
155 BOOST_CHECK_EQUAL(im[0], 0.0);
|
Chris@114
|
156 BOOST_CHECK_EQUAL(im[1], -2.0);
|
Chris@114
|
157 BOOST_CHECK_EQUAL(im[2], 0.0);
|
Chris@114
|
158 BOOST_CHECK_EQUAL(im[3], 2.0);
|
Chris@114
|
159 double back[4];
|
Chris@114
|
160 double backim[4];
|
Chris@114
|
161 FFT(4).process(true, re, im, back, backim);
|
Chris@114
|
162 COMPARE_ARRAY(back, in);
|
Chris@114
|
163 COMPARE_CONST(backim, 0.0);
|
Chris@114
|
164 }
|
Chris@114
|
165
|
Chris@114
|
166 BOOST_AUTO_TEST_CASE(r_sine)
|
Chris@114
|
167 {
|
Chris@114
|
168 // Sine. Output is purely imaginary
|
Chris@114
|
169 double in[] = { 0, 1, 0, -1 };
|
Chris@114
|
170 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
171 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
172 FFTReal(4).forward(in, re, im);
|
Chris@114
|
173 COMPARE_CONST(re, 0.0);
|
Chris@114
|
174 BOOST_CHECK_EQUAL(im[0], 0.0);
|
Chris@114
|
175 BOOST_CHECK_EQUAL(im[1], -2.0);
|
Chris@114
|
176 BOOST_CHECK_EQUAL(im[2], 0.0);
|
Chris@114
|
177 BOOST_CHECK_EQUAL(im[3], 2.0);
|
Chris@114
|
178 double back[4];
|
Chris@114
|
179 // check conjugates are reconstructed
|
Chris@114
|
180 re[3] = 999;
|
Chris@114
|
181 im[3] = 999;
|
Chris@114
|
182 FFTReal(4).inverse(re, im, back);
|
Chris@114
|
183 COMPARE_ARRAY(back, in);
|
Chris@114
|
184 }
|
Chris@114
|
185
|
Chris@114
|
186 BOOST_AUTO_TEST_CASE(cosine)
|
Chris@114
|
187 {
|
Chris@114
|
188 // Cosine. Output is purely real
|
Chris@114
|
189 double in[] = { 1, 0, -1, 0 };
|
Chris@114
|
190 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
191 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
192 FFT(4).process(false, in, 0, re, im);
|
Chris@114
|
193 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@114
|
194 BOOST_CHECK_EQUAL(re[1], 2.0);
|
Chris@114
|
195 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@114
|
196 BOOST_CHECK_EQUAL(re[3], 2.0);
|
Chris@114
|
197 COMPARE_CONST(im, 0.0);
|
Chris@114
|
198 double back[4];
|
Chris@114
|
199 double backim[4];
|
Chris@114
|
200 FFT(4).process(true, re, im, back, backim);
|
Chris@114
|
201 COMPARE_ARRAY(back, in);
|
Chris@114
|
202 COMPARE_CONST(backim, 0.0);
|
Chris@114
|
203 }
|
Chris@114
|
204
|
Chris@114
|
205 BOOST_AUTO_TEST_CASE(r_cosine)
|
Chris@114
|
206 {
|
Chris@114
|
207 // Cosine. Output is purely real
|
Chris@114
|
208 double in[] = { 1, 0, -1, 0 };
|
Chris@114
|
209 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
210 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
211 FFTReal(4).forward(in, re, im);
|
Chris@114
|
212 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@114
|
213 BOOST_CHECK_EQUAL(re[1], 2.0);
|
Chris@114
|
214 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@114
|
215 BOOST_CHECK_EQUAL(re[3], 2.0);
|
Chris@114
|
216 COMPARE_CONST(im, 0.0);
|
Chris@114
|
217 double back[4];
|
Chris@114
|
218 // check conjugates are reconstructed
|
Chris@114
|
219 re[3] = 999;
|
Chris@114
|
220 im[3] = 999;
|
Chris@114
|
221 FFTReal(4).inverse(re, im, back);
|
Chris@114
|
222 COMPARE_ARRAY(back, in);
|
Chris@114
|
223 }
|
Chris@159
|
224
|
Chris@159
|
225 BOOST_AUTO_TEST_CASE(c_cosine)
|
Chris@159
|
226 {
|
Chris@159
|
227 // Cosine. Output is purely real
|
Chris@159
|
228 double rin[] = { 1, 0, -1, 0 };
|
Chris@159
|
229 double iin[] = { 1, 0, -1, 0 };
|
Chris@159
|
230 double re[] = { 999, 999, 999, 999 };
|
Chris@159
|
231 double im[] = { 999, 999, 999, 999 };
|
Chris@159
|
232 FFT(4).process(false, rin, iin, re, im);
|
Chris@159
|
233 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@159
|
234 BOOST_CHECK_EQUAL(re[1], 2.0);
|
Chris@159
|
235 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@159
|
236 BOOST_CHECK_EQUAL(re[3], 2.0);
|
Chris@159
|
237 BOOST_CHECK_EQUAL(im[0], 0.0);
|
Chris@159
|
238 BOOST_CHECK_EQUAL(im[1], 2.0);
|
Chris@159
|
239 BOOST_CHECK_EQUAL(im[2], 0.0);
|
Chris@159
|
240 BOOST_CHECK_EQUAL(im[3], 2.0);
|
Chris@159
|
241 double back[4];
|
Chris@159
|
242 double backim[4];
|
Chris@159
|
243 FFT(4).process(true, re, im, back, backim);
|
Chris@159
|
244 COMPARE_ARRAY(back, rin);
|
Chris@159
|
245 COMPARE_ARRAY(backim, iin);
|
Chris@159
|
246 }
|
Chris@114
|
247
|
Chris@114
|
248 BOOST_AUTO_TEST_CASE(sineCosine)
|
Chris@114
|
249 {
|
Chris@114
|
250 // Sine and cosine mixed
|
Chris@114
|
251 double in[] = { 0.5, 1, -0.5, -1 };
|
Chris@114
|
252 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
253 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
254 FFT(4).process(false, in, 0, re, im);
|
Chris@114
|
255 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@114
|
256 BOOST_CHECK_CLOSE(re[1], 1.0, 1e-12);
|
Chris@114
|
257 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@114
|
258 BOOST_CHECK_CLOSE(re[3], 1.0, 1e-12);
|
Chris@114
|
259 BOOST_CHECK_EQUAL(im[0], 0.0);
|
Chris@114
|
260 BOOST_CHECK_CLOSE(im[1], -2.0, 1e-12);
|
Chris@114
|
261 BOOST_CHECK_EQUAL(im[2], 0.0);
|
Chris@114
|
262 BOOST_CHECK_CLOSE(im[3], 2.0, 1e-12);
|
Chris@114
|
263 double back[4];
|
Chris@114
|
264 double backim[4];
|
Chris@114
|
265 FFT(4).process(true, re, im, back, backim);
|
Chris@114
|
266 COMPARE_ARRAY(back, in);
|
Chris@114
|
267 COMPARE_CONST(backim, 0.0);
|
Chris@114
|
268 }
|
Chris@114
|
269
|
Chris@114
|
270 BOOST_AUTO_TEST_CASE(r_sineCosine)
|
Chris@114
|
271 {
|
Chris@114
|
272 // Sine and cosine mixed
|
Chris@114
|
273 double in[] = { 0.5, 1, -0.5, -1 };
|
Chris@114
|
274 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
275 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
276 FFTReal(4).forward(in, re, im);
|
Chris@114
|
277 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@114
|
278 BOOST_CHECK_CLOSE(re[1], 1.0, 1e-12);
|
Chris@114
|
279 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@114
|
280 BOOST_CHECK_CLOSE(re[3], 1.0, 1e-12);
|
Chris@114
|
281 BOOST_CHECK_EQUAL(im[0], 0.0);
|
Chris@114
|
282 BOOST_CHECK_CLOSE(im[1], -2.0, 1e-12);
|
Chris@114
|
283 BOOST_CHECK_EQUAL(im[2], 0.0);
|
Chris@114
|
284 BOOST_CHECK_CLOSE(im[3], 2.0, 1e-12);
|
Chris@114
|
285 double back[4];
|
Chris@114
|
286 // check conjugates are reconstructed
|
Chris@114
|
287 re[3] = 999;
|
Chris@114
|
288 im[3] = 999;
|
Chris@114
|
289 FFTReal(4).inverse(re, im, back);
|
Chris@114
|
290 COMPARE_ARRAY(back, in);
|
Chris@114
|
291 }
|
Chris@159
|
292
|
Chris@159
|
293 BOOST_AUTO_TEST_CASE(c_sineCosine)
|
Chris@159
|
294 {
|
Chris@159
|
295 double rin[] = { 1, 0, -1, 0 };
|
Chris@159
|
296 double iin[] = { 0, 1, 0, -1 };
|
Chris@159
|
297 double re[] = { 999, 999, 999, 999 };
|
Chris@159
|
298 double im[] = { 999, 999, 999, 999 };
|
Chris@159
|
299 FFT(4).process(false, rin, iin, re, im);
|
Chris@159
|
300 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@159
|
301 BOOST_CHECK_EQUAL(re[1], 4.0);
|
Chris@159
|
302 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@159
|
303 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@159
|
304 COMPARE_CONST(im, 0.0);
|
Chris@159
|
305 double back[4];
|
Chris@159
|
306 double backim[4];
|
Chris@159
|
307 FFT(4).process(true, re, im, back, backim);
|
Chris@159
|
308 COMPARE_ARRAY(back, rin);
|
Chris@159
|
309 COMPARE_ARRAY(backim, iin);
|
Chris@159
|
310 }
|
Chris@114
|
311
|
Chris@114
|
312 BOOST_AUTO_TEST_CASE(nyquist)
|
Chris@114
|
313 {
|
Chris@114
|
314 double in[] = { 1, -1, 1, -1 };
|
Chris@114
|
315 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
316 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
317 FFT(4).process(false, in, 0, re, im);
|
Chris@114
|
318 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@114
|
319 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@114
|
320 BOOST_CHECK_EQUAL(re[2], 4.0);
|
Chris@114
|
321 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@114
|
322 COMPARE_CONST(im, 0.0);
|
Chris@114
|
323 double back[4];
|
Chris@114
|
324 double backim[4];
|
Chris@114
|
325 FFT(4).process(true, re, im, back, backim);
|
Chris@114
|
326 COMPARE_ARRAY(back, in);
|
Chris@114
|
327 COMPARE_CONST(backim, 0.0);
|
Chris@114
|
328 }
|
Chris@114
|
329
|
Chris@114
|
330 BOOST_AUTO_TEST_CASE(r_nyquist)
|
Chris@114
|
331 {
|
Chris@114
|
332 double in[] = { 1, -1, 1, -1 };
|
Chris@114
|
333 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
334 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
335 FFTReal(4).forward(in, re, im);
|
Chris@114
|
336 BOOST_CHECK_EQUAL(re[0], 0.0);
|
Chris@114
|
337 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@114
|
338 BOOST_CHECK_EQUAL(re[2], 4.0);
|
Chris@114
|
339 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@114
|
340 COMPARE_CONST(im, 0.0);
|
Chris@114
|
341 double back[4];
|
Chris@114
|
342 // check conjugates are reconstructed
|
Chris@114
|
343 re[3] = 999;
|
Chris@114
|
344 im[3] = 999;
|
Chris@114
|
345 FFTReal(4).inverse(re, im, back);
|
Chris@114
|
346 COMPARE_ARRAY(back, in);
|
Chris@114
|
347 }
|
Chris@114
|
348
|
Chris@114
|
349 BOOST_AUTO_TEST_CASE(dirac)
|
Chris@114
|
350 {
|
Chris@114
|
351 double in[] = { 1, 0, 0, 0 };
|
Chris@114
|
352 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
353 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
354 FFT(4).process(false, in, 0, re, im);
|
Chris@114
|
355 BOOST_CHECK_EQUAL(re[0], 1.0);
|
Chris@114
|
356 BOOST_CHECK_EQUAL(re[1], 1.0);
|
Chris@114
|
357 BOOST_CHECK_EQUAL(re[2], 1.0);
|
Chris@114
|
358 BOOST_CHECK_EQUAL(re[3], 1.0);
|
Chris@114
|
359 COMPARE_CONST(im, 0.0);
|
Chris@114
|
360 double back[4];
|
Chris@114
|
361 double backim[4];
|
Chris@114
|
362 FFT(4).process(true, re, im, back, backim);
|
Chris@114
|
363 COMPARE_ARRAY(back, in);
|
Chris@114
|
364 COMPARE_CONST(backim, 0.0);
|
Chris@114
|
365 }
|
Chris@114
|
366
|
Chris@114
|
367 BOOST_AUTO_TEST_CASE(r_dirac)
|
Chris@114
|
368 {
|
Chris@114
|
369 double in[] = { 1, 0, 0, 0 };
|
Chris@114
|
370 double re[] = { 999, 999, 999, 999 };
|
Chris@114
|
371 double im[] = { 999, 999, 999, 999 };
|
Chris@114
|
372 FFTReal(4).forward(in, re, im);
|
Chris@114
|
373 BOOST_CHECK_EQUAL(re[0], 1.0);
|
Chris@114
|
374 BOOST_CHECK_EQUAL(re[1], 1.0);
|
Chris@114
|
375 BOOST_CHECK_EQUAL(re[2], 1.0);
|
Chris@114
|
376 BOOST_CHECK_EQUAL(re[3], 1.0);
|
Chris@114
|
377 COMPARE_CONST(im, 0.0);
|
Chris@114
|
378 double back[4];
|
Chris@114
|
379 // check conjugates are reconstructed
|
Chris@114
|
380 re[3] = 999;
|
Chris@114
|
381 im[3] = 999;
|
Chris@114
|
382 FFTReal(4).inverse(re, im, back);
|
Chris@114
|
383 COMPARE_ARRAY(back, in);
|
Chris@114
|
384 }
|
Chris@114
|
385
|
Chris@129
|
386 BOOST_AUTO_TEST_CASE(sizes)
|
Chris@129
|
387 {
|
Chris@129
|
388 // Complex supports any size. A single test with an odd size
|
Chris@129
|
389 // will do here, without getting too much into our expectations
|
Chris@129
|
390 // about supported butterflies etc
|
Chris@129
|
391
|
Chris@129
|
392 double in[] = { 1, 1, 1 };
|
Chris@129
|
393 double re[] = { 999, 999, 999 };
|
Chris@129
|
394 double im[] = { 999, 999, 999 };
|
Chris@129
|
395 FFT(3).process(false, in, 0, re, im);
|
Chris@129
|
396 BOOST_CHECK_EQUAL(re[0], 3.0);
|
Chris@129
|
397 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@129
|
398 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@129
|
399 COMPARE_CONST(im, 0.0);
|
Chris@129
|
400 double back[3];
|
Chris@129
|
401 double backim[3];
|
Chris@129
|
402 FFT(3).process(true, re, im, back, backim);
|
Chris@129
|
403 COMPARE_ARRAY(back, in);
|
Chris@129
|
404 COMPARE_CONST(backim, 0.0);
|
Chris@129
|
405 }
|
Chris@129
|
406
|
Chris@129
|
407 BOOST_AUTO_TEST_CASE(r_sizes)
|
Chris@129
|
408 {
|
Chris@129
|
409 // Real supports any even size, but not odd ones
|
Chris@129
|
410
|
Chris@129
|
411 BOOST_CHECK_THROW(FFTReal r(3), std::invalid_argument);
|
Chris@129
|
412
|
Chris@129
|
413 double in[] = { 1, 1, 1, 1, 1, 1 };
|
Chris@129
|
414 double re[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@129
|
415 double im[] = { 999, 999, 999, 999, 999, 999 };
|
Chris@129
|
416 FFTReal(6).forward(in, re, im);
|
Chris@129
|
417 BOOST_CHECK_EQUAL(re[0], 6.0);
|
Chris@129
|
418 BOOST_CHECK_EQUAL(re[1], 0.0);
|
Chris@129
|
419 BOOST_CHECK_EQUAL(re[2], 0.0);
|
Chris@129
|
420 BOOST_CHECK_EQUAL(re[3], 0.0);
|
Chris@129
|
421 BOOST_CHECK_EQUAL(re[4], 0.0);
|
Chris@129
|
422 BOOST_CHECK_EQUAL(re[5], 0.0);
|
Chris@129
|
423 COMPARE_CONST(im, 0.0);
|
Chris@129
|
424 double back[6];
|
Chris@129
|
425 FFTReal(6).inverse(re, im, back);
|
Chris@129
|
426 COMPARE_ARRAY(back, in);
|
Chris@129
|
427 }
|
Chris@129
|
428
|
Chris@110
|
429 BOOST_AUTO_TEST_SUITE_END()
|
Chris@110
|
430
|