ruby-fftw3 0.4.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.0.0
data/README.rd DELETED
File without changes
@@ -1,116 +0,0 @@
1
- <?xml version="1.0" ?>
2
- <!DOCTYPE html
3
- PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
- <html xmlns="http://www.w3.org/1999/xhtml">
6
- <head>
7
- <title>ruby-fftw3.rd</title>
8
- </head>
9
- <body>
10
- <h1><a name="label-0" id="label-0">module NumRu::FFTW3</a></h1><!-- RDLabel: "module NumRu::FFTW3" -->
11
- <p>Fast Fourier Transforms by using <a href="http://www.fftw.org">FFTW</a> Ver.3.</p>
12
- <p>Takeshi Horinouchi</p>
13
- <p>(C) Takeshi Horinouchi / GFD Dennou Club,
14
- 2003</p>
15
- <p>NO WARRANTY</p>
16
- <h2><a name="label-1" id="label-1">Features</a></h2><!-- RDLabel: "Features" -->
17
- <ul>
18
- <li>Uses <a href="http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray">NArray</a>.</li>
19
- <li>Multi-dimensional complex FFT. (Real data are coerced to complex).</li>
20
- <li>Supports both double and single float transforms.</li>
21
- <li>Not normalized as in FFTW</li>
22
- </ul>
23
- <h2><a name="label-2" id="label-2">Features yet to be introduced</a></h2><!-- RDLabel: "Features yet to be introduced" -->
24
- <ul>
25
- <li>Sine / cosine transforms</li>
26
- <li>User choice of optimization levels (i.e., FFTW_MEASURE etc in
27
- addition to FFTW_ESTIMATE).</li>
28
- <li>Multi-threaded FFT3 support -- don't know whether it's really feasible.</li>
29
- </ul>
30
- <h2><a name="label-3" id="label-3">Installation</a></h2><!-- RDLabel: "Installation" -->
31
- <ul>
32
- <li>Install <a href="http://www.fftw.org">FFTW</a> Ver.3.
33
- <ul>
34
- <li>NOTE:
35
- To activate the single-float transform, you have to install FFTW3 with
36
- the single-float compilation, in addition to the default double-float
37
- version. This can be done by configuring FFTW3 with
38
- the --enable-float option, and install it again. The single-float
39
- version will coexist with the double-float version.
40
- If you do not install the single-float version, FFT is always done
41
- with the double precision, which is not bad if you are not time- and
42
- memory-conscious.</li>
43
- </ul></li>
44
- <li>Install <a href="http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray">NArray</a>.</li>
45
- <li><p>Then, install this library as follows (replace "version" with
46
- the actual version number):</p>
47
- <pre>% tar xvzf fftw3-version.tar.gz
48
- % cd fftw3-version
49
- % ruby extconf.rb
50
- % make
51
- % make site-install</pre>
52
- <p>Or</p>
53
- <pre>% make install</pre>
54
- <p>(If you are using Ruby 1.8, make install is the same make site-install.)</p></li>
55
- </ul>
56
- <h2><a name="label-4" id="label-4">How to use</a></h2><!-- RDLabel: "How to use" -->
57
- <p>See the following peice of code. (Install this library and copy and
58
- paste the following to the interactive shell irb).</p>
59
- <pre>require "numru/fftw3"
60
- include NumRu
61
-
62
- na = NArray.float(8,6) # float -&gt; will be corced to complex
63
- na[1,1]=1
64
-
65
- # &lt;example 1&gt;
66
- fc = FFTW3.fft(na, -1)/na.length # forward 2D FFT and normalization
67
- nc = FFTW3.fft(fc, 1) # backward 2D FFT (complex) --&gt;
68
- nb = nc.real # should be equal to na except round errors
69
-
70
- # &lt;example 2&gt;
71
- fc = FFTW3.fft(na, -1, 0) / na.shape[0] # forward FFT with the first dim
72
-
73
- # &lt;example 3&gt;
74
- fc = FFTW3.fft(na, -1, 1) / na.shape[1] # forward FFT with the second dim</pre>
75
- <h2><a name="label-5" id="label-5">API Reference</a></h2><!-- RDLabel: "API Reference" -->
76
- <h3><a name="label-6" id="label-6">Module methods</a></h3><!-- RDLabel: "Module methods" -->
77
- <dl>
78
- <dt><a name="label-7" id="label-7"><code>fft(<var>narray</var>, <var>dir</var> [,<var>dim</var>,<var>dim</var>,...])</code></a></dt><!-- RDLabel: "fft" -->
79
- <dd>
80
- <p>Complex FFT.</p>
81
- <p>The 3rd, 4th,... arguments are optional.</p>
82
- <p>ARGUMENTS</p>
83
- <ul>
84
- <li>narray (NArray or NArray-compatible Array) : array to be
85
- transformed. If real, coerced to complex before transformation.
86
- If narray is single-precision and the single-precision
87
- version of FFTW3 is installed (before installing this module),
88
- this method does a single-precision transform.
89
- Otherwise, a double-precision transform is used.</li>
90
- <li>dir (-1 or 1) : forward transform if -1; backward transform if 1.</li>
91
- <li>optional 3rd, 4th,... arguments (Integer) : Specifies dimensions
92
- to apply FFT. For example, if 0, the first dimension is
93
- transformed (1D FFT); If -1, the last dimension is used (1D FFT);
94
- If 0,2,4, the first, third, and fifth dimensions
95
- are transformed (3D FFT); If entirely omitted, ALL DIMENSIONS
96
- ARE SUBJECT TO FFT, so 3D FFT is done with a 3D array.</li>
97
- </ul>
98
- <p>RETURN VALUE</p>
99
- <ul>
100
- <li>a complex NArray</li>
101
- </ul>
102
- <p>NOTE</p>
103
- <ul>
104
- <li>As in FFTW, return value is NOT normalized. Thus, a consecutive
105
- forward and backward transform would multiply the size of
106
- data used for transform. You can normalize, for example,
107
- the forward transform FFTW.fft(narray, -1, 0, 1)
108
- (FFT regarding the first (dim 0) &amp; second (dim 1) dimensions) by
109
- dividing with (narray.shape[0]*narray.shape[1]). Likewise,
110
- the result of FFTW.fft(narray, -1) (FFT for all dimensions)
111
- can be normalized by narray.length.</li>
112
- </ul></dd>
113
- </dl>
114
-
115
- </body>
116
- </html>
@@ -1,115 +0,0 @@
1
- =module NumRu::FFTW3
2
-
3
- Fast Fourier Transforms by using ((<FFTW|URL:http://www.fftw.org>)) Ver.3.
4
-
5
- Takeshi Horinouchi
6
-
7
- (C) Takeshi Horinouchi / GFD Dennou Club,
8
- 2003
9
-
10
- NO WARRANTY
11
-
12
- ==Features
13
-
14
- * Uses ((<NArray|URL:http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray>)).
15
- * Multi-dimensional complex FFT. (Real data are coerced to complex).
16
- * Supports both double and single float transforms.
17
- * Not normalized as in FFTW
18
-
19
- ==Features yet to be introduced
20
-
21
- * Sine / cosine transforms
22
- * User choice of optimization levels (i.e., FFTW_MEASURE etc in
23
- addition to FFTW_ESTIMATE).
24
- * Multi-threaded FFT3 support -- don't know whether it's really feasible.
25
-
26
- ==Installation
27
-
28
- * Install ((<FFTW|URL:http://www.fftw.org>)) Ver.3.
29
-
30
- * NOTE:
31
- To activate the single-float transform, you have to install FFTW3 with
32
- the single-float compilation, in addition to the default double-float
33
- version. This can be done by configuring FFTW3 with
34
- the --enable-float option, and install it again. The single-float
35
- version will coexist with the double-float version.
36
- If you do not install the single-float version, FFT is always done
37
- with the double precision, which is not bad if you are not time- and
38
- memory-conscious.
39
-
40
- * Install ((<NArray|URL:http://www.ruby-lang.org/en/raa-list.rhtml?name=NArray>)).
41
-
42
- * Then, install this library as follows (replace "version" with
43
- the actual version number):
44
-
45
- % tar xvzf fftw3-version.tar.gz
46
- % cd fftw3-version
47
- % ruby extconf.rb
48
- % make
49
- % make site-install
50
- Or
51
- % make install
52
- (If you are using Ruby 1.8, make install is the same make site-install.)
53
-
54
- ==How to use
55
-
56
- See the following peice of code. (Install this library and copy and
57
- paste the following to the interactive shell irb).
58
-
59
- require "numru/fftw3"
60
- include NumRu
61
-
62
- na = NArray.float(8,6) # float -> will be corced to complex
63
- na[1,1]=1
64
-
65
- # <example 1>
66
- fc = FFTW3.fft(na, -1)/na.length # forward 2D FFT and normalization
67
- nc = FFTW3.fft(fc, 1) # backward 2D FFT (complex) -->
68
- nb = nc.real # should be equal to na except round errors
69
-
70
- # <example 2>
71
- fc = FFTW3.fft(na, -1, 0) / na.shape[0] # forward FFT with the first dim
72
-
73
- # <example 3>
74
- fc = FFTW3.fft(na, -1, 1) / na.shape[1] # forward FFT with the second dim
75
-
76
- ==API Reference
77
-
78
- ===Module methods
79
-
80
- ---fft(narray, dir [,dim,dim,...])
81
-
82
- Complex FFT.
83
-
84
- The 3rd, 4th,... arguments are optional.
85
-
86
- ARGUMENTS
87
- * narray (NArray or NArray-compatible Array) : array to be
88
- transformed. If real, coerced to complex before transformation.
89
- If narray is single-precision and the single-precision
90
- version of FFTW3 is installed (before installing this module),
91
- this method does a single-precision transform.
92
- Otherwise, a double-precision transform is used.
93
- * dir (-1 or 1) : forward transform if -1; backward transform if 1.
94
- * optional 3rd, 4th,... arguments (Integer) : Specifies dimensions
95
- to apply FFT. For example, if 0, the first dimension is
96
- transformed (1D FFT); If -1, the last dimension is used (1D FFT);
97
- If 0,2,4, the first, third, and fifth dimensions
98
- are transformed (3D FFT); If entirely omitted, ALL DIMENSIONS
99
- ARE SUBJECT TO FFT, so 3D FFT is done with a 3D array.
100
-
101
- RETURN VALUE
102
- * a complex NArray
103
-
104
- NOTE
105
- * As in FFTW, return value is NOT normalized. Thus, a consecutive
106
- forward and backward transform would multiply the size of
107
- data used for transform. You can normalize, for example,
108
- the forward transform FFTW.fft(narray, -1, 0, 1)
109
- (FFT regarding the first (dim 0) & second (dim 1) dimensions) by
110
- dividing with (narray.shape[0]*narray.shape[1]). Likewise,
111
- the result of FFTW.fft(narray, -1) (FFT for all dimensions)
112
- can be normalized by narray.length.
113
-
114
-
115
-
data/na_fftw3.c DELETED
@@ -1,285 +0,0 @@
1
- /*
2
- na_fftw3.c
3
-
4
- FFT using FFTW Ver.3 (www.fftw.org)
5
-
6
- (C) Takeshi Horinouchi
7
- NO WARRANTY.
8
-
9
- */
10
-
11
- #include <ruby.h>
12
- #include "narray.h"
13
- #include <fftw3.h>
14
-
15
- VALUE rb_mFFTW3;
16
- VALUE mNumRu;
17
-
18
- static VALUE
19
- #ifdef FFTW3_HAS_SINGLE_SUPPORT
20
- na_fftw3_double(int argc, VALUE *argv, VALUE self)
21
- /* to be called by na_fftw3 */
22
- #else
23
- na_fftw3(int argc, VALUE *argv, VALUE self)
24
- /* to be called directly */
25
- #endif
26
- {
27
- VALUE val, vdir;
28
- struct NARRAY *a1, *a2;
29
- int i, dir, *shape, *bucket;
30
- fftw_plan p;
31
- fftw_complex *in, *out;
32
- volatile VALUE v1, v2;
33
-
34
- if (argc<2){
35
- rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
36
- }
37
- val = argv[0];
38
- vdir = argv[1];
39
-
40
- dir = NUM2INT(vdir);
41
- if ( dir != 1 && dir != -1 ){
42
- rb_raise(rb_eArgError, "direction should be 1 or -1");
43
- }
44
- v1 = na_cast_object(val, NA_DCOMPLEX);
45
- GetNArray(v1,a1);
46
- v2 = na_make_object( NA_DCOMPLEX, a1->rank, a1->shape, CLASS_OF(v1) );
47
- GetNArray(v2,a2);
48
-
49
- shape = ALLOCA_N(int, a2->rank);
50
- for (i=0; i<a2->rank; i++){
51
- shape[i] = a2->shape[a2->rank-1-i];
52
- }
53
- in = (fftw_complex*)a1->ptr;
54
- out = (fftw_complex*)a2->ptr;
55
-
56
- if (argc==2) {
57
- /* apply FFT to all dimensions */
58
- p = fftw_plan_dft( a2->rank, shape,
59
- in, out, dir, FFTW_ESTIMATE );
60
- } else {
61
- /* apply FFT to selected dimensions (by using the Guru interface) */
62
- { /* introduce a new scope for additonal local variables */
63
- int fft_rank, howmany_rank, ib, j, jf, je, dim;
64
- fftw_iodim *fft_dims, *howmany_dims;
65
- int *dimids;
66
- fft_rank = argc - 2;
67
- fft_dims = ALLOCA_N(fftw_iodim, fft_rank);
68
- dimids = ALLOCA_N(int, fft_rank);
69
- howmany_rank = fft_rank + 1;
70
- howmany_dims = ALLOCA_N(fftw_iodim, howmany_rank);
71
-
72
- for (i=2;i<argc;i++){
73
- dim = NUM2INT(argv[i]);
74
- if (dim<0) dim += a2->rank; /* negative: count from the end */
75
- if (dim<0 || dim>=a2->rank){
76
- rb_raise(rb_eArgError, "dimension < 0 or >= rank");
77
- }
78
- dimids[i-2] = a2->rank - 1 - dim;
79
- if ( i>2 && dimids[i-2] == dimids[i-3] ){
80
- rb_raise(rb_eArgError, "redundant -- a same dimension is reppeated");
81
- }
82
- }
83
-
84
- /* bukcet sort in increasing order */
85
- bucket = ALLOCA_N(int,a2->rank);
86
- for(j=0; j<a2->rank; j++) bucket[j] = 0; /* initialize */
87
- for(i=0; i<fft_rank; i++) bucket[ dimids[i] ] = 1;
88
- for(j=0,i=0; j<a2->rank; j++) {
89
- if (bucket[j]==1){
90
- dimids[i] = j;
91
- i++;
92
- }
93
- }
94
-
95
- for(j=0; j<fft_rank; j++){
96
- fft_dims[j].n = shape[ dimids[j] ];
97
- fft_dims[j].is = 1;
98
- for (i=dimids[j]+1 ; i<a2->rank ; i++){
99
- fft_dims[j].is *= shape[i];
100
- }
101
- fft_dims[j].os = fft_dims[j].is;
102
- /* printf("fft_ %d n:%d is:%d\n",j,
103
- fft_dims[j].n,fft_dims[j].is);*/
104
- }
105
- for(j=0; j<=fft_rank; j++){
106
- howmany_dims[j].n = 1;
107
- jf = (j==0) ? 0 : (dimids[j-1]+1) ;
108
- je = (j==fft_rank) ? a2->rank : (dimids[j]) ;
109
- for (i=jf; i<je; i++){
110
- howmany_dims[j].n *= shape[i];
111
- }
112
- howmany_dims[j].is = 1;
113
- if (j<fft_rank){
114
- for (i=dimids[j]; i<a2->rank; i++){
115
- howmany_dims[j].is *= shape[i];
116
- }
117
- }
118
- howmany_dims[j].os = howmany_dims[j].is;
119
- /* printf("how_ %d n:%d is:%d\n",j,
120
- howmany_dims[j].n,howmany_dims[j].is); */
121
- }
122
-
123
- p = fftw_plan_guru_dft( fft_rank, fft_dims,
124
- howmany_rank, howmany_dims,
125
- in, out, dir, FFTW_ESTIMATE );
126
-
127
- }
128
- }
129
-
130
- fftw_execute(p);
131
- fftw_destroy_plan(p);
132
-
133
- return v2;
134
- }
135
-
136
- #ifdef FFTW3_HAS_SINGLE_SUPPORT
137
-
138
- /* sourse code generation of na_fftw3_float:
139
- Copy na_fftw3_double, and replace
140
- fftw --> fftwf
141
- DCOMPLEX --> SCOMPLEX
142
- */
143
- static VALUE
144
- na_fftw3_float(int argc, VALUE *argv, VALUE self)
145
- {
146
- VALUE val, vdir;
147
- struct NARRAY *a1, *a2;
148
- int i, dir, *shape, *bucket;
149
- fftwf_plan p;
150
- fftwf_complex *in, *out;
151
- volatile VALUE v1, v2;
152
-
153
- if (argc<2){
154
- rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
155
- }
156
- val = argv[0];
157
- vdir = argv[1];
158
-
159
- dir = NUM2INT(vdir);
160
- if ( dir != 1 && dir != -1 ){
161
- rb_raise(rb_eArgError, "direction should be 1 or -1");
162
- }
163
- v1 = na_cast_object(val, NA_SCOMPLEX);
164
- GetNArray(v1,a1);
165
- v2 = na_make_object( NA_SCOMPLEX, a1->rank, a1->shape, CLASS_OF(v1) );
166
- GetNArray(v2,a2);
167
-
168
- shape = ALLOCA_N(int, a2->rank);
169
- for (i=0; i<a2->rank; i++){
170
- shape[i] = a2->shape[a2->rank-1-i];
171
- }
172
- in = (fftwf_complex*)a1->ptr;
173
- out = (fftwf_complex*)a2->ptr;
174
-
175
- if (argc==2) {
176
- /* apply FFT to all dimensions */
177
- p = fftwf_plan_dft( a2->rank, shape,
178
- in, out, dir, FFTW_ESTIMATE );
179
- } else {
180
- /* apply FFT to selected dimensions (by using the Guru interface) */
181
- { /* introduce a new scope for additonal local variables */
182
- int fft_rank, howmany_rank, ib, j, jf, je, dim;
183
- fftw_iodim *fft_dims, *howmany_dims;
184
- int *dimids;
185
- fft_rank = argc - 2;
186
- fft_dims = ALLOCA_N(fftw_iodim, fft_rank);
187
- dimids = ALLOCA_N(int, fft_rank);
188
- howmany_rank = fft_rank + 1;
189
- howmany_dims = ALLOCA_N(fftw_iodim, howmany_rank);
190
-
191
- for (i=2;i<argc;i++){
192
- dim = NUM2INT(argv[i]);
193
- if (dim<0) dim += a2->rank; /* negative: count from the end */
194
- if (dim<0 || dim>=a2->rank){
195
- rb_raise(rb_eArgError, "dimension < 0 or >= rank");
196
- }
197
- dimids[i-2] = a2->rank - 1 - dim;
198
- if ( i>2 && dimids[i-2] == dimids[i-3] ){
199
- rb_raise(rb_eArgError, "redundant -- a same dimension is reppeated");
200
- }
201
- }
202
-
203
- /* bukcet sort in increasing order */
204
- bucket = ALLOCA_N(int,a2->rank);
205
- for(j=0; j<a2->rank; j++) bucket[j] = 0; /* initialize */
206
- for(i=0; i<fft_rank; i++) bucket[ dimids[i] ] = 1;
207
- for(j=0,i=0; j<a2->rank; j++) {
208
- if (bucket[j]==1){
209
- dimids[i] = j;
210
- i++;
211
- }
212
- }
213
-
214
- for(j=0; j<fft_rank; j++){
215
- fft_dims[j].n = shape[ dimids[j] ];
216
- fft_dims[j].is = 1;
217
- for (i=dimids[j]+1 ; i<a2->rank ; i++){
218
- fft_dims[j].is *= shape[i];
219
- }
220
- fft_dims[j].os = fft_dims[j].is;
221
- /* printf("fft_ %d n:%d is:%d\n",j,
222
- fft_dims[j].n,fft_dims[j].is);*/
223
- }
224
- for(j=0; j<=fft_rank; j++){
225
- howmany_dims[j].n = 1;
226
- jf = (j==0) ? 0 : (dimids[j-1]+1) ;
227
- je = (j==fft_rank) ? a2->rank : (dimids[j]) ;
228
- for (i=jf; i<je; i++){
229
- howmany_dims[j].n *= shape[i];
230
- }
231
- howmany_dims[j].is = 1;
232
- if (j<fft_rank){
233
- for (i=dimids[j]; i<a2->rank; i++){
234
- howmany_dims[j].is *= shape[i];
235
- }
236
- }
237
- howmany_dims[j].os = howmany_dims[j].is;
238
- /* printf("how_ %d n:%d is:%d\n",j,
239
- howmany_dims[j].n,howmany_dims[j].is); */
240
- }
241
-
242
- p = fftwf_plan_guru_dft( fft_rank, fft_dims,
243
- howmany_rank, howmany_dims,
244
- in, out, dir, FFTW_ESTIMATE );
245
-
246
- }
247
- }
248
-
249
- fftwf_execute(p);
250
- fftwf_destroy_plan(p);
251
-
252
- return v2;
253
- }
254
-
255
- static VALUE
256
- na_fftw3(int argc, VALUE *argv, VALUE self)
257
- {
258
- VALUE val;
259
- volatile VALUE v1;
260
- struct NARRAY *a1;
261
-
262
- if (argc<2){
263
- rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
264
- }
265
- val = argv[0];
266
- v1 = na_to_narray(val);
267
- GetNArray(v1,a1);
268
- if(a1->type <= NA_SFLOAT || a1->type == NA_SCOMPLEX ){
269
- return( na_fftw3_float(argc, argv, self) );
270
- } else {
271
- return( na_fftw3_double(argc, argv, self) );
272
- }
273
-
274
- }
275
-
276
- #endif
277
-
278
- void
279
- Init_fftw3()
280
- {
281
- rb_require("narray");
282
- mNumRu = rb_define_module("NumRu");
283
- rb_mFFTW3 = rb_define_module_under(mNumRu, "FFTW3");
284
- rb_define_module_function(rb_mFFTW3, "fft", na_fftw3, -1);
285
- }