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 +7 -0
- data/ChangeLog +21 -0
- data/LICENSE.txt +34 -0
- data/doc/ruby-fftw3.html +116 -0
- data/doc/ruby-fftw3.rd +115 -0
- data/ext/extconf.rb +44 -0
- data/ext/na_fftw3.c +285 -0
- data/test/complexFFT.rb +38 -0
- metadata +68 -0
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.
|
data/doc/ruby-fftw3.html
ADDED
@@ -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 -> 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</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) & 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
|
+
}
|
data/test/complexFFT.rb
ADDED
@@ -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
|
+
|