NANA
fft.cpp
1#include "..\include\math\fft.h"
2#include <cmath>
3
4namespace NANA {
5namespace MATH {
6
7
8
9void fft(NAFLOAT* p, Complex<NAFLOAT>* f, int n, int k) {
10 int it, m, is, i, j, nv;
11 double q, s, poddr, poddi;
12 for(it = 0; it < n; ++it) {
13 m = it;
14 is = 0;
15 for (i = 0; i < k; ++i) {
16 j = m >> 1;
17 is = is << 1 + (m - j << 1);
18 m = j;
19 f[it].re = p[is];
20 f[it].im = 0.0;
21 }
22 }
23 std::vector<NAFLOAT> pm(n);//记录傅里叶变换的模
24 std::memcpy(&pm[0], p, n * sizeof(NAFLOAT));
25 std::vector<NAFLOAT> pt(n,0.0);//记录傅里叶变换的幅角
26 double temp = NA_2PI / static_cast<NAFLOAT>(n);
27 pm[0] = 1.0;
28 pt[0] = 0.0;
29 pm[1] = std::cos(temp);
30 pt[1] = -std::sin(temp);
31 for (i = 2; i < n - 1; ++i) {
32 temp = pm[i - 1] * pm[1];
33 q = pt[i - 1] * pt[i];
34 s = (pm[i - 1] + pt[i - 1]) * (pm[1] + pt[1]);
35 pm[i] = temp - q;
36 pt[i] = s - temp - q;
37 }
38 m = n >> 1;
39 nv = 2;
40 for (i = k - 2; i >= 0; --i) {
41 m >>= 1;
42 nv <<= 1;
43 for (it = 0; it <= (m - 1) * nv; it += nv) {
44 for (j = 0; j < (nv >> 1); ++j) {
45 temp = pm[m * j] * f[it + j + nv >> 1].re;
46 q = pt[m * j] * f[it + j + nv >> 1].im;
47 s = pm[m * j] + pt[m * j];
48 s *= (f[it + j + nv >> 1].re+ f[it + j + nv >> 1].im);
49 poddr = temp - q;
50 poddi = s - poddr;
51 f[it + j + nv >> 1].re = f[it + j].re - poddr;
52 f[it + j + nv >> 1].im = f[it + j].im - poddi;
53 f[it + j].re += poddr;
54 f[it + j].im += poddi;
55 }
56 }
57 }
58
59
60
61}
62
63}
64}
65
66
67
68
复数类,用于实现复数的加减乘除运算
Definition: Complex.hpp:26
void NA_API fft(NAFLOAT *p, Complex< NAFLOAT > *f, int n, int k)
实现快速傅里叶变换
Definition: fft.cpp:9
#define NA_2PI
二倍圆周率
Definition: nadef.hpp:37