ruby-fftw3 0.4.2 → 1.0.0
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 +4 -4
- data/{ChangeLog → .ChangeLog.until20110419} +0 -0
- data/.gitignore +5 -6
- data/LICENSE.txt +1 -1
- data/Rakefile +35 -1
- data/{extconf.rb → ext/numru/fftw3/extconf.rb} +32 -6
- data/ext/numru/fftw3/na_fftw3.c +690 -0
- data/lib/numru/fftw3.rb +102 -0
- data/lib/numru/fftw3/version.rb +2 -2
- data/ruby-fftw3-bigmem.gemspec +25 -0
- data/ruby-fftw3.gemspec +5 -12
- data/test/complexFFT.rb +57 -34
- data/test/r2rFFT.rb +77 -0
- metadata +19 -22
- data/.rspec +0 -2
- data/.travis.yml +0 -3
- data/README.rd +0 -0
- data/doc/ruby-fftw3.html +0 -116
- data/doc/ruby-fftw3.rd +0 -115
- data/na_fftw3.c +0 -285
- data/spec/ruby/fftw3_spec.rb +0 -11
- data/spec/spec_helper.rb +0 -2
data/lib/numru/fftw3.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
begin
|
2
|
+
require "rubygems"
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
|
6
|
+
require "numru/fftw3/version"
|
7
|
+
require "numru/fftw3/fftw3"
|
8
|
+
|
9
|
+
module NumRu
|
10
|
+
|
11
|
+
# Ruby wrapper of FFTW3, a fast discrete Fourier transform library. http://www.fftw.org
|
12
|
+
#
|
13
|
+
# ==Features
|
14
|
+
#
|
15
|
+
# * Uses NArray (https://github.com/masa16/narray). (Also it supports
|
16
|
+
# NumRu::NArray as well, if this library is compiled to use it).
|
17
|
+
# * Multi-dimensional complex and real FFT.
|
18
|
+
# * Supports both double and single float transforms.
|
19
|
+
#
|
20
|
+
# ==How to use
|
21
|
+
#
|
22
|
+
# Copy and paste the following code line-by-line using irb.
|
23
|
+
# Or you can run it by saving it in a file fftw3test.rb (say)
|
24
|
+
# and executing "ruby fftw3test.rb".
|
25
|
+
#
|
26
|
+
# require "numru/fftw3"
|
27
|
+
# include NumRu
|
28
|
+
#
|
29
|
+
# na = NArray.float(8,6) # float -> will be coerced to complex
|
30
|
+
# na[1,1]=1
|
31
|
+
#
|
32
|
+
# # <example 1: complex FFT on all dimensions >
|
33
|
+
#
|
34
|
+
# fc = FFTW3.fft(na, FFTW3::FORWARD)/na.length # forward 2D FFT and normalization
|
35
|
+
# nc = FFTW3.fft(fc, FFTW3::BACKWARD) # backward 2D FFT (complex) -->
|
36
|
+
# nb = nc.real # should be equal to na except round errors
|
37
|
+
# p (nb - na).abs.max # => 8.970743058303247e-17 (sufficiently small)
|
38
|
+
#
|
39
|
+
# # <example 2: complex FFT on all dimensions >
|
40
|
+
# # Same as example 1 but using more user-friendly wrapper of FFTW3.fft
|
41
|
+
#
|
42
|
+
# fc = FFTW3.fft_fw(na) # forward 2D FFT and normalization
|
43
|
+
# nc = FFTW3.fft_bk(fc) # backward 2D FFT (complex) -->
|
44
|
+
# nb = nc.real # should be equal to na except round errors
|
45
|
+
# p (nb - na).abs.max # => 8.970743058303247e-17 (sufficiently small)
|
46
|
+
#
|
47
|
+
# # <example 3: complex FFT along a dimension >
|
48
|
+
# fc = FFTW3.fft_fw(na, 0) # forward 1D FFT along the first dim
|
49
|
+
# nc = FFTW3.fft_bk(fc, 0) # backward 1D FFT along the first dim
|
50
|
+
# p (nc.real - na).abs.max # => 1.1102230246251565e-16 (sufficiently small)
|
51
|
+
#
|
52
|
+
# # <example 4: complex FFT along a dimension >
|
53
|
+
# fc = FFTW3.fft_fw(na, 1) # forward 1D FFT along the second dim
|
54
|
+
#
|
55
|
+
# # <example 5: real FFT along a dimension >
|
56
|
+
#
|
57
|
+
# fc = FFTW3.fft_r2r(na, FFTW3::RODFT00, 0) # not normalized sine transform along the 1st dim
|
58
|
+
# len = 2*(na.shape[0]+1) # this is the supposed length of this transformation
|
59
|
+
# nc = FFTW3.fft_r2r(fc/len, FFTW3::RODFT00, 0) # forward==backward transformation
|
60
|
+
# p (nc-na).abs.max # => 2.220446049250313e-16 (sufficiently small)
|
61
|
+
#
|
62
|
+
# # <example 5b: real FFT on all dimensions >
|
63
|
+
#
|
64
|
+
# fc = FFTW3.fft_r2r(na, FFTW3::REDFT11) # unnormalized cosine transform
|
65
|
+
# len = 4*na.length # from (2*na.shape[0]) * (2*na.shape[1])
|
66
|
+
# nc = FFTW3.fft_r2r(fc/len, FFTW3::REDFT11) # forward==backward transformation
|
67
|
+
# p (nc-na).abs.max # => 6.228190483314256e-17 (sufficiently small)
|
68
|
+
#
|
69
|
+
# See the FFTW3 manual for the kinds of supported real FFTs. See Ch.2 of
|
70
|
+
# http://www.fftw.org/fftw3_doc/ (http://www.fftw.org/fftw3.pdf).
|
71
|
+
# Virtually all kinds are supported!
|
72
|
+
#
|
73
|
+
module FFTW3
|
74
|
+
|
75
|
+
module_function
|
76
|
+
|
77
|
+
# Forward complex FFT with normalization
|
78
|
+
#
|
79
|
+
# This calls FFW3.fft(na, FFW3::FORWARD, *dims) and normalizes the result
|
80
|
+
# by dividing by the length
|
81
|
+
#
|
82
|
+
def fft_fw(na, *dims)
|
83
|
+
fc = fft(na, FORWARD, *dims)
|
84
|
+
if dims.length == 0
|
85
|
+
len = na.total
|
86
|
+
else
|
87
|
+
len = 1
|
88
|
+
shape = na.shape
|
89
|
+
dims.each{|d| len *= shape[d]}
|
90
|
+
end
|
91
|
+
fc / len
|
92
|
+
end
|
93
|
+
|
94
|
+
# Backward complex FFT
|
95
|
+
#
|
96
|
+
# This method simply calls FFW3.fft(na, FFW3::BACKWARD, *dims)
|
97
|
+
#
|
98
|
+
def fft_bk(na, *dims)
|
99
|
+
fft(na, BACKWARD, *dims)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/numru/fftw3/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'numru/fftw3/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "ruby-fftw3-bigmem"
|
8
|
+
spec.version = NumRu::FFTW3::VERSION
|
9
|
+
spec.authors = ["Takeshi Horinouchi"]
|
10
|
+
spec.email = ['eriko@gfd-dennou.org']
|
11
|
+
|
12
|
+
spec.summary = %q{The Ruby interface of the FFTW (ver 3) library}
|
13
|
+
spec.description = %q{Fast Fourier Transforms by using FFTW Ver.3. This new version works with Ruby2.0.}
|
14
|
+
spec.homepage = 'http://www.gfd-dennou.org/arch/ruby/products/ruby-fftw3/'
|
15
|
+
spec.licenses = ["BSD-2-Clause"]
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.test_files = spec.files.grep(%r{^test/})
|
19
|
+
spec.require_paths = ["ext","lib"]
|
20
|
+
|
21
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 1.8")
|
22
|
+
spec.add_runtime_dependency(%q<narray-bigmem>, [">= 0"])
|
23
|
+
|
24
|
+
spec.extensions << "ext/numru/fftw3/extconf.rb"
|
25
|
+
end
|
data/ruby-fftw3.gemspec
CHANGED
@@ -5,28 +5,21 @@ require 'numru/fftw3/version'
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "ruby-fftw3"
|
8
|
-
spec.version =
|
8
|
+
spec.version = NumRu::FFTW3::VERSION
|
9
9
|
spec.authors = ["Takeshi Horinouchi"]
|
10
10
|
spec.email = ['eriko@gfd-dennou.org']
|
11
11
|
|
12
|
-
#if spec.respond_to?(:metadata)
|
13
|
-
# spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com' to prevent pushes to rubygems.org, or delete to allow pushes to any server."
|
14
|
-
#end
|
15
|
-
|
16
12
|
spec.summary = %q{The Ruby interface of the FFTW (ver 3) library}
|
17
13
|
spec.description = %q{Fast Fourier Transforms by using FFTW Ver.3. This new version works with Ruby2.0.}
|
18
14
|
spec.homepage = 'http://www.gfd-dennou.org/arch/ruby/products/ruby-fftw3/'
|
19
|
-
spec.licenses = ["
|
15
|
+
spec.licenses = ["BSD-2-Clause"]
|
20
16
|
|
21
|
-
#spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
22
17
|
spec.files = `git ls-files -z`.split("\x0")
|
23
18
|
spec.test_files = spec.files.grep(%r{^test/})
|
24
|
-
|
25
|
-
#spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
26
|
-
spec.require_paths = ["lib"]
|
19
|
+
spec.require_paths = ["ext","lib"]
|
27
20
|
|
28
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 1.
|
21
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 1.8")
|
29
22
|
spec.add_runtime_dependency(%q<narray>, [">= 0"])
|
30
23
|
|
31
|
-
spec.extensions << "extconf.rb"
|
24
|
+
spec.extensions << "ext/numru/fftw3/extconf.rb"
|
32
25
|
end
|
data/test/complexFFT.rb
CHANGED
@@ -1,39 +1,62 @@
|
|
1
|
-
|
1
|
+
begin
|
2
|
+
require "rubygems"
|
3
|
+
rescue LoadError
|
4
|
+
end
|
5
|
+
require "narray" # This line is needed for rake test when making a gem package.
|
2
6
|
require "numru/fftw3"
|
7
|
+
require "test/unit"
|
3
8
|
include NumRu
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
na = NArray.
|
33
|
-
na[1,1
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
10
|
+
class FFTW3Test < Test::Unit::TestCase
|
11
|
+
def setup
|
12
|
+
@eps = 1e-10
|
13
|
+
@seps = 1e-6
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_fft_fw_bk
|
17
|
+
na = NArray.float(8,4).fill(1) # will be corced to complex
|
18
|
+
na[1,1]=5
|
19
|
+
fc = FFTW3.fft_fw(na)
|
20
|
+
nb = FFTW3.fft_bk(fc).real
|
21
|
+
assert( (na-nb).abs.max < @eps )
|
22
|
+
|
23
|
+
fc = FFTW3.fft_fw(na,1)
|
24
|
+
nb = FFTW3.fft_bk(fc,1).real
|
25
|
+
assert( (na-nb).abs.max < @eps )
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_real_all_dims
|
29
|
+
na = NArray.float(8,4).fill(1) # will be corced to complex
|
30
|
+
na[1,1]=5
|
31
|
+
fc = FFTW3.fft(na, FFTW3::FORWARD)/na.length
|
32
|
+
nb = FFTW3.fft(fc, FFTW3::BACKWARD).real
|
33
|
+
assert( (na-nb).abs.max < @eps )
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_complex_all_dims
|
37
|
+
na = NArray.complex(8,4).fill(1) * Complex::I
|
38
|
+
na[1,1]=5
|
39
|
+
fc = FFTW3.fft(na, -1)/na.length
|
40
|
+
nb = FFTW3.fft(fc, 1)
|
41
|
+
assert( (na-nb).abs.max < @eps )
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_dim_selection
|
45
|
+
na = NArray.float(8,4).indgen!
|
46
|
+
fc = FFTW3.fft(na, FFTW3::FORWARD, 0)
|
47
|
+
fc = FFTW3.fft(fc, FFTW3::FORWARD, 1)
|
48
|
+
fc2 = FFTW3.fft(na, FFTW3::FORWARD)
|
49
|
+
assert( (fc-fc2).abs.max < @eps )
|
50
|
+
end
|
51
|
+
|
52
|
+
# TEST: single float (treated as single if lib fftw3f exits).
|
53
|
+
# see http://www.fftw.org/fftw3_doc/Precision.html for more info
|
54
|
+
def test_single_float
|
55
|
+
na = NArray.sfloat(8,4).indgen!
|
56
|
+
fc = FFTW3.fft(na, -1)/na.length
|
57
|
+
nb = FFTW3.fft(fc, 1).real
|
58
|
+
assert( (na-nb).abs.max < @seps )
|
59
|
+
end
|
60
|
+
end
|
38
61
|
|
39
62
|
|
data/test/r2rFFT.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require "narray" # This line is needed for rake test when making a gem package.
|
2
|
+
require "numru/fftw3"
|
3
|
+
require "test/unit"
|
4
|
+
include NumRu
|
5
|
+
|
6
|
+
class FFTW3_R2R_Test < Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@eps = 1e-10
|
9
|
+
@seps = 1e-5
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_r2r_all_dims
|
13
|
+
nx = 8
|
14
|
+
ny = 4
|
15
|
+
na = NArray.float(nx,ny).indgen!
|
16
|
+
|
17
|
+
fc = FFTW3.fft_r2r(na, FFTW3::REDFT00) # cosine trans at 0, 1, 2,...
|
18
|
+
c = 1.0 / (2*(nx-1)) / (2*(ny-1))
|
19
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT00)
|
20
|
+
assert( (na-nb).abs.max < @eps )
|
21
|
+
|
22
|
+
fc = FFTW3.fft_r2r(na, FFTW3::REDFT11) # cosine trans at 1/2, 1+1/2,...
|
23
|
+
c = 1.0 / (2*nx) / (2*ny)
|
24
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT11)
|
25
|
+
assert( (na-nb).abs.max < @eps )
|
26
|
+
|
27
|
+
fc = FFTW3.fft_r2r(na, FFTW3::REDFT01)
|
28
|
+
c = 1.0 / (2*nx) / (2*ny)
|
29
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT10)
|
30
|
+
assert( (na-nb).abs.max < @eps )
|
31
|
+
|
32
|
+
fc = FFTW3.fft_r2r(na, FFTW3::RODFT00) # sine trans at 1, 2,...
|
33
|
+
c = 1.0 / (2*(nx+1)) / (2*(ny+1))
|
34
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::RODFT00)
|
35
|
+
assert( (na-nb).abs.max < @eps )
|
36
|
+
|
37
|
+
fc = FFTW3.fft_r2r(na, FFTW3::RODFT11) # sine trans at 1/2, 1+1/2,...
|
38
|
+
c = 1.0 / (2*nx) / (2*ny)
|
39
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::RODFT11)
|
40
|
+
assert( (na-nb).abs.max < @eps )
|
41
|
+
|
42
|
+
fc = FFTW3.fft_r2r(na, FFTW3::RODFT01) # sine trans
|
43
|
+
c = 1.0 / (2*nx) / (2*ny)
|
44
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::RODFT10)
|
45
|
+
assert( (na-nb).abs.max < @eps )
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_r2r_sigle
|
50
|
+
nx = 8
|
51
|
+
ny = 4
|
52
|
+
na = NArray.sfloat(nx,ny).indgen!
|
53
|
+
|
54
|
+
fc = FFTW3.fft_r2r(na, FFTW3::REDFT00) # cosine trans at 0, 1, 2,...
|
55
|
+
c = 1.0 / (2*(nx-1)) / (2*(ny-1))
|
56
|
+
nb = FFTW3.fft_r2r(fc*c, FFTW3::REDFT00)
|
57
|
+
assert( (na-nb).abs.max < @seps )
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
def test_r2r_some_dims
|
62
|
+
nx = 8
|
63
|
+
ny = 4
|
64
|
+
na = NArray.float(nx,ny).indgen!
|
65
|
+
|
66
|
+
fc = FFTW3.fft_r2r(na, FFTW3::REDFT00, 0)
|
67
|
+
nb = FFTW3.fft_r2r(fc, FFTW3::REDFT00, 0) / (2*(nx-1))
|
68
|
+
assert( (na-nb).abs.max < @eps )
|
69
|
+
|
70
|
+
fc = FFTW3.fft_r2r(fc, FFTW3::RODFT11, 1)
|
71
|
+
fc2 = FFTW3.fft_r2r(na, [FFTW3::REDFT00, FFTW3::RODFT11])
|
72
|
+
fc3 = FFTW3.fft_r2r(na, [FFTW3::REDFT00, FFTW3::RODFT11], 0, 1)
|
73
|
+
assert( (fc-fc2).abs.max < @eps )
|
74
|
+
assert( (fc-fc3).abs.max < @eps )
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
metadata
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-fftw3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takeshi Horinouchi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: narray
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
description: Fast Fourier Transforms by using FFTW Ver.3. This new version works with
|
@@ -30,51 +30,48 @@ email:
|
|
30
30
|
- eriko@gfd-dennou.org
|
31
31
|
executables: []
|
32
32
|
extensions:
|
33
|
-
- extconf.rb
|
33
|
+
- ext/numru/fftw3/extconf.rb
|
34
34
|
extra_rdoc_files: []
|
35
35
|
files:
|
36
|
-
- .
|
37
|
-
- .
|
38
|
-
- .travis.yml
|
39
|
-
- ChangeLog
|
36
|
+
- ".ChangeLog.until20110419"
|
37
|
+
- ".gitignore"
|
40
38
|
- Gemfile
|
41
39
|
- LICENSE.txt
|
42
|
-
- README.rd
|
43
40
|
- Rakefile
|
44
41
|
- ToDo
|
45
|
-
-
|
46
|
-
-
|
47
|
-
-
|
42
|
+
- ext/numru/fftw3/extconf.rb
|
43
|
+
- ext/numru/fftw3/na_fftw3.c
|
44
|
+
- lib/numru/fftw3.rb
|
48
45
|
- lib/numru/fftw3/version.rb
|
49
|
-
-
|
46
|
+
- ruby-fftw3-bigmem.gemspec
|
50
47
|
- ruby-fftw3.gemspec
|
51
|
-
- spec/ruby/fftw3_spec.rb
|
52
|
-
- spec/spec_helper.rb
|
53
48
|
- test/complexFFT.rb
|
49
|
+
- test/r2rFFT.rb
|
54
50
|
homepage: http://www.gfd-dennou.org/arch/ruby/products/ruby-fftw3/
|
55
51
|
licenses:
|
56
|
-
-
|
57
|
-
- GFD Dennou Club
|
52
|
+
- BSD-2-Clause
|
58
53
|
metadata: {}
|
59
54
|
post_install_message:
|
60
55
|
rdoc_options: []
|
61
56
|
require_paths:
|
57
|
+
- ext
|
62
58
|
- lib
|
63
59
|
required_ruby_version: !ruby/object:Gem::Requirement
|
64
60
|
requirements:
|
65
|
-
- -
|
61
|
+
- - ">="
|
66
62
|
- !ruby/object:Gem::Version
|
67
|
-
version: '1.
|
63
|
+
version: '1.8'
|
68
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
65
|
requirements:
|
70
|
-
- -
|
66
|
+
- - ">="
|
71
67
|
- !ruby/object:Gem::Version
|
72
68
|
version: '0'
|
73
69
|
requirements: []
|
74
70
|
rubyforge_project:
|
75
|
-
rubygems_version: 2.
|
71
|
+
rubygems_version: 2.2.2
|
76
72
|
signing_key:
|
77
73
|
specification_version: 4
|
78
74
|
summary: The Ruby interface of the FFTW (ver 3) library
|
79
75
|
test_files:
|
80
76
|
- test/complexFFT.rb
|
77
|
+
- test/r2rFFT.rb
|
data/.rspec
DELETED