annotate constant-q-cpp/test/TestFFT.cpp @ 372:af71cbdab621 tip

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