annotate tests/TestFFT.cpp @ 209:ccd2019190bf msvc

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