annotate tests/TestFFT.cpp @ 395:a0829908bb74

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