fftw3 0.2
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.
- 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
|