ooura_fft 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +17 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +82 -0
- data/Rakefile +19 -0
- data/ext/ooura_fft/abi/fftsg/fftsg.c +3528 -0
- data/ext/ooura_fft/abi/fftsg/fftsg.h +307 -0
- data/ext/ooura_fft/abi/fftsg/readme.txt +167 -0
- data/ext/ooura_fft/extconf.rb +18 -0
- data/ext/ooura_fft/fft.c +307 -0
- data/ext/ooura_fft/internal/setting/ooura_fft.h +17 -0
- data/ext/ooura_fft/internal/solver/ooura_fft/cdft.h +52 -0
- data/ext/ooura_fft/internal/solver/ooura_fft/ddct.h +47 -0
- data/ext/ooura_fft/internal/solver/ooura_fft/ddst.h +47 -0
- data/ext/ooura_fft/internal/solver/ooura_fft/dfct.h +55 -0
- data/ext/ooura_fft/internal/solver/ooura_fft/dfst.h +52 -0
- data/ext/ooura_fft/internal/solver/ooura_fft/rdft.h +47 -0
- data/ext/ooura_fft/missing/ispow2l.c +9 -0
- data/ext/ooura_fft/missing/missing.h +21 -0
- data/ext/ooura_fft/ooura_fft/api.h +13 -0
- data/ext/ooura_fft/ooura_fft/ext_extern.h +18 -0
- data/ext/ooura_fft/ooura_fft/globals.h +9 -0
- data/ext/ooura_fft/ooura_fft.c +56 -0
- data/lib/ooura_fft/version.rb +6 -0
- data/lib/ooura_fft.rb +6 -0
- data/sig/ooura_fft.rbs +4 -0
- metadata +116 -0
@@ -0,0 +1,307 @@
|
|
1
|
+
/*******************************************************************************
|
2
|
+
Fast Fourier/Cosine/Sine Transform
|
3
|
+
dimension :one
|
4
|
+
data length :power of 2
|
5
|
+
decimation :frequency
|
6
|
+
radix :split-radix
|
7
|
+
data :inplace
|
8
|
+
table :use
|
9
|
+
functions
|
10
|
+
cdft: Complex Discrete Fourier Transform
|
11
|
+
rdft: Real Discrete Fourier Transform
|
12
|
+
ddct: Discrete Cosine Transform
|
13
|
+
ddst: Discrete Sine Transform
|
14
|
+
dfct: Cosine Transform of RDFT (Real Symmetric DFT)
|
15
|
+
dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
|
16
|
+
function prototypes
|
17
|
+
void cdft(int, int, double *, int *, double *);
|
18
|
+
void rdft(int, int, double *, int *, double *);
|
19
|
+
void ddct(int, int, double *, int *, double *);
|
20
|
+
void ddst(int, int, double *, int *, double *);
|
21
|
+
void dfct(int, double *, double *, int *, double *);
|
22
|
+
void dfst(int, double *, double *, int *, double *);
|
23
|
+
macro definitions
|
24
|
+
USE_CDFT_PTHREADS : default=not defined
|
25
|
+
CDFT_THREADS_BEGIN_N : must be >= 512, default=8192
|
26
|
+
CDFT_4THREADS_BEGIN_N : must be >= 512, default=65536
|
27
|
+
USE_CDFT_WINTHREADS : default=not defined
|
28
|
+
CDFT_THREADS_BEGIN_N : must be >= 512, default=32768
|
29
|
+
CDFT_4THREADS_BEGIN_N : must be >= 512, default=524288
|
30
|
+
*******************************************************************************/
|
31
|
+
#ifndef OOURA_FFTSG_H
|
32
|
+
#define OOURA_FFTSG_H
|
33
|
+
|
34
|
+
#if defined(__cplusplus)
|
35
|
+
extern "C" {
|
36
|
+
#endif
|
37
|
+
|
38
|
+
/*
|
39
|
+
-------- Complex DFT (Discrete Fourier Transform) --------
|
40
|
+
[definition]
|
41
|
+
<case1>
|
42
|
+
X[k] = sum_j=0^n-1 x[j]*exp(2*pi*i*j*k/n), 0<=k<n
|
43
|
+
<case2>
|
44
|
+
X[k] = sum_j=0^n-1 x[j]*exp(-2*pi*i*j*k/n), 0<=k<n
|
45
|
+
(notes: sum_j=0^n-1 is a summation from j=0 to n-1)
|
46
|
+
[usage]
|
47
|
+
<case1>
|
48
|
+
ip[0] = 0; // first time only
|
49
|
+
cdft(2*n, 1, a, ip, w);
|
50
|
+
<case2>
|
51
|
+
ip[0] = 0; // first time only
|
52
|
+
cdft(2*n, -1, a, ip, w);
|
53
|
+
[parameters]
|
54
|
+
2*n :data length (int)
|
55
|
+
n >= 1, n = power of 2
|
56
|
+
a[0...2*n-1] :input/output data (double *)
|
57
|
+
input data
|
58
|
+
a[2*j] = Re(x[j]),
|
59
|
+
a[2*j+1] = Im(x[j]), 0<=j<n
|
60
|
+
output data
|
61
|
+
a[2*k] = Re(X[k]),
|
62
|
+
a[2*k+1] = Im(X[k]), 0<=k<n
|
63
|
+
ip[0...*] :work area for bit reversal (int *)
|
64
|
+
length of ip >= 2+sqrt(n)
|
65
|
+
strictly,
|
66
|
+
length of ip >=
|
67
|
+
2+(1<<(int)(log(n+0.5)/log(2))/2).
|
68
|
+
ip[0],ip[1] are pointers of the cos/sin table.
|
69
|
+
w[0...n/2-1] :cos/sin table (double *)
|
70
|
+
w[],ip[] are initialized if ip[0] == 0.
|
71
|
+
[remark]
|
72
|
+
Inverse of
|
73
|
+
cdft(2*n, -1, a, ip, w);
|
74
|
+
is
|
75
|
+
cdft(2*n, 1, a, ip, w);
|
76
|
+
for (j = 0; j <= 2 * n - 1; j++) {
|
77
|
+
a[j] *= 1.0 / n;
|
78
|
+
}
|
79
|
+
.
|
80
|
+
*/
|
81
|
+
extern void cdft(int n, int isgn, double *a, int *ip, double *w);
|
82
|
+
|
83
|
+
/*
|
84
|
+
-------- Real DFT / Inverse of Real DFT --------
|
85
|
+
[definition]
|
86
|
+
<case1> RDFT
|
87
|
+
R[k] = sum_j=0^n-1 a[j]*cos(2*pi*j*k/n), 0<=k<=n/2
|
88
|
+
I[k] = sum_j=0^n-1 a[j]*sin(2*pi*j*k/n), 0<k<n/2
|
89
|
+
<case2> IRDFT (excluding scale)
|
90
|
+
a[k] = (R[0] + R[n/2]*cos(pi*k))/2 +
|
91
|
+
sum_j=1^n/2-1 R[j]*cos(2*pi*j*k/n) +
|
92
|
+
sum_j=1^n/2-1 I[j]*sin(2*pi*j*k/n), 0<=k<n
|
93
|
+
[usage]
|
94
|
+
<case1>
|
95
|
+
ip[0] = 0; // first time only
|
96
|
+
rdft(n, 1, a, ip, w);
|
97
|
+
<case2>
|
98
|
+
ip[0] = 0; // first time only
|
99
|
+
rdft(n, -1, a, ip, w);
|
100
|
+
[parameters]
|
101
|
+
n :data length (int)
|
102
|
+
n >= 2, n = power of 2
|
103
|
+
a[0...n-1] :input/output data (double *)
|
104
|
+
<case1>
|
105
|
+
output data
|
106
|
+
a[2*k] = R[k], 0<=k<n/2
|
107
|
+
a[2*k+1] = I[k], 0<k<n/2
|
108
|
+
a[1] = R[n/2]
|
109
|
+
<case2>
|
110
|
+
input data
|
111
|
+
a[2*j] = R[j], 0<=j<n/2
|
112
|
+
a[2*j+1] = I[j], 0<j<n/2
|
113
|
+
a[1] = R[n/2]
|
114
|
+
ip[0...*] :work area for bit reversal (int *)
|
115
|
+
length of ip >= 2+sqrt(n/2)
|
116
|
+
strictly,
|
117
|
+
length of ip >=
|
118
|
+
2+(1<<(int)(log(n/2+0.5)/log(2))/2).
|
119
|
+
ip[0],ip[1] are pointers of the cos/sin table.
|
120
|
+
w[0...n/2-1] :cos/sin table (double *)
|
121
|
+
w[],ip[] are initialized if ip[0] == 0.
|
122
|
+
[remark]
|
123
|
+
Inverse of
|
124
|
+
rdft(n, 1, a, ip, w);
|
125
|
+
is
|
126
|
+
rdft(n, -1, a, ip, w);
|
127
|
+
for (j = 0; j <= n - 1; j++) {
|
128
|
+
a[j] *= 2.0 / n;
|
129
|
+
}
|
130
|
+
.
|
131
|
+
*/
|
132
|
+
extern void rdft(int n, int isgn, double *a, int *ip, double *w);
|
133
|
+
|
134
|
+
/*
|
135
|
+
-------- DCT (Discrete Cosine Transform) / Inverse of DCT --------
|
136
|
+
[definition]
|
137
|
+
<case1> IDCT (excluding scale)
|
138
|
+
C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n
|
139
|
+
<case2> DCT
|
140
|
+
C[k] = sum_j=0^n-1 a[j]*cos(pi*(j+1/2)*k/n), 0<=k<n
|
141
|
+
[usage]
|
142
|
+
<case1>
|
143
|
+
ip[0] = 0; // first time only
|
144
|
+
ddct(n, 1, a, ip, w);
|
145
|
+
<case2>
|
146
|
+
ip[0] = 0; // first time only
|
147
|
+
ddct(n, -1, a, ip, w);
|
148
|
+
[parameters]
|
149
|
+
n :data length (int)
|
150
|
+
n >= 2, n = power of 2
|
151
|
+
a[0...n-1] :input/output data (double *)
|
152
|
+
output data
|
153
|
+
a[k] = C[k], 0<=k<n
|
154
|
+
ip[0...*] :work area for bit reversal (int *)
|
155
|
+
length of ip >= 2+sqrt(n/2)
|
156
|
+
strictly,
|
157
|
+
length of ip >=
|
158
|
+
2+(1<<(int)(log(n/2+0.5)/log(2))/2).
|
159
|
+
ip[0],ip[1] are pointers of the cos/sin table.
|
160
|
+
w[0...n*5/4-1] :cos/sin table (double *)
|
161
|
+
w[],ip[] are initialized if ip[0] == 0.
|
162
|
+
[remark]
|
163
|
+
Inverse of
|
164
|
+
ddct(n, -1, a, ip, w);
|
165
|
+
is
|
166
|
+
a[0] *= 0.5;
|
167
|
+
ddct(n, 1, a, ip, w);
|
168
|
+
for (j = 0; j <= n - 1; j++) {
|
169
|
+
a[j] *= 2.0 / n;
|
170
|
+
}
|
171
|
+
.
|
172
|
+
*/
|
173
|
+
extern void ddct(int n, int isgn, double *a, int *ip, double *w);
|
174
|
+
|
175
|
+
/*
|
176
|
+
-------- DST (Discrete Sine Transform) / Inverse of DST --------
|
177
|
+
[definition]
|
178
|
+
<case1> IDST (excluding scale)
|
179
|
+
S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n
|
180
|
+
<case2> DST
|
181
|
+
S[k] = sum_j=0^n-1 a[j]*sin(pi*(j+1/2)*k/n), 0<k<=n
|
182
|
+
[usage]
|
183
|
+
<case1>
|
184
|
+
ip[0] = 0; // first time only
|
185
|
+
ddst(n, 1, a, ip, w);
|
186
|
+
<case2>
|
187
|
+
ip[0] = 0; // first time only
|
188
|
+
ddst(n, -1, a, ip, w);
|
189
|
+
[parameters]
|
190
|
+
n :data length (int)
|
191
|
+
n >= 2, n = power of 2
|
192
|
+
a[0...n-1] :input/output data (double *)
|
193
|
+
<case1>
|
194
|
+
input data
|
195
|
+
a[j] = A[j], 0<j<n
|
196
|
+
a[0] = A[n]
|
197
|
+
output data
|
198
|
+
a[k] = S[k], 0<=k<n
|
199
|
+
<case2>
|
200
|
+
output data
|
201
|
+
a[k] = S[k], 0<k<n
|
202
|
+
a[0] = S[n]
|
203
|
+
ip[0...*] :work area for bit reversal (int *)
|
204
|
+
length of ip >= 2+sqrt(n/2)
|
205
|
+
strictly,
|
206
|
+
length of ip >=
|
207
|
+
2+(1<<(int)(log(n/2+0.5)/log(2))/2).
|
208
|
+
ip[0],ip[1] are pointers of the cos/sin table.
|
209
|
+
w[0...n*5/4-1] :cos/sin table (double *)
|
210
|
+
w[],ip[] are initialized if ip[0] == 0.
|
211
|
+
[remark]
|
212
|
+
Inverse of
|
213
|
+
ddst(n, -1, a, ip, w);
|
214
|
+
is
|
215
|
+
a[0] *= 0.5;
|
216
|
+
ddst(n, 1, a, ip, w);
|
217
|
+
for (j = 0; j <= n - 1; j++) {
|
218
|
+
a[j] *= 2.0 / n;
|
219
|
+
}
|
220
|
+
.
|
221
|
+
*/
|
222
|
+
extern void ddst(int n, int isgn, double *a, int *ip, double *w);
|
223
|
+
|
224
|
+
/*
|
225
|
+
-------- Cosine Transform of RDFT (Real Symmetric DFT) --------
|
226
|
+
[definition]
|
227
|
+
C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
|
228
|
+
[usage]
|
229
|
+
ip[0] = 0; // first time only
|
230
|
+
dfct(n, a, t, ip, w);
|
231
|
+
[parameters]
|
232
|
+
n :data length - 1 (int)
|
233
|
+
n >= 2, n = power of 2
|
234
|
+
a[0...n] :input/output data (double *)
|
235
|
+
output data
|
236
|
+
a[k] = C[k], 0<=k<=n
|
237
|
+
t[0...n/2] :work area (double *)
|
238
|
+
ip[0...*] :work area for bit reversal (int *)
|
239
|
+
length of ip >= 2+sqrt(n/4)
|
240
|
+
strictly,
|
241
|
+
length of ip >=
|
242
|
+
2+(1<<(int)(log(n/4+0.5)/log(2))/2).
|
243
|
+
ip[0],ip[1] are pointers of the cos/sin table.
|
244
|
+
w[0...n*5/8-1] :cos/sin table (double *)
|
245
|
+
w[],ip[] are initialized if ip[0] == 0.
|
246
|
+
[remark]
|
247
|
+
Inverse of
|
248
|
+
a[0] *= 0.5;
|
249
|
+
a[n] *= 0.5;
|
250
|
+
dfct(n, a, t, ip, w);
|
251
|
+
is
|
252
|
+
a[0] *= 0.5;
|
253
|
+
a[n] *= 0.5;
|
254
|
+
dfct(n, a, t, ip, w);
|
255
|
+
for (j = 0; j <= n; j++) {
|
256
|
+
a[j] *= 2.0 / n;
|
257
|
+
}
|
258
|
+
.
|
259
|
+
*/
|
260
|
+
extern void dfct(int n, double *a, double *t, int *ip, double *w);
|
261
|
+
|
262
|
+
/*
|
263
|
+
-------- Sine Transform of RDFT (Real Anti-symmetric DFT) --------
|
264
|
+
[definition]
|
265
|
+
S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
|
266
|
+
[usage]
|
267
|
+
ip[0] = 0; // first time only
|
268
|
+
dfst(n, a, t, ip, w);
|
269
|
+
[parameters]
|
270
|
+
n :data length + 1 (int)
|
271
|
+
n >= 2, n = power of 2
|
272
|
+
a[0...n-1] :input/output data (double *)
|
273
|
+
output data
|
274
|
+
a[k] = S[k], 0<k<n
|
275
|
+
(a[0] is used for work area)
|
276
|
+
t[0...n/2-1] :work area (double *)
|
277
|
+
ip[0...*] :work area for bit reversal (int *)
|
278
|
+
length of ip >= 2+sqrt(n/4)
|
279
|
+
strictly,
|
280
|
+
length of ip >=
|
281
|
+
2+(1<<(int)(log(n/4+0.5)/log(2))/2).
|
282
|
+
ip[0],ip[1] are pointers of the cos/sin table.
|
283
|
+
w[0...n*5/8-1] :cos/sin table (double *)
|
284
|
+
w[],ip[] are initialized if ip[0] == 0.
|
285
|
+
[remark]
|
286
|
+
Inverse of
|
287
|
+
dfst(n, a, t, ip, w);
|
288
|
+
is
|
289
|
+
dfst(n, a, t, ip, w);
|
290
|
+
for (j = 1; j <= n - 1; j++) {
|
291
|
+
a[j] *= 2.0 / n;
|
292
|
+
}
|
293
|
+
.
|
294
|
+
*/
|
295
|
+
extern void dfst(int n, double *a, double *t, int *ip, double *w);
|
296
|
+
|
297
|
+
/*
|
298
|
+
Appendix :
|
299
|
+
The cos/sin table is recalculated when the larger table required.
|
300
|
+
w[] and ip[] are compatible with all routines.
|
301
|
+
*/
|
302
|
+
|
303
|
+
#if defined(__cplusplus)
|
304
|
+
}
|
305
|
+
#endif
|
306
|
+
|
307
|
+
#endif /* OOURA_FFTSG_H */
|
@@ -0,0 +1,167 @@
|
|
1
|
+
General Purpose FFT (Fast Fourier/Cosine/Sine Transform) Package
|
2
|
+
|
3
|
+
Description:
|
4
|
+
A package to calculate Discrete Fourier/Cosine/Sine Transforms of
|
5
|
+
1-dimensional sequences of length 2^N.
|
6
|
+
|
7
|
+
Files:
|
8
|
+
fft4g.c : FFT Package in C - Fast Version I (radix 4,2)
|
9
|
+
fft4g.f : FFT Package in Fortran - Fast Version I (radix 4,2)
|
10
|
+
fft4g_h.c : FFT Package in C - Simple Version I (radix 4,2)
|
11
|
+
fft8g.c : FFT Package in C - Fast Version II (radix 8,4,2)
|
12
|
+
fft8g.f : FFT Package in Fortran - Fast Version II (radix 8,4,2)
|
13
|
+
fft8g_h.c : FFT Package in C - Simple Version II (radix 8,4,2)
|
14
|
+
fftsg.c : FFT Package in C - Fast Version III (Split-Radix)
|
15
|
+
fftsg.f : FFT Package in Fortran - Fast Version III (Split-Radix)
|
16
|
+
fftsg_h.c : FFT Package in C - Simple Version III (Split-Radix)
|
17
|
+
readme.txt : Readme File
|
18
|
+
sample1/ : Test Directory
|
19
|
+
Makefile : for gcc, cc
|
20
|
+
Makefile.f77: for Fortran
|
21
|
+
testxg.c : Test Program for "fft*g.c"
|
22
|
+
testxg.f : Test Program for "fft*g.f"
|
23
|
+
testxg_h.c : Test Program for "fft*g_h.c"
|
24
|
+
sample2/ : Benchmark Directory
|
25
|
+
Makefile : for gcc, cc
|
26
|
+
Makefile.pth: POSIX Thread version
|
27
|
+
pi_fft.c : PI(= 3.1415926535897932384626...) Calculation Program
|
28
|
+
for a Benchmark Test for "fft*g.c"
|
29
|
+
|
30
|
+
Difference of the Files:
|
31
|
+
C and Fortran versions are equal and
|
32
|
+
the same routines are in each version.
|
33
|
+
"fft4g*.*" are optimized for most machines.
|
34
|
+
"fft8g*.*" are fast on the UltraSPARC.
|
35
|
+
"fftsg*.*" are optimized for the machines that
|
36
|
+
have the multi-level (L1,L2,etc) cache.
|
37
|
+
The simple versions "fft*g_h.c" use no work area, but
|
38
|
+
the fast versions "fft*g.*" use work areas.
|
39
|
+
The fast versions "fft*g.*" have the same specification.
|
40
|
+
|
41
|
+
Routines in the Package:
|
42
|
+
cdft: Complex Discrete Fourier Transform
|
43
|
+
rdft: Real Discrete Fourier Transform
|
44
|
+
ddct: Discrete Cosine Transform
|
45
|
+
ddst: Discrete Sine Transform
|
46
|
+
dfct: Cosine Transform of RDFT (Real Symmetric DFT)
|
47
|
+
dfst: Sine Transform of RDFT (Real Anti-symmetric DFT)
|
48
|
+
|
49
|
+
Usage:
|
50
|
+
Please refer to the comments in the "fft**.*" file which
|
51
|
+
you want to use. Brief explanations are in the block
|
52
|
+
comments of each package. The examples are also given in
|
53
|
+
the test programs.
|
54
|
+
|
55
|
+
Method:
|
56
|
+
-------- cdft --------
|
57
|
+
fft4g*.*, fft8g*.*:
|
58
|
+
A method of in-place, radix 2^M, Sande-Tukey (decimation in
|
59
|
+
frequency). Index of the butterfly loop is in bit
|
60
|
+
reverse order to keep continuous memory access.
|
61
|
+
fftsg*.*:
|
62
|
+
A method of in-place, Split-Radix, recursive fast
|
63
|
+
algorithm.
|
64
|
+
-------- rdft --------
|
65
|
+
A method with a following butterfly operation appended to "cdft".
|
66
|
+
In forward transform :
|
67
|
+
A[k] = sum_j=0^n-1 a[j]*W(n)^(j*k), 0<=k<=n/2,
|
68
|
+
W(n) = exp(2*pi*i/n),
|
69
|
+
this routine makes an array x[] :
|
70
|
+
x[j] = a[2*j] + i*a[2*j+1], 0<=j<n/2
|
71
|
+
and calls "cdft" of length n/2 :
|
72
|
+
X[k] = sum_j=0^n/2-1 x[j] * W(n/2)^(j*k), 0<=k<n.
|
73
|
+
The result A[k] are :
|
74
|
+
A[k] = X[k] - (1+i*W(n)^k)/2 * (X[k]-conjg(X[n/2-k])),
|
75
|
+
A[n/2-k] = X[n/2-k] +
|
76
|
+
conjg((1+i*W(n)^k)/2 * (X[k]-conjg(X[n/2-k]))),
|
77
|
+
0<=k<=n/2
|
78
|
+
(notes: conjg() is a complex conjugate, X[n/2]=X[0]).
|
79
|
+
-------- ddct --------
|
80
|
+
A method with a following butterfly operation appended to "rdft".
|
81
|
+
In backward transform :
|
82
|
+
C[k] = sum_j=0^n-1 a[j]*cos(pi*j*(k+1/2)/n), 0<=k<n,
|
83
|
+
this routine makes an array r[] :
|
84
|
+
r[0] = a[0],
|
85
|
+
r[j] = Re((a[j] - i*a[n-j]) * W(4*n)^j*(1+i)/2),
|
86
|
+
r[n-j] = Im((a[j] - i*a[n-j]) * W(4*n)^j*(1+i)/2),
|
87
|
+
0<j<=n/2
|
88
|
+
and calls "rdft" of length n :
|
89
|
+
A[k] = sum_j=0^n-1 r[j]*W(n)^(j*k), 0<=k<=n/2,
|
90
|
+
W(n) = exp(2*pi*i/n).
|
91
|
+
The result C[k] are :
|
92
|
+
C[2*k] = Re(A[k] * (1-i)),
|
93
|
+
C[2*k-1] = -Im(A[k] * (1-i)).
|
94
|
+
-------- ddst --------
|
95
|
+
A method with a following butterfly operation appended to "rdft".
|
96
|
+
In backward transform :
|
97
|
+
S[k] = sum_j=1^n A[j]*sin(pi*j*(k+1/2)/n), 0<=k<n,
|
98
|
+
this routine makes an array r[] :
|
99
|
+
r[0] = a[0],
|
100
|
+
r[j] = Im((a[n-j] - i*a[j]) * W(4*n)^j*(1+i)/2),
|
101
|
+
r[n-j] = Re((a[n-j] - i*a[j]) * W(4*n)^j*(1+i)/2),
|
102
|
+
0<j<=n/2
|
103
|
+
and calls "rdft" of length n :
|
104
|
+
A[k] = sum_j=0^n-1 r[j]*W(n)^(j*k), 0<=k<=n/2,
|
105
|
+
W(n) = exp(2*pi*i/n).
|
106
|
+
The result S[k] are :
|
107
|
+
S[2*k] = Re(A[k] * (1+i)),
|
108
|
+
S[2*k-1] = -Im(A[k] * (1+i)).
|
109
|
+
-------- dfct --------
|
110
|
+
A method to split into "dfct" and "ddct" of half length.
|
111
|
+
The transform :
|
112
|
+
C[k] = sum_j=0^n a[j]*cos(pi*j*k/n), 0<=k<=n
|
113
|
+
is divided into :
|
114
|
+
C[2*k] = sum'_j=0^n/2 (a[j]+a[n-j])*cos(pi*j*k/(n/2)),
|
115
|
+
C[2*k+1] = sum_j=0^n/2-1 (a[j]-a[n-j])*cos(pi*j*(k+1/2)/(n/2))
|
116
|
+
(sum' is a summation whose last term multiplies 1/2).
|
117
|
+
This routine uses "ddct" recursively.
|
118
|
+
To keep the in-place operation, the data in fft*g_h.*
|
119
|
+
are sorted in bit reversal order.
|
120
|
+
-------- dfst --------
|
121
|
+
A method to split into "dfst" and "ddst" of half length.
|
122
|
+
The transform :
|
123
|
+
S[k] = sum_j=1^n-1 a[j]*sin(pi*j*k/n), 0<k<n
|
124
|
+
is divided into :
|
125
|
+
S[2*k] = sum_j=1^n/2-1 (a[j]-a[n-j])*sin(pi*j*k/(n/2)),
|
126
|
+
S[2*k+1] = sum'_j=1^n/2 (a[j]+a[n-j])*sin(pi*j*(k+1/2)/(n/2))
|
127
|
+
(sum' is a summation whose last term multiplies 1/2).
|
128
|
+
This routine uses "ddst" recursively.
|
129
|
+
To keep the in-place operation, the data in fft*g_h.*
|
130
|
+
are sorted in bit reversal order.
|
131
|
+
|
132
|
+
Reference:
|
133
|
+
* Masatake MORI, Makoto NATORI, Tatuo TORII: Suchikeisan,
|
134
|
+
Iwanamikouzajyouhoukagaku18, Iwanami, 1982 (Japanese)
|
135
|
+
* Henri J. Nussbaumer: Fast Fourier Transform and Convolution
|
136
|
+
Algorithms, Springer Verlag, 1982
|
137
|
+
* C. S. Burrus, Notes on the FFT (with large FFT paper list)
|
138
|
+
http://www-dsp.rice.edu/research/fft/fftnote.asc
|
139
|
+
|
140
|
+
Copyright:
|
141
|
+
Copyright(C) 1996-2001 Takuya OOURA
|
142
|
+
email: ooura@mmm.t.u-tokyo.ac.jp
|
143
|
+
download: http://momonga.t.u-tokyo.ac.jp/~ooura/fft.html
|
144
|
+
You may use, copy, modify this code for any purpose and
|
145
|
+
without fee. You may distribute this ORIGINAL package.
|
146
|
+
|
147
|
+
History:
|
148
|
+
...
|
149
|
+
Dec. 1995 : Edit the General Purpose FFT
|
150
|
+
Mar. 1996 : Change the specification
|
151
|
+
Jun. 1996 : Change the method of trigonometric function table
|
152
|
+
Sep. 1996 : Modify the documents
|
153
|
+
Feb. 1997 : Change the butterfly loops
|
154
|
+
Dec. 1997 : Modify the documents
|
155
|
+
Dec. 1997 : Add "fft4g.*"
|
156
|
+
Jul. 1998 : Fix some bugs in the documents
|
157
|
+
Jul. 1998 : Add "fft8g.*" and delete "fft4f.*"
|
158
|
+
Jul. 1998 : Add a benchmark program "pi_fft.c"
|
159
|
+
Jul. 1999 : Add a simple version "fft*g_h.c"
|
160
|
+
Jul. 1999 : Add a Split-Radix FFT package "fftsg*.c"
|
161
|
+
Sep. 1999 : Reduce the memory operation (minor optimization)
|
162
|
+
Oct. 1999 : Change the butterfly structure of "fftsg*.c"
|
163
|
+
Oct. 1999 : Save the code size
|
164
|
+
Sep. 2001 : Add "fftsg.f"
|
165
|
+
Sep. 2001 : Add Pthread & Win32thread routines to "fftsg*.c"
|
166
|
+
Dec. 2006 : Fix a minor bug in "fftsg.f"
|
167
|
+
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'mkmf'
|
3
|
+
|
4
|
+
have_header('windows.h')
|
5
|
+
have_header('pthread.h')
|
6
|
+
|
7
|
+
have_func('pthread_create', 'pthread.h')
|
8
|
+
have_func('pthread_join', 'pthread.h')
|
9
|
+
have_func('CreateThread', 'windows.h')
|
10
|
+
have_func('WaitForSingleObject', 'windows.h')
|
11
|
+
have_func('CloseHandle', 'windows.h')
|
12
|
+
|
13
|
+
have_header('stdbit.h')
|
14
|
+
have_func('ispow2l', 'stdbit.h')
|
15
|
+
|
16
|
+
$INSTALLFILES = Dir.glob(%w[ooura_fft/*.h]).map{|x| [x,'$(archdir)'] }
|
17
|
+
|
18
|
+
create_makefile('ooura_fft/ooura_fft')
|