📄 fft4f.c
字号:
int j, k, l, m, mh, nw, nc;
double xr, xi;
nw = ip[0];
if (n > (nw << 3)) {
nw = n >> 3;
makewt(nw, ip, w);
}
nc = ip[1];
if (n > (nc << 1)) {
nc = n >> 1;
makect(nc, ip, w + nw);
}
m = n >> 1;
xr = a[0] + a[n];
a[0] -= a[n];
t[0] = xr - a[m];
t[m] = xr + a[m];
if (n > 2) {
mh = m >> 1;
for (j = 1; j <= mh - 1; j++) {
k = m - j;
xr = a[j] + a[n - j];
a[j] -= a[n - j];
xi = a[k] + a[n - k];
a[k] -= a[n - k];
t[j] = xr - xi;
t[k] = xr + xi;
}
t[mh] = a[mh] + a[n - mh];
a[mh] -= a[n - mh];
dctsub(m, a, nc, w + nw);
if (m > 4) {
bitrv2(m, ip + 2, a);
}
cftsub(m, a, w);
if (m > 4) {
rftsub(m, a, nc, w + nw);
}
xr = a[0] + a[1];
a[n - 1] = a[0] - a[1];
for (j = m - 2; j >= 2; j -= 2) {
a[(j << 1) + 1] = a[j] + a[j + 1];
a[(j << 1) - 1] = a[j] - a[j + 1];
}
a[1] = xr;
l = 2;
m = mh;
while (m >= 2) {
dctsub(m, t, nc, w + nw);
if (m > 4) {
bitrv2(m, ip + 2, t);
}
cftsub(m, t, w);
if (m > 4) {
rftsub(m, t, nc, w + nw);
}
a[n - l] = t[0] - t[1];
a[l] = t[0] + t[1];
k = 0;
for (j = 2; j <= m - 2; j += 2) {
k += l << 2;
a[k - l] = t[j] - t[j + 1];
a[k + l] = t[j] + t[j + 1];
}
l <<= 1;
mh = m >> 1;
for (j = 0; j <= mh - 1; j++) {
k = m - j;
t[j] = t[m + k] - t[m + j];
t[k] = t[m + k] + t[m + j];
}
t[mh] = t[m + mh];
m = mh;
}
a[l] = t[0];
a[n] = t[2] - t[1];
a[0] = t[2] + t[1];
} else {
a[1] = a[0];
a[2] = t[0];
a[0] = t[1];
}
}
void dfst(int n, double *a, double *t, int *ip, double *w)
{
void makewt(int nw, int *ip, double *w);
void makect(int nc, int *ip, double *c);
void bitrv2(int n, int *ip, double *a);
void cftsub(int n, double *a, double *w);
void rftsub(int n, double *a, int nc, double *c);
void dstsub(int n, double *a, int nc, double *c);
int j, k, l, m, mh, nw, nc;
double xr, xi;
nw = ip[0];
if (n > (nw << 3)) {
nw = n >> 3;
makewt(nw, ip, w);
}
nc = ip[1];
if (n > (nc << 1)) {
nc = n >> 1;
makect(nc, ip, w + nw);
}
if (n > 2) {
m = n >> 1;
mh = m >> 1;
for (j = 1; j <= mh - 1; j++) {
k = m - j;
xr = a[j] - a[n - j];
a[j] += a[n - j];
xi = a[k] - a[n - k];
a[k] += a[n - k];
t[j] = xr + xi;
t[k] = xr - xi;
}
t[0] = a[mh] - a[n - mh];
a[mh] += a[n - mh];
a[0] = a[m];
dstsub(m, a, nc, w + nw);
if (m > 4) {
bitrv2(m, ip + 2, a);
}
cftsub(m, a, w);
if (m > 4) {
rftsub(m, a, nc, w + nw);
}
xr = a[0] + a[1];
a[n - 1] = a[1] - a[0];
for (j = m - 2; j >= 2; j -= 2) {
a[(j << 1) + 1] = a[j] - a[j + 1];
a[(j << 1) - 1] = -a[j] - a[j + 1];
}
a[1] = xr;
l = 2;
m = mh;
while (m >= 2) {
dstsub(m, t, nc, w + nw);
if (m > 4) {
bitrv2(m, ip + 2, t);
}
cftsub(m, t, w);
if (m > 4) {
rftsub(m, t, nc, w + nw);
}
a[n - l] = t[1] - t[0];
a[l] = t[0] + t[1];
k = 0;
for (j = 2; j <= m - 2; j += 2) {
k += l << 2;
a[k - l] = -t[j] - t[j + 1];
a[k + l] = t[j] - t[j + 1];
}
l <<= 1;
mh = m >> 1;
for (j = 1; j <= mh - 1; j++) {
k = m - j;
t[j] = t[m + k] + t[m + j];
t[k] = t[m + k] - t[m + j];
}
t[0] = t[m + mh];
m = mh;
}
a[l] = t[0];
}
a[0] = 0;
}
/* -------- initializing routines -------- */
#include <math.h>
void makewt(int nw, int *ip, double *w)
{
void bitrv2(int n, int *ip, double *a);
int nwh, j;
double delta, x, y;
ip[0] = nw;
ip[1] = 1;
if (nw > 2) {
nwh = nw >> 1;
delta = atan(1.0) / nwh;
w[0] = 1;
w[1] = 0;
w[nwh] = cos(delta * nwh);
w[nwh + 1] = w[nwh];
for (j = 2; j <= nwh - 2; j += 2) {
x = cos(delta * j);
y = sin(delta * j);
w[j] = x;
w[j + 1] = y;
w[nw - j] = y;
w[nw - j + 1] = x;
}
bitrv2(nw, ip + 2, w);
}
}
void makect(int nc, int *ip, double *c)
{
int nch, j;
double delta;
ip[1] = nc;
if (nc > 1) {
nch = nc >> 1;
delta = atan(1.0) / nch;
c[0] = 0.5;
c[nch] = 0.5 * cos(delta * nch);
for (j = 1; j <= nch - 1; j++) {
c[j] = 0.5 * cos(delta * j);
c[nc - j] = 0.5 * sin(delta * j);
}
}
}
/* -------- child routines -------- */
void bitrv2(int n, int *ip, double *a)
{
int j, j1, k, k1, l, m, m2;
double xr, xi;
ip[0] = 0;
l = n;
m = 1;
while ((m << 2) < l) {
l >>= 1;
for (j = 0; j <= m - 1; j++) {
ip[m + j] = ip[j] + l;
}
m <<= 1;
}
if ((m << 2) > l) {
for (k = 1; k <= m - 1; k++) {
for (j = 0; j <= k - 1; j++) {
j1 = (j << 1) + ip[k];
k1 = (k << 1) + ip[j];
xr = a[j1];
xi = a[j1 + 1];
a[j1] = a[k1];
a[j1 + 1] = a[k1 + 1];
a[k1] = xr;
a[k1 + 1] = xi;
}
}
} else {
m2 = m << 1;
for (k = 1; k <= m - 1; k++) {
for (j = 0; j <= k - 1; j++) {
j1 = (j << 1) + ip[k];
k1 = (k << 1) + ip[j];
xr = a[j1];
xi = a[j1 + 1];
a[j1] = a[k1];
a[j1 + 1] = a[k1 + 1];
a[k1] = xr;
a[k1 + 1] = xi;
j1 += m2;
k1 += m2;
xr = a[j1];
xi = a[j1 + 1];
a[j1] = a[k1];
a[j1 + 1] = a[k1 + 1];
a[k1] = xr;
a[k1 + 1] = xi;
}
}
}
}
void cftsub(int n, double *a, double *w)
{
int j, j1, j2, j3, k, k1, ks, l, m;
double wk1r, wk1i, wk2r, wk2i, wk3r, wk3i;
double x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
l = 2;
while ((l << 1) < n) {
m = l << 2;
for (j = 0; j <= l - 2; j += 2) {
j1 = j + l;
j2 = j1 + l;
j3 = j2 + l;
x0r = a[j] + a[j1];
x0i = a[j + 1] + a[j1 + 1];
x1r = a[j] - a[j1];
x1i = a[j + 1] - a[j1 + 1];
x2r = a[j2] + a[j3];
x2i = a[j2 + 1] + a[j3 + 1];
x3r = a[j2] - a[j3];
x3i = a[j2 + 1] - a[j3 + 1];
a[j] = x0r + x2r;
a[j + 1] = x0i + x2i;
a[j2] = x0r - x2r;
a[j2 + 1] = x0i - x2i;
a[j1] = x1r - x3i;
a[j1 + 1] = x1i + x3r;
a[j3] = x1r + x3i;
a[j3 + 1] = x1i - x3r;
}
if (m < n) {
wk1r = w[2];
for (j = m; j <= l + m - 2; j += 2) {
j1 = j + l;
j2 = j1 + l;
j3 = j2 + l;
x0r = a[j] + a[j1];
x0i = a[j + 1] + a[j1 + 1];
x1r = a[j] - a[j1];
x1i = a[j + 1] - a[j1 + 1];
x2r = a[j2] + a[j3];
x2i = a[j2 + 1] + a[j3 + 1];
x3r = a[j2] - a[j3];
x3i = a[j2 + 1] - a[j3 + 1];
a[j] = x0r + x2r;
a[j + 1] = x0i + x2i;
a[j2] = x2i - x0i;
a[j2 + 1] = x0r - x2r;
x0r = x1r - x3i;
x0i = x1i + x3r;
a[j1] = wk1r * (x0r - x0i);
a[j1 + 1] = wk1r * (x0r + x0i);
x0r = x3i + x1r;
x0i = x3r - x1i;
a[j3] = wk1r * (x0i - x0r);
a[j3 + 1] = wk1r * (x0i + x0r);
}
k1 = 1;
ks = -1;
for (k = (m << 1); k <= n - m; k += m) {
k1++;
ks = -ks;
wk1r = w[k1 << 1];
wk1i = w[(k1 << 1) + 1];
wk2r = ks * w[k1];
wk2i = w[k1 + ks];
wk3r = wk1r - 2 * wk2i * wk1i;
wk3i = 2 * wk2i * wk1r - wk1i;
for (j = k; j <= l + k - 2; j += 2) {
j1 = j + l;
j2 = j1 + l;
j3 = j2 + l;
x0r = a[j] + a[j1];
x0i = a[j + 1] + a[j1 + 1];
x1r = a[j] - a[j1];
x1i = a[j + 1] - a[j1 + 1];
x2r = a[j2] + a[j3];
x2i = a[j2 + 1] + a[j3 + 1];
x3r = a[j2] - a[j3];
x3i = a[j2 + 1] - a[j3 + 1];
a[j] = x0r + x2r;
a[j + 1] = x0i + x2i;
x0r -= x2r;
x0i -= x2i;
a[j2] = wk2r * x0r - wk2i * x0i;
a[j2 + 1] = wk2r * x0i + wk2i * x0r;
x0r = x1r - x3i;
x0i = x1i + x3r;
a[j1] = wk1r * x0r - wk1i * x0i;
a[j1 + 1] = wk1r * x0i + wk1i * x0r;
x0r = x1r + x3i;
x0i = x1i - x3r;
a[j3] = wk3r * x0r - wk3i * x0i;
a[j3 + 1] = wk3r * x0i + wk3i * x0r;
}
}
}
l = m;
}
if (l < n) {
for (j = 0; j <= l - 2; j += 2) {
j1 = j + l;
x0r = a[j] - a[j1];
x0i = a[j + 1] - a[j1 + 1];
a[j] += a[j1];
a[j + 1] += a[j1 + 1];
a[j1] = x0r;
a[j1 + 1] = x0i;
}
}
}
void rftsub(int n, double *a, int nc, double *c)
{
int j, k, kk, ks;
double wkr, wki, xr, xi, yr, yi;
ks = (nc << 2) / n;
kk = 0;
for (k = (n >> 1) - 2; k >= 2; k -= 2) {
j = n - k;
kk += ks;
wkr = 0.5 - c[kk];
wki = c[nc - kk];
xr = a[k] - a[j];
xi = a[k + 1] + a[j + 1];
yr = wkr * xr - wki * xi;
yi = wkr * xi + wki * xr;
a[k] -= yr;
a[k + 1] -= yi;
a[j] += yr;
a[j + 1] -= yi;
}
}
void dctsub(int n, double *a, int nc, double *c)
{
int j, k, kk, ks, m;
double wkr, wki, xr;
ks = nc / n;
kk = ks;
m = n >> 1;
for (k = 1; k <= m - 1; k++) {
j = n - k;
wkr = c[kk] - c[nc - kk];
wki = c[kk] + c[nc - kk];
kk += ks;
xr = wki * a[k] - wkr * a[j];
a[k] = wkr * a[k] + wki * a[j];
a[j] = xr;
}
a[m] *= 2 * c[kk];
}
void dstsub(int n, double *a, int nc, double *c)
{
int j, k, kk, ks, m;
double wkr, wki, xr;
ks = nc / n;
kk = ks;
m = n >> 1;
for (k = 1; k <= m - 1; k++) {
j = n - k;
wkr = c[kk] - c[nc - kk];
wki = c[kk] + c[nc - kk];
kk += ks;
xr = wki * a[j] - wkr * a[k];
a[j] = wkr * a[j] + wki * a[k];
a[k] = xr;
}
a[m] *= 2 * c[kk];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -