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.
@@ -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')