fftw3 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/ChangeLog +11 -0
- data/Manifest +9 -0
- data/README +116 -0
- data/Rakefile +10 -0
- data/ToDo +4 -0
- data/ext/extconf.rb +44 -0
- data/ext/na_fftw3.c +282 -0
- data/fftw3.gemspec +37 -0
- data/lib/fftw3.rb +7 -0
- data/test/test_fftw3.rb +37 -0
- metadata +103 -0
- metadata.gz.sig +1 -0
data.tar.gz.sig
ADDED
Binary file
|
data/ChangeLog
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Mon Jun 7 2004 T Horinouchi < T Koshiro
|
2
|
+
* version 0.2 released (cvs tag ruby-fftw3-0_2)
|
3
|
+
* extconf.rb: improved
|
4
|
+
Mon Jun 7 2004 T Horinouchi
|
5
|
+
* renamed to ruby-fftw. Started a new cvs module ruby-fftw3.
|
6
|
+
Fri Nov 20 2003 T Horinouchi
|
7
|
+
* version 0.1 released
|
8
|
+
Thu Nov 20 2003 T Horinouchi
|
9
|
+
* na_fftw3.c: debug of na_fftw3_float
|
10
|
+
Tue Nov 18 2003 T Horinouchi
|
11
|
+
* created. version 0.0
|
data/Manifest
ADDED
data/README
ADDED
@@ -0,0 +1,116 @@
|
|
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 "narray"
|
60
|
+
require "numru/fftw3"
|
61
|
+
include NumRu
|
62
|
+
|
63
|
+
na = NArray.float(8,6) # float -> will be corced to complex
|
64
|
+
na[1,1]=1
|
65
|
+
|
66
|
+
# <example 1>
|
67
|
+
fc = FFTW3.fft(na, -1)/na.length # forward 2D FFT and normalization
|
68
|
+
nc = FFTW3.fft(fc, 1) # backward 2D FFT (complex) -->
|
69
|
+
nb = nc.real # should be equal to na except round errors
|
70
|
+
|
71
|
+
# <example 2>
|
72
|
+
fc = FFTW3.fft(na, -1, 0) / na.shape[0] # forward FFT with the first dim
|
73
|
+
|
74
|
+
# <example 3>
|
75
|
+
fc = FFTW3.fft(na, -1, 1) / na.shape[1] # forward FFT with the second dim
|
76
|
+
|
77
|
+
==API Reference
|
78
|
+
|
79
|
+
===Module methods
|
80
|
+
|
81
|
+
---fft(narray, dir [,dim,dim,...])
|
82
|
+
|
83
|
+
Complex FFT.
|
84
|
+
|
85
|
+
The 3rd, 4th,... arguments are optional.
|
86
|
+
|
87
|
+
ARGUMENTS
|
88
|
+
* narray (NArray or NArray-compatible Array) : array to be
|
89
|
+
transformed. If real, coerced to complex before transformation.
|
90
|
+
If narray is single-precision and the single-precision
|
91
|
+
version of FFTW3 is installed (before installing this module),
|
92
|
+
this method does a single-precision transform.
|
93
|
+
Otherwise, a double-precision transform is used.
|
94
|
+
* dir (-1 or 1) : forward transform if -1; backward transform if 1.
|
95
|
+
* optional 3rd, 4th,... arguments (Integer) : Specifies dimensions
|
96
|
+
to apply FFT. For example, if 0, the first dimension is
|
97
|
+
transformed (1D FFT); If -1, the last dimension is used (1D FFT);
|
98
|
+
If 0,2,4, the first, third, and fifth dimensions
|
99
|
+
are transformed (3D FFT); If entirely omitted, ALL DIMENSIONS
|
100
|
+
ARE SUBJECT TO FFT, so 3D FFT is done with a 3D array.
|
101
|
+
|
102
|
+
RETURN VALUE
|
103
|
+
* a complex NArray
|
104
|
+
|
105
|
+
NOTE
|
106
|
+
* As in FFTW, return value is NOT normalized. Thus, a consecutive
|
107
|
+
forward and backward transform would multiply the size of
|
108
|
+
data used for transform. You can normalize, for example,
|
109
|
+
the forward transform FFTW.fft(narray, -1, 0, 1)
|
110
|
+
(FFT regarding the first (dim 0) & second (dim 1) dimensions) by
|
111
|
+
dividing with (narray.shape[0]*narray.shape[1]). Likewise,
|
112
|
+
the result of FFTW.fft(narray, -1) (FFT for all dimensions)
|
113
|
+
can be normalized by narray.length.
|
114
|
+
|
115
|
+
|
116
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'echoe'
|
2
|
+
|
3
|
+
Echoe.new("fftw3", "0.2") do |p|
|
4
|
+
p.author = "T. Horinouchi, Evan Weaver"
|
5
|
+
p.project = "fauna"
|
6
|
+
p.dependencies = ["narray"]
|
7
|
+
p.summary = "Gem version of T. Horinouchi's ruby-fftw3."
|
8
|
+
p.url = "http://blog.evanweaver.com/files/doc/fauna/ruby-fftw3/"
|
9
|
+
p.docs_host = "blog.evanweaver.com:~/www/bax/public/files/doc/"
|
10
|
+
end
|
data/ToDo
ADDED
data/ext/extconf.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require "mkmf"
|
2
|
+
require "rubygems"
|
3
|
+
|
4
|
+
narray_dir = File.dirname(Gem.find_files("narray.h").first) rescue $sitearchdir
|
5
|
+
dir_config('narray', narray_dir, narray_dir)
|
6
|
+
dir_config('fftw3','/usr/local')
|
7
|
+
|
8
|
+
if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then
|
9
|
+
print <<-EOS
|
10
|
+
** configure error **
|
11
|
+
Header narray.h or narray_config.h is not found. If you have these files in
|
12
|
+
/narraydir/include, try the following:
|
13
|
+
|
14
|
+
% ruby extconf.rb --with-narray-include=/narraydir/include
|
15
|
+
|
16
|
+
EOS
|
17
|
+
exit(-1)
|
18
|
+
end
|
19
|
+
|
20
|
+
if ( ! ( have_header("fftw3.h") && have_library("fftw3") ) ) then
|
21
|
+
print <<EOS
|
22
|
+
** configure error **
|
23
|
+
Header fftw3.h or the compiled fftw3 library is not found.
|
24
|
+
If you have the library installed under /fftw3dir (that is, fftw3.h is
|
25
|
+
in /fftw3dir/include and the library in /fftw3dir/lib/),
|
26
|
+
try the following:
|
27
|
+
|
28
|
+
% ruby extconf.rb --with-fftw3-dir=/fftw3dir
|
29
|
+
|
30
|
+
Alternatively, you can specify the two directory separately
|
31
|
+
with --with-fftw3-include and --with-fftw3-lib.
|
32
|
+
EOS
|
33
|
+
exit(-1)
|
34
|
+
end
|
35
|
+
|
36
|
+
if have_library("fftw3f")
|
37
|
+
$CFLAGS += ' -DFFTW3_HAS_SINGLE_SUPPORT'
|
38
|
+
end
|
39
|
+
|
40
|
+
if /cygwin|mingw/ =~ RUBY_PLATFORM
|
41
|
+
have_library("narray") || raise("ERROR: narray library is not found")
|
42
|
+
end
|
43
|
+
|
44
|
+
create_makefile("fftw3/fftw3")
|
data/ext/na_fftw3.c
ADDED
@@ -0,0 +1,282 @@
|
|
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 mFFTW3;
|
16
|
+
|
17
|
+
static VALUE
|
18
|
+
#ifdef FFTW3_HAS_SINGLE_SUPPORT
|
19
|
+
na_fftw3_double(int argc, VALUE *argv, VALUE self)
|
20
|
+
/* to be called by na_fftw3 */
|
21
|
+
#else
|
22
|
+
na_fftw3(int argc, VALUE *argv, VALUE self)
|
23
|
+
/* to be called directly */
|
24
|
+
#endif
|
25
|
+
{
|
26
|
+
VALUE val, vdir;
|
27
|
+
struct NARRAY *a1, *a2;
|
28
|
+
int i, dir, *shape, *bucket;
|
29
|
+
fftw_plan p;
|
30
|
+
fftw_complex *in, *out;
|
31
|
+
volatile VALUE v1, v2;
|
32
|
+
|
33
|
+
if (argc<2){
|
34
|
+
rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
|
35
|
+
}
|
36
|
+
val = argv[0];
|
37
|
+
vdir = argv[1];
|
38
|
+
|
39
|
+
dir = NUM2INT(vdir);
|
40
|
+
if ( dir != 1 && dir != -1 ){
|
41
|
+
rb_raise(rb_eArgError, "direction should be 1 or -1");
|
42
|
+
}
|
43
|
+
v1 = na_cast_object(val, NA_DCOMPLEX);
|
44
|
+
GetNArray(v1,a1);
|
45
|
+
v2 = na_make_object( NA_DCOMPLEX, a1->rank, a1->shape, CLASS_OF(v1) );
|
46
|
+
GetNArray(v2,a2);
|
47
|
+
|
48
|
+
shape = ALLOCA_N(int, a2->rank);
|
49
|
+
for (i=0; i<a2->rank; i++){
|
50
|
+
shape[i] = a2->shape[a2->rank-1-i];
|
51
|
+
}
|
52
|
+
in = (fftw_complex*)a1->ptr;
|
53
|
+
out = (fftw_complex*)a2->ptr;
|
54
|
+
|
55
|
+
if (argc==2) {
|
56
|
+
/* apply FFT to all dimensions */
|
57
|
+
p = fftw_plan_dft( a2->rank, shape,
|
58
|
+
in, out, dir, FFTW_ESTIMATE );
|
59
|
+
} else {
|
60
|
+
/* apply FFT to selected dimensions (by using the Guru interface) */
|
61
|
+
{ /* introduce a new scope for additonal local variables */
|
62
|
+
int fft_rank, howmany_rank, ib, j, jf, je, dim;
|
63
|
+
fftw_iodim *fft_dims, *howmany_dims;
|
64
|
+
int *dimids;
|
65
|
+
fft_rank = argc - 2;
|
66
|
+
fft_dims = ALLOCA_N(fftw_iodim, fft_rank);
|
67
|
+
dimids = ALLOCA_N(int, fft_rank);
|
68
|
+
howmany_rank = fft_rank + 1;
|
69
|
+
howmany_dims = ALLOCA_N(fftw_iodim, howmany_rank);
|
70
|
+
|
71
|
+
for (i=2;i<argc;i++){
|
72
|
+
dim = NUM2INT(argv[i]);
|
73
|
+
if (dim<0) dim += a2->rank; /* negative: count from the end */
|
74
|
+
if (dim<0 || dim>=a2->rank){
|
75
|
+
rb_raise(rb_eArgError, "dimension < 0 or >= rank");
|
76
|
+
}
|
77
|
+
dimids[i-2] = a2->rank - 1 - dim;
|
78
|
+
if ( i>2 && dimids[i-2] == dimids[i-3] ){
|
79
|
+
rb_raise(rb_eArgError, "redundant -- a same dimension is reppeated");
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
/* bukcet sort in increasing order */
|
84
|
+
bucket = ALLOCA_N(int,a2->rank);
|
85
|
+
for(j=0; j<a2->rank; j++) bucket[j] = 0; /* initialize */
|
86
|
+
for(i=0; i<fft_rank; i++) bucket[ dimids[i] ] = 1;
|
87
|
+
for(j=0,i=0; j<a2->rank; j++) {
|
88
|
+
if (bucket[j]==1){
|
89
|
+
dimids[i] = j;
|
90
|
+
i++;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
for(j=0; j<fft_rank; j++){
|
95
|
+
fft_dims[j].n = shape[ dimids[j] ];
|
96
|
+
fft_dims[j].is = 1;
|
97
|
+
for (i=dimids[j]+1 ; i<a2->rank ; i++){
|
98
|
+
fft_dims[j].is *= shape[i];
|
99
|
+
}
|
100
|
+
fft_dims[j].os = fft_dims[j].is;
|
101
|
+
/* printf("fft_ %d n:%d is:%d\n",j,
|
102
|
+
fft_dims[j].n,fft_dims[j].is);*/
|
103
|
+
}
|
104
|
+
for(j=0; j<=fft_rank; j++){
|
105
|
+
howmany_dims[j].n = 1;
|
106
|
+
jf = (j==0) ? 0 : (dimids[j-1]+1) ;
|
107
|
+
je = (j==fft_rank) ? a2->rank : (dimids[j]) ;
|
108
|
+
for (i=jf; i<je; i++){
|
109
|
+
howmany_dims[j].n *= shape[i];
|
110
|
+
}
|
111
|
+
howmany_dims[j].is = 1;
|
112
|
+
if (j<fft_rank){
|
113
|
+
for (i=dimids[j]; i<a2->rank; i++){
|
114
|
+
howmany_dims[j].is *= shape[i];
|
115
|
+
}
|
116
|
+
}
|
117
|
+
howmany_dims[j].os = howmany_dims[j].is;
|
118
|
+
/* printf("how_ %d n:%d is:%d\n",j,
|
119
|
+
howmany_dims[j].n,howmany_dims[j].is); */
|
120
|
+
}
|
121
|
+
|
122
|
+
p = fftw_plan_guru_dft( fft_rank, fft_dims,
|
123
|
+
howmany_rank, howmany_dims,
|
124
|
+
in, out, dir, FFTW_ESTIMATE );
|
125
|
+
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
fftw_execute(p);
|
130
|
+
fftw_destroy_plan(p);
|
131
|
+
|
132
|
+
return v2;
|
133
|
+
}
|
134
|
+
|
135
|
+
#ifdef FFTW3_HAS_SINGLE_SUPPORT
|
136
|
+
|
137
|
+
/* sourse code generation of na_fftw3_float:
|
138
|
+
Copy na_fftw3_double, and replace
|
139
|
+
fftw --> fftwf
|
140
|
+
DCOMPLEX --> SCOMPLEX
|
141
|
+
*/
|
142
|
+
static VALUE
|
143
|
+
na_fftw3_float(int argc, VALUE *argv, VALUE self)
|
144
|
+
{
|
145
|
+
VALUE val, vdir;
|
146
|
+
struct NARRAY *a1, *a2;
|
147
|
+
int i, dir, *shape, *bucket;
|
148
|
+
fftwf_plan p;
|
149
|
+
fftwf_complex *in, *out;
|
150
|
+
volatile VALUE v1, v2;
|
151
|
+
|
152
|
+
if (argc<2){
|
153
|
+
rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
|
154
|
+
}
|
155
|
+
val = argv[0];
|
156
|
+
vdir = argv[1];
|
157
|
+
|
158
|
+
dir = NUM2INT(vdir);
|
159
|
+
if ( dir != 1 && dir != -1 ){
|
160
|
+
rb_raise(rb_eArgError, "direction should be 1 or -1");
|
161
|
+
}
|
162
|
+
v1 = na_cast_object(val, NA_SCOMPLEX);
|
163
|
+
GetNArray(v1,a1);
|
164
|
+
v2 = na_make_object( NA_SCOMPLEX, a1->rank, a1->shape, CLASS_OF(v1) );
|
165
|
+
GetNArray(v2,a2);
|
166
|
+
|
167
|
+
shape = ALLOCA_N(int, a2->rank);
|
168
|
+
for (i=0; i<a2->rank; i++){
|
169
|
+
shape[i] = a2->shape[a2->rank-1-i];
|
170
|
+
}
|
171
|
+
in = (fftwf_complex*)a1->ptr;
|
172
|
+
out = (fftwf_complex*)a2->ptr;
|
173
|
+
|
174
|
+
if (argc==2) {
|
175
|
+
/* apply FFT to all dimensions */
|
176
|
+
p = fftwf_plan_dft( a2->rank, shape,
|
177
|
+
in, out, dir, FFTW_ESTIMATE );
|
178
|
+
} else {
|
179
|
+
/* apply FFT to selected dimensions (by using the Guru interface) */
|
180
|
+
{ /* introduce a new scope for additonal local variables */
|
181
|
+
int fft_rank, howmany_rank, ib, j, jf, je, dim;
|
182
|
+
fftw_iodim *fft_dims, *howmany_dims;
|
183
|
+
int *dimids;
|
184
|
+
fft_rank = argc - 2;
|
185
|
+
fft_dims = ALLOCA_N(fftw_iodim, fft_rank);
|
186
|
+
dimids = ALLOCA_N(int, fft_rank);
|
187
|
+
howmany_rank = fft_rank + 1;
|
188
|
+
howmany_dims = ALLOCA_N(fftw_iodim, howmany_rank);
|
189
|
+
|
190
|
+
for (i=2;i<argc;i++){
|
191
|
+
dim = NUM2INT(argv[i]);
|
192
|
+
if (dim<0) dim += a2->rank; /* negative: count from the end */
|
193
|
+
if (dim<0 || dim>=a2->rank){
|
194
|
+
rb_raise(rb_eArgError, "dimension < 0 or >= rank");
|
195
|
+
}
|
196
|
+
dimids[i-2] = a2->rank - 1 - dim;
|
197
|
+
if ( i>2 && dimids[i-2] == dimids[i-3] ){
|
198
|
+
rb_raise(rb_eArgError, "redundant -- a same dimension is reppeated");
|
199
|
+
}
|
200
|
+
}
|
201
|
+
|
202
|
+
/* bukcet sort in increasing order */
|
203
|
+
bucket = ALLOCA_N(int,a2->rank);
|
204
|
+
for(j=0; j<a2->rank; j++) bucket[j] = 0; /* initialize */
|
205
|
+
for(i=0; i<fft_rank; i++) bucket[ dimids[i] ] = 1;
|
206
|
+
for(j=0,i=0; j<a2->rank; j++) {
|
207
|
+
if (bucket[j]==1){
|
208
|
+
dimids[i] = j;
|
209
|
+
i++;
|
210
|
+
}
|
211
|
+
}
|
212
|
+
|
213
|
+
for(j=0; j<fft_rank; j++){
|
214
|
+
fft_dims[j].n = shape[ dimids[j] ];
|
215
|
+
fft_dims[j].is = 1;
|
216
|
+
for (i=dimids[j]+1 ; i<a2->rank ; i++){
|
217
|
+
fft_dims[j].is *= shape[i];
|
218
|
+
}
|
219
|
+
fft_dims[j].os = fft_dims[j].is;
|
220
|
+
/* printf("fft_ %d n:%d is:%d\n",j,
|
221
|
+
fft_dims[j].n,fft_dims[j].is);*/
|
222
|
+
}
|
223
|
+
for(j=0; j<=fft_rank; j++){
|
224
|
+
howmany_dims[j].n = 1;
|
225
|
+
jf = (j==0) ? 0 : (dimids[j-1]+1) ;
|
226
|
+
je = (j==fft_rank) ? a2->rank : (dimids[j]) ;
|
227
|
+
for (i=jf; i<je; i++){
|
228
|
+
howmany_dims[j].n *= shape[i];
|
229
|
+
}
|
230
|
+
howmany_dims[j].is = 1;
|
231
|
+
if (j<fft_rank){
|
232
|
+
for (i=dimids[j]; i<a2->rank; i++){
|
233
|
+
howmany_dims[j].is *= shape[i];
|
234
|
+
}
|
235
|
+
}
|
236
|
+
howmany_dims[j].os = howmany_dims[j].is;
|
237
|
+
/* printf("how_ %d n:%d is:%d\n",j,
|
238
|
+
howmany_dims[j].n,howmany_dims[j].is); */
|
239
|
+
}
|
240
|
+
|
241
|
+
p = fftwf_plan_guru_dft( fft_rank, fft_dims,
|
242
|
+
howmany_rank, howmany_dims,
|
243
|
+
in, out, dir, FFTW_ESTIMATE );
|
244
|
+
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
fftwf_execute(p);
|
249
|
+
fftwf_destroy_plan(p);
|
250
|
+
|
251
|
+
return v2;
|
252
|
+
}
|
253
|
+
|
254
|
+
static VALUE
|
255
|
+
na_fftw3(int argc, VALUE *argv, VALUE self)
|
256
|
+
{
|
257
|
+
VALUE val;
|
258
|
+
volatile VALUE v1;
|
259
|
+
struct NARRAY *a1;
|
260
|
+
|
261
|
+
if (argc<2){
|
262
|
+
rb_raise(rb_eArgError, "Usage: fftw(narray, direction [,dim0,dim1,...])");
|
263
|
+
}
|
264
|
+
val = argv[0];
|
265
|
+
v1 = na_to_narray(val);
|
266
|
+
GetNArray(v1,a1);
|
267
|
+
if(a1->type <= NA_SFLOAT || a1->type == NA_SCOMPLEX ){
|
268
|
+
return( na_fftw3_float(argc, argv, self) );
|
269
|
+
} else {
|
270
|
+
return( na_fftw3_double(argc, argv, self) );
|
271
|
+
}
|
272
|
+
|
273
|
+
}
|
274
|
+
|
275
|
+
#endif
|
276
|
+
|
277
|
+
void
|
278
|
+
Init_fftw3()
|
279
|
+
{
|
280
|
+
mFFTW3 = rb_define_module("FFTW3");
|
281
|
+
rb_define_module_function(mFFTW3, "fft", na_fftw3, -1);
|
282
|
+
}
|
data/fftw3.gemspec
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{fftw3}
|
5
|
+
s.version = "0.2"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["T. Horinouchi, Evan Weaver"]
|
9
|
+
s.cert_chain = ["/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-public_cert.pem"]
|
10
|
+
s.date = %q{2009-10-15}
|
11
|
+
s.description = %q{Gem version of T. Horinouchi's ruby-fftw3.}
|
12
|
+
s.email = %q{}
|
13
|
+
s.extensions = ["ext/extconf.rb"]
|
14
|
+
s.extra_rdoc_files = ["README", "ext/extconf.rb", "ext/na_fftw3.c", "lib/fftw3.rb"]
|
15
|
+
s.files = ["ChangeLog", "Manifest", "README", "Rakefile", "ToDo", "ext/extconf.rb", "ext/na_fftw3.c", "lib/fftw3.rb", "test/test_fftw3.rb", "fftw3.gemspec"]
|
16
|
+
s.homepage = %q{http://blog.evanweaver.com/files/doc/fauna/ruby-fftw3/}
|
17
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Fftw3", "--main", "README"]
|
18
|
+
s.require_paths = ["lib", "ext"]
|
19
|
+
s.rubyforge_project = %q{fauna}
|
20
|
+
s.rubygems_version = %q{1.3.4}
|
21
|
+
s.signing_key = %q{/Users/eweaver/p/configuration/gem_certificates/evan_weaver-original-private_key.pem}
|
22
|
+
s.summary = %q{Gem version of T. Horinouchi's ruby-fftw3.}
|
23
|
+
s.test_files = ["test/test_fftw3.rb"]
|
24
|
+
|
25
|
+
if s.respond_to? :specification_version then
|
26
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
27
|
+
s.specification_version = 3
|
28
|
+
|
29
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
30
|
+
s.add_runtime_dependency(%q<narray>, [">= 0"])
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<narray>, [">= 0"])
|
33
|
+
end
|
34
|
+
else
|
35
|
+
s.add_dependency(%q<narray>, [">= 0"])
|
36
|
+
end
|
37
|
+
end
|
data/lib/fftw3.rb
ADDED
data/test/test_fftw3.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require "fftw3"
|
2
|
+
|
3
|
+
print "\n**TEST** all dimensions\n\n"
|
4
|
+
|
5
|
+
na = NArray.float(8,4).fill(1) # will be corced to complex
|
6
|
+
na[1,1]=5
|
7
|
+
p na
|
8
|
+
fc = FFTW3.fft(na, -1)/na.length
|
9
|
+
p fc
|
10
|
+
p fc.real
|
11
|
+
|
12
|
+
p FFTW3.fft(fc, 1).real
|
13
|
+
|
14
|
+
print "\n**TEST** single float (treated as single if lib fftw3f exits)\n"
|
15
|
+
print " --- see http://www.fftw.org/fftw3_doc/Precision.html for more info\n\n"
|
16
|
+
na = NArray.sfloat(8,4).indgen!
|
17
|
+
fc = FFTW3.fft(na, -1)/na.length
|
18
|
+
p fc
|
19
|
+
p FFTW3.fft(fc, 1).real
|
20
|
+
|
21
|
+
print "\n**TEST** dimension selection\n\n"
|
22
|
+
|
23
|
+
fc = FFTW3.fft(na, -1, 0)/na.shape[0]
|
24
|
+
p fc
|
25
|
+
p FFTW3.fft(fc, 1, 0).real
|
26
|
+
fc = FFTW3.fft(na, -1, 1)/na.shape[1]
|
27
|
+
p fc
|
28
|
+
p FFTW3.fft(fc, 1, 1).real
|
29
|
+
|
30
|
+
na = NArray.float(4,3,8,3)
|
31
|
+
na[1,1,1,0]= 1
|
32
|
+
p( fc=FFTW3.fft(na, -1, 0,2) / (na.shape[0]*na.shape[2]) )
|
33
|
+
p( fc=FFTW3.fft(na, -1, 1) / na.shape[1] )
|
34
|
+
p( fc=FFTW3.fft(na, -1, 0,1,2) / (na.shape[0]*na.shape[1]*na.shape[2]) )
|
35
|
+
p FFTW3.fft(fc, 1, 0,1,2).real
|
36
|
+
|
37
|
+
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fftw3
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "0.2"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- T. Horinouchi, Evan Weaver
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDLjCCAhagAwIBAgIBADANBgkqhkiG9w0BAQUFADA9MQ0wCwYDVQQDDARldmFu
|
14
|
+
MRgwFgYKCZImiZPyLGQBGRYIY2xvdWRidXIxEjAQBgoJkiaJk/IsZAEZFgJzdDAe
|
15
|
+
Fw0wNzA5MTYxMDMzMDBaFw0wODA5MTUxMDMzMDBaMD0xDTALBgNVBAMMBGV2YW4x
|
16
|
+
GDAWBgoJkiaJk/IsZAEZFghjbG91ZGJ1cjESMBAGCgmSJomT8ixkARkWAnN0MIIB
|
17
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5C0Io89nyApnr+PvbNFge9Vs
|
18
|
+
yRWAlGBUEMahpXp28VrrfXZT0rAW7JBo4PlCE3jl4nE4dzE6gAdItSycjTosrw7A
|
19
|
+
Ir5+xoyl4Vb35adv56TIQQXvNz+BzlqnkAY5JN0CSBRTQb6mxS3hFyD/h4qgDosj
|
20
|
+
R2RFVzHqSxCS8xq4Ny8uzOwOi+Xyu4w67fI5JvnPvMxqrlR1eaIQHmxnf76RzC46
|
21
|
+
QO5QhufjAYGGXd960XzbQsQyTDUYJzrvT7AdOfiyZzKQykKt8dEpDn+QPjFTnGnT
|
22
|
+
QmgJBX5WJN0lHF2l1sbv3gh4Kn1tZu+kTUqeXY6ShAoDTyvZRiFqQdwh8w2lTQID
|
23
|
+
AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU+WqJz3xQ
|
24
|
+
XSea1hRvvHWcIMgeeC4wDQYJKoZIhvcNAQEFBQADggEBAGLZ75jfOEW8Nsl26CTt
|
25
|
+
JFrWxQTcQT/UljeefVE3xYr7lc9oQjbqO3FOyued3qW7TaNEtZfSHoYeUSMYbpw1
|
26
|
+
XAwocIPuSRFDGM4B+hgQGVDx8PMGiJKom4qLXjO40UZsR7QyN/u869Vj45LURm6h
|
27
|
+
MBcPeqCASI+WNprj9+uZa2kmHiitrFqqfMBNlm5IFbn9XeYSta9AHVvs5QQqV2m5
|
28
|
+
hIPfLqCyxsn/YgOGvo6iwyQTWyTswamaAC3HRWZxIS1sfn/Ssqa7E7oQMkv5FAXr
|
29
|
+
x5rKePfXINf8XTJczkl9OBEYdE9aNdJsJpXD0asLgGVwBICS5Bjohp6mizJcDC1+
|
30
|
+
yZ0=
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
|
33
|
+
date: 2009-10-15 00:00:00 -07:00
|
34
|
+
default_executable:
|
35
|
+
dependencies:
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: narray
|
38
|
+
type: :runtime
|
39
|
+
version_requirement:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: "0"
|
45
|
+
version:
|
46
|
+
description: Gem version of T. Horinouchi's ruby-fftw3.
|
47
|
+
email: ""
|
48
|
+
executables: []
|
49
|
+
|
50
|
+
extensions:
|
51
|
+
- ext/extconf.rb
|
52
|
+
extra_rdoc_files:
|
53
|
+
- README
|
54
|
+
- ext/extconf.rb
|
55
|
+
- ext/na_fftw3.c
|
56
|
+
- lib/fftw3.rb
|
57
|
+
files:
|
58
|
+
- ChangeLog
|
59
|
+
- Manifest
|
60
|
+
- README
|
61
|
+
- Rakefile
|
62
|
+
- ToDo
|
63
|
+
- ext/extconf.rb
|
64
|
+
- ext/na_fftw3.c
|
65
|
+
- lib/fftw3.rb
|
66
|
+
- test/test_fftw3.rb
|
67
|
+
- fftw3.gemspec
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://blog.evanweaver.com/files/doc/fauna/ruby-fftw3/
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options:
|
74
|
+
- --line-numbers
|
75
|
+
- --inline-source
|
76
|
+
- --title
|
77
|
+
- Fftw3
|
78
|
+
- --main
|
79
|
+
- README
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
- ext
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: "0"
|
88
|
+
version:
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ">="
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: "1.2"
|
94
|
+
version:
|
95
|
+
requirements: []
|
96
|
+
|
97
|
+
rubyforge_project: fauna
|
98
|
+
rubygems_version: 1.3.4
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: Gem version of T. Horinouchi's ruby-fftw3.
|
102
|
+
test_files:
|
103
|
+
- test/test_fftw3.rb
|
metadata.gz.sig
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
�����k�IM e~���]1�HAcM@�.���74��F��<�֝�O�X��]��a+)EM�/V����C-�m�9�\6��n��=3�'j�����[����F��o�P�_�ߊ�2�{ ���Ps�赊��=%:$�p������r�S��ze�.(�k� �Jt~�Ѝ�����U&&��C�c�lw²X%Jd�>+&����AB9(�/�CAEcO�Rg��{4?SR�����U�x�A
|