ooura_fft 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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')
|