fft.cpp 1.32 KB
Newer Older
1 2 3 4 5 6
#include "benchmark_base/fft.h"

namespace comparison_benchmarks {
namespace base {
namespace fft {

7 8 9
void fill_input(fft::complex_vector &data) {
  for (size_t i = 0; i < data.size(); i++) {
    data[i] = std::complex<double>(sin(i), 0.0);
10 11 12
  }
}

13
void divide(complex_vector::iterator data, complex_vector::iterator tmp_odd_elements, int n) {
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
  for (int i = 0; i < n / 2; i++) {
    tmp_odd_elements[i] = data[i * 2 + 1];
  }
  for (int i = 0; i < n / 2; i++) {
    data[i] = data[i * 2];
  }
  for (int i = 0; i < n / 2; i++) {
    data[i + n / 2] = tmp_odd_elements[i];
  }
}

void combine(complex_vector::iterator data, int n) {
  for (int i = 0; i < n / 2; i++) {
    std::complex<double> even = data[i];
    std::complex<double> odd = data[i + n / 2];

    // w is the "twiddle-factor".
    // this could be cached, but we run the same 'base' algorithm parallel/serial,
    // so it won't impact the performance comparison.
    std::complex<double> w = exp(std::complex<double>(0, -2. * M_PI * i / n));

    data[i] = even + w * odd;
    data[i + n / 2] = even - w * odd;
  }
}

40
void conquer(complex_vector::iterator data, complex_vector::iterator swap_array, int n) {
41 42 43 44
  if (n < 2) {
    return;
  }

45 46 47
  divide(data, swap_array, n);
  conquer(data, swap_array, n / 2);
  conquer(data + n / 2, swap_array + n / 2, n / 2);
48 49 50 51 52 53
  combine(data, n);
}

}
}
}