gentooboontoo-ruby-fftw3 0.4

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ data.tar.gz: 381bc6384e2b4f1154e496bf8ddeba529e2a80c4
4
+ metadata.gz: beb5b7d7898dbcbb4984b57a6d6e0e8354fd7610
5
+ SHA512:
6
+ data.tar.gz: 8def53c2e5f3f1dd6821ace719a356deb7b984ca2288d544606e4db4586d9ede2a4270821364145c7235fe3c968d27a0e41ebf544049163bc7e98818c154036a
7
+ metadata.gz: c2f131652decce6fcfc944ddafb62f95605b8df76112e9aa137226eb39284ba60ed5cb9e8b2f4a92b15124caad67a10bf212c1f1bbf56c6b6386126fea112ff0
data/ChangeLog ADDED
@@ -0,0 +1,21 @@
1
+ Tue Apr 19 2011 T Horinouchi
2
+ * version 0.4 released (cvs tag ruby-fftw3-0_4)
3
+ * doc/ruby-fftw3.rd and doc/ruby-fftw3.html : updated
4
+ * na_fftw3.c: added rb_require("narray"); -- then you do
5
+ not need to require "narray" separately.
6
+ * test/complexFFT.rb: removed the first line: require "narray"
7
+ * LICENSE.txt: changed --> BSD 2-clause license
8
+ Thu Mar 24 2011 T Horinouchi
9
+ * version 0.3 released (cvs tag ruby-fftw3-0_3)
10
+ * LICENSE.txt: added
11
+ Mon Jun 7 2004 T Horinouchi < T Koshiro
12
+ * version 0.2 released (cvs tag ruby-fftw3-0_2)
13
+ * extconf.rb: improved
14
+ Mon Jun 7 2004 T Horinouchi
15
+ * renamed to ruby-fftw. Started a new cvs module ruby-fftw3.
16
+ Fri Nov 20 2003 T Horinouchi
17
+ * version 0.1 released
18
+ Thu Nov 20 2003 T Horinouchi
19
+ * na_fftw3.c: debug of na_fftw3_float
20
+ Tue Nov 18 2003 T Horinouchi
21
+ * created. version 0.0
data/LICENSE.txt ADDED
@@ -0,0 +1,34 @@
1
+ Ruby-FFTW3 is copyrighted free software by Takeshi Horinouchi and GFD
2
+ Dennou Club (http://www.gfd-dennou.org/).
3
+
4
+ Copyright 2001 (C) Takeshi Horinouchi and GFD Dennou Club
5
+ (http://www.gfd-dennou.org/) All rights reserved.
6
+
7
+ Redistribution and use in source and binary forms, with or without
8
+ modification, are permitted provided that the following conditions are
9
+ met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
13
+
14
+ 2. Redistributions in binary form must reproduce the above copyright
15
+ notice, this list of conditions and the following disclaimer in
16
+ the documentation and/or other materials provided with the
17
+ distribution.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY GFD DENNOU CLUB AND CONTRIBUTORS ``AS IS''
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
23
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ The views and conclusions contained in the software and documentation
32
+ are those of the authors and should not be interpreted as representing
33
+ official policies, either expressed or implied, of Takeshi Horinouchi
34
+ and GFD Dennou Club.
@@ -0,0 +1,116 @@
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>
data/doc/ruby-fftw3.rd ADDED
@@ -0,0 +1,115 @@
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/ext/extconf.rb ADDED
@@ -0,0 +1,44 @@
1
+ require "mkmf"
2
+
3
+ narray_spec = Gem::Specification.find_by_name('narray')
4
+ narray_gem_path = narray_spec.full_gem_path
5
+ dir_config('narray', narray_gem_path, narray_gem_path)
6
+
7
+ if ( ! ( have_header("narray.h") && have_header("narray_config.h") ) ) then
8
+ print <<-EOS
9
+ ** configure error **
10
+ Header narray.h or narray_config.h is not found. If you have these files in
11
+ /narraydir/include, try the following:
12
+
13
+ % ruby extconf.rb --with-narray-include=/narraydir/include
14
+
15
+ EOS
16
+ exit(-1)
17
+ end
18
+
19
+ if ( ! ( have_header("fftw3.h") && have_library("fftw3") ) ) then
20
+ print <<EOS
21
+ ** configure error **
22
+ Header fftw3.h or the compiled fftw3 library is not found.
23
+ If you have the library installed under /fftw3dir (that is, fftw3.h is
24
+ in /fftw3dir/include and the library in /fftw3dir/lib/),
25
+ try the following:
26
+
27
+ % ruby extconf.rb --with-fftw3-dir=/fftw3dir
28
+
29
+ Alternatively, you can specify the two directory separately
30
+ with --with-fftw3-include and --with-fftw3-lib.
31
+ EOS
32
+ exit(-1)
33
+ end
34
+
35
+ if have_library("fftw3f")
36
+ $CFLAGS += ' -DFFTW3_HAS_SINGLE_SUPPORT'
37
+ end
38
+
39
+ if /cygwin|mingw/ =~ RUBY_PLATFORM
40
+ have_library("narray") || raise("ERROR: narray library is not found")
41
+ end
42
+
43
+ $libs << " -l:narray.so" # Fix underlinking issue on Gentoo (extension linked with --as-needed --no-undefined)
44
+ create_makefile("numru/fftw3")
data/ext/na_fftw3.c ADDED
@@ -0,0 +1,285 @@
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
+ }
@@ -0,0 +1,38 @@
1
+ require "numru/fftw3"
2
+ include NumRu
3
+
4
+ print "\n**TEST** all dimensions\n\n"
5
+
6
+ na = NArray.float(8,4).fill(1) # will be corced to complex
7
+ na[1,1]=5
8
+ p na
9
+ fc = FFTW3.fft(na, -1)/na.length
10
+ p fc
11
+ p fc.real
12
+
13
+ p FFTW3.fft(fc, 1).real
14
+
15
+ print "\n**TEST** single float (treated as single if lib fftw3f exits)\n"
16
+ print " --- see http://www.fftw.org/fftw3_doc/Precision.html for more info\n\n"
17
+ na = NArray.sfloat(8,4).indgen!
18
+ fc = FFTW3.fft(na, -1)/na.length
19
+ p fc
20
+ p FFTW3.fft(fc, 1).real
21
+
22
+ print "\n**TEST** dimension selection\n\n"
23
+
24
+ fc = FFTW3.fft(na, -1, 0)/na.shape[0]
25
+ p fc
26
+ p FFTW3.fft(fc, 1, 0).real
27
+ fc = FFTW3.fft(na, -1, 1)/na.shape[1]
28
+ p fc
29
+ p FFTW3.fft(fc, 1, 1).real
30
+
31
+ na = NArray.float(4,3,8,3)
32
+ na[1,1,1,0]= 1
33
+ p( fc=FFTW3.fft(na, -1, 0,2) / (na.shape[0]*na.shape[2]) )
34
+ p( fc=FFTW3.fft(na, -1, 1) / na.shape[1] )
35
+ p( fc=FFTW3.fft(na, -1, 0,1,2) / (na.shape[0]*na.shape[1]*na.shape[2]) )
36
+ p FFTW3.fft(fc, 1, 0,1,2).real
37
+
38
+
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gentooboontoo-ruby-fftw3
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.4"
5
+ platform: ruby
6
+ authors:
7
+ - Takeshi Horinouchi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2012-02-26 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: narray
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - &id002
20
+ - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ type: :runtime
24
+ version_requirements: *id001
25
+ description: Fast Fourier Transforms by using FFTW Ver.3
26
+ email:
27
+ - julien.sanchez@gmail.com
28
+ executables: []
29
+
30
+ extensions:
31
+ - ext/extconf.rb
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - doc/ruby-fftw3.html
36
+ - doc/ruby-fftw3.rd
37
+ - test/complexFFT.rb
38
+ - ChangeLog
39
+ - LICENSE.txt
40
+ - ext/na_fftw3.c
41
+ - ext/extconf.rb
42
+ homepage: http://www.gfd-dennou.org/arch/ruby/products/ruby-fftw3/
43
+ licenses:
44
+ - BSD
45
+ metadata: {}
46
+
47
+ post_install_message:
48
+ rdoc_options: []
49
+
50
+ require_paths:
51
+ - lib
52
+ required_ruby_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "1.6"
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - *id002
60
+ requirements: []
61
+
62
+ rubyforge_project:
63
+ rubygems_version: 2.0.3
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Rubygems-compatible fork of the Ruby interface of the FFTW (ver 3) library
67
+ test_files: []
68
+