FFT.cpp 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. struct cpx{
  2. cpx(){}
  3. cpx(double aa):a(aa) {}
  4. cpx(double aa, double bb):a(aa),b(bb) {}
  5. double a;
  6. double b;
  7. double modsq(void) const {
  8. return a * a + b * b;
  9. }
  10. cpx bar(void) const {
  11. return cpx(a, -b);
  12. }
  13. };
  14. cpx operator +(cpx a, cpx b) {
  15. return cpx(a.a + b.a, a.b + b.b);
  16. }
  17. cpx operator *(cpx a, cpx b) {
  18. return cpx(a.a * b.a - a.b * b.b, a.a * b.b + a.b * b.a);
  19. }
  20. cpx operator /(cpx a, cpx b) {
  21. cpx r = a * b.bar();
  22. return cpx(r.a / b.modsq(), r.b / b.modsq());
  23. }
  24. cpx EXP(double theta) {
  25. return cpx(cos(theta),sin(theta));
  26. }
  27. const double two_pi = 4 * acos(0);
  28. // in: input array
  29. // out: output array
  30. // step: {SET TO 1} (used internally)
  31. // size: length of the input/output {MUST BE A POWER OF 2} (use nextPowerOf2)
  32. // dir: either plus or minus one (direction of the FFT)
  33. // RESULT: out[k] = \sum_{j=0}^{size - 1} in[j] * exp(dir * 2pi * i * j * k / size)
  34. void FFT(cpx *in, cpx *out, int step, int size, int dir) {
  35. if(size < 1) return;
  36. if(size == 1) {
  37. out[0] = in[0];
  38. return;
  39. }
  40. FFT(in, out, step * 2, size / 2, dir);
  41. FFT(in + step, out + size / 2, step * 2, size / 2, dir);
  42. for(int i = 0 ; i < size / 2 ; i++) {
  43. cpx even = out[i];
  44. cpx odd = out[i + size / 2];
  45. out[i] = even + EXP(dir * two_pi * i / size) * odd;
  46. out[i + size / 2] = even + EXP(dir * two_pi * (i + size / 2) / size) * odd;
  47. }
  48. }
  49. unsigned int nextPowerOf2(unsigned int n) {
  50. unsigned int p = 1;
  51. if (n && !(n & (n - 1))) return n;
  52. while (p < n) p <<= 1;
  53. return p;
  54. }