convolver 0.3.2 → 0.4.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 +5 -5
- data/.github/workflows/ci.yml +40 -0
- data/.rubocop.yml +16 -0
- data/Gemfile +11 -0
- data/README.md +22 -2
- data/Rakefile +8 -6
- data/convolver.gemspec +17 -21
- data/ext/convolver/convolve_raw.c +15 -1
- data/ext/convolver/convolve_raw.h +5 -0
- data/ext/convolver/convolver.c +0 -1
- data/ext/convolver/extconf.rb +15 -9
- data/lib/convolver/version.rb +3 -1
- data/lib/convolver.rb +41 -53
- data/spec/convolver_basic_spec.rb +89 -0
- data/spec/convolver_fftw3_spec.rb +166 -0
- data/spec/convolver_spec.rb +53 -0
- data/spec/helpers.rb +13 -16
- metadata +16 -106
- data/.travis.yml +0 -19
- data/spec/convolve_basic_spec.rb +0 -84
- data/spec/convolve_fftw3_spec.rb +0 -161
- data/spec/convolve_spec.rb +0 -49
data/spec/convolve_fftw3_spec.rb
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
require 'helpers'
|
|
2
|
-
|
|
3
|
-
describe Convolver do
|
|
4
|
-
describe "#convolve_fftw3" do
|
|
5
|
-
|
|
6
|
-
it "should work like the example in the README" do
|
|
7
|
-
a = NArray[ 0.3, 0.4, 0.5 ]
|
|
8
|
-
b = NArray[ 1.3, -0.5 ]
|
|
9
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
10
|
-
expect( c ).to be_narray_like NArray[ 0.19, 0.27 ]
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "should convolve 1D arrays with a variety of signal and kernel lengths" do
|
|
14
|
-
a = NArray[ 0.3 ]
|
|
15
|
-
b = NArray[ -0.7 ]
|
|
16
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
17
|
-
expect( c ).to be_narray_like NArray[ -0.21 ]
|
|
18
|
-
|
|
19
|
-
a = NArray[ 0.3, 0.4, 0.5, 0.2 ]
|
|
20
|
-
b = NArray[ -0.7 ]
|
|
21
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
22
|
-
expect( c ).to be_narray_like NArray[ -0.21, -0.28, -0.35, -0.14 ]
|
|
23
|
-
|
|
24
|
-
a = NArray[ 0.3, 0.4, 0.5, 0.2 ]
|
|
25
|
-
b = NArray[ 1.1, -0.7 ]
|
|
26
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
27
|
-
expect( c ).to be_narray_like NArray[ 0.05, 0.09, 0.41 ]
|
|
28
|
-
|
|
29
|
-
a = NArray[ 0.3, 0.4, 0.5, 0.2 ]
|
|
30
|
-
b = NArray[ 1.1, -0.7, -0.2 ]
|
|
31
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
32
|
-
expect( c ).to be_narray_like NArray[ -0.05, 0.05 ]
|
|
33
|
-
|
|
34
|
-
a = NArray[ 0.3, 0.4, 0.5, 0.2, 0.6 ]
|
|
35
|
-
b = NArray[ 1.1, -0.7 ]
|
|
36
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
37
|
-
expect( c ).to be_narray_like NArray[ 0.05, 0.09, 0.41, -0.2 ]
|
|
38
|
-
|
|
39
|
-
a = NArray[ 0.3, 0.4, 0.5, 0.2, 0.6 ]
|
|
40
|
-
b = NArray[ 1.1, -0.7, 2.1 ]
|
|
41
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
42
|
-
expect( c ).to be_narray_like NArray[ 1.1, 0.51, 1.67 ]
|
|
43
|
-
|
|
44
|
-
a = NArray[ 0.3, 0.4, 0.5, 0.2, 0.6 ]
|
|
45
|
-
b = NArray[ 0.6, -0.5, -0.4, 0.7 ]
|
|
46
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
47
|
-
expect( c ).to be_narray_like NArray[ -0.08, 0.33 ]
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "should calculate a 2D convolution" do
|
|
51
|
-
a = NArray[ [ 0.3, 0.4, 0.5 ], [ 0.6, 0.8, 0.2 ], [ 0.9, 1.0, 0.1 ] ]
|
|
52
|
-
b = NArray[ [ 1.2, -0.5 ], [ 0.5, -1.3 ] ]
|
|
53
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
54
|
-
expect( c ).to be_narray_like NArray[ [ -0.58, 0.37 ], [ -0.53, 1.23 ] ]
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
it "should calculate a 3D convolution" do
|
|
58
|
-
# 5x4x3
|
|
59
|
-
a = NArray[
|
|
60
|
-
[ [ 1.0, 0.6, 1.1, 0.2, 0.9 ], [ 1.0, 0.7, 0.8, 1.0, 1.0 ], [ 0.2, 0.6, 0.1, 0.2, 0.5 ], [ 0.5, 0.9, 0.2, 0.1, 0.6 ] ],
|
|
61
|
-
[ [ 0.4, 0.9, 0.4, 0.0, 0.6 ], [ 0.2, 1.1, 0.2, 0.4, 0.1 ], [ 0.4, 0.2, 0.5, 0.8, 0.7 ], [ 0.1, 0.9, 0.7, 0.1, 0.3 ] ],
|
|
62
|
-
[ [ 0.8, 0.6, 1.0, 0.1, 0.4 ], [ 0.3, 0.8, 0.6, 0.7, 1.1 ], [ 0.9, 1.0, 0.3, 0.4, 0.6 ], [ 0.2, 0.5, 0.4, 0.7, 0.2 ] ]
|
|
63
|
-
]
|
|
64
|
-
|
|
65
|
-
# 3x3x3
|
|
66
|
-
b = NArray[
|
|
67
|
-
[ [ -0.9, 1.2, 0.8 ], [ 0.9, 0.1, -0.5 ], [ 1.1, 0.1, -1.1 ] ],
|
|
68
|
-
[ [ -0.2, -1.0, 1.4 ], [ -1.4, 0.0, 1.3 ], [ 0.3, 1.0, -0.5 ] ],
|
|
69
|
-
[ [ 0.6, 0.0, 0.7 ], [ -0.7, 1.1, 1.2 ], [ 1.3, 0.7, 0.0 ] ]
|
|
70
|
-
]
|
|
71
|
-
|
|
72
|
-
# Should be 3x2x1
|
|
73
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
74
|
-
expect( c ).to be_narray_like NArray[ [ [ 5.51, 3.04, 4.3 ], [ 3.04, 6.31, 3.87 ] ] ]
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it "should calculate a 4D convolution" do
|
|
78
|
-
# 3x4x5x3
|
|
79
|
-
a = NArray[
|
|
80
|
-
[ [ [ 0.5, 0.4, 0.9 ], [ 0.1, 0.9, 0.8 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
81
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
82
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
83
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
84
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ] ],
|
|
85
|
-
[ [ [ 0.5, 0.4, 0.9 ], [ 0.1, 0.9, 0.8 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
86
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
87
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
88
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
89
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ] ],
|
|
90
|
-
[ [ [ 0.5, 0.4, 0.9 ], [ 0.1, 0.9, 0.8 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
91
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
92
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
93
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
94
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ] ] ]
|
|
95
|
-
|
|
96
|
-
# 2x3x3x2
|
|
97
|
-
b = NArray[ [
|
|
98
|
-
[ [ 1.1, 0.6 ], [ 1.2, 0.6 ], [ 0.8, 0.1 ] ], [ [ -0.4, 0.8 ], [ 0.5, 0.4 ], [ 1.2, 0.2 ] ],
|
|
99
|
-
[ [ 0.8, 0.2 ], [ 0.5, 0.0 ], [ 1.4, 1.3 ] ] ],
|
|
100
|
-
[ [ [ 1.1, 0.6 ], [ 1.2, 0.6 ], [ 0.8, 0.1 ] ], [ [ -0.4, 0.8 ], [ 0.5, 0.4 ], [ 1.2, 0.2 ] ],
|
|
101
|
-
[ [ 0.8, 0.2 ], [ 0.5, 0.0 ], [ 1.4, 1.3 ] ] ] ]
|
|
102
|
-
|
|
103
|
-
# Should be 2x2x3x2
|
|
104
|
-
c = Convolver.convolve_fftw3( a, b )
|
|
105
|
-
expect( c ).to be_narray_like NArray[
|
|
106
|
-
[ [ [ 8.5, 8.2 ], [ 11.34, 9.68 ] ], [ [ 7.68, 6.56 ], [ 11.24, 7.16 ] ], [ [ 9.14, 6.54 ], [ 12.44, 9.2 ] ] ],
|
|
107
|
-
[ [ [ 8.5, 8.2 ], [ 11.34, 9.68 ] ], [ [ 7.68, 6.56 ], [ 11.24, 7.16 ] ], [ [ 9.14, 6.54 ], [ 12.44, 9.2 ] ] ]
|
|
108
|
-
]
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
describe "compared with #convolve" do
|
|
112
|
-
it "should produce same results for 1D arrays " do
|
|
113
|
-
(1..30).each do |signal_length|
|
|
114
|
-
(1..signal_length).each do |kernel_length|
|
|
115
|
-
signal = NArray.sfloat(signal_length).random()
|
|
116
|
-
kernel = NArray.sfloat(kernel_length).random()
|
|
117
|
-
expect_result = Convolver.convolve_basic( signal, kernel )
|
|
118
|
-
got_result = Convolver.convolve_fftw3( signal, kernel )
|
|
119
|
-
expect( got_result ).to be_narray_like expect_result
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
it "should produce same results for 2D arrays " do
|
|
125
|
-
(3..10).each do |signal_x|
|
|
126
|
-
(signal_x-2..signal_x+2).each do |signal_y|
|
|
127
|
-
(1..signal_x).each do |kernel_x|
|
|
128
|
-
(1..signal_y).each do |kernel_y|
|
|
129
|
-
signal = NArray.sfloat(signal_x,signal_y).random()
|
|
130
|
-
kernel = NArray.sfloat(kernel_x,kernel_y).random()
|
|
131
|
-
expect_result = Convolver.convolve_basic( signal, kernel )
|
|
132
|
-
got_result = Convolver.convolve_fftw3( signal, kernel )
|
|
133
|
-
expect( got_result ).to be_narray_like expect_result
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
it "should produce same results for 3D arrays " do
|
|
141
|
-
(3..5).each do |signal_x|
|
|
142
|
-
(signal_x-2..signal_x+2).each do |signal_y|
|
|
143
|
-
(signal_x-2..signal_x+2).each do |signal_z|
|
|
144
|
-
(1..signal_x).each do |kernel_x|
|
|
145
|
-
(1..signal_y).each do |kernel_y|
|
|
146
|
-
(1..signal_z).each do |kernel_z|
|
|
147
|
-
signal = NArray.sfloat(signal_x,signal_y,signal_z).random()
|
|
148
|
-
kernel = NArray.sfloat(kernel_x,kernel_y,kernel_z).random()
|
|
149
|
-
expect_result = Convolver.convolve_basic( signal, kernel )
|
|
150
|
-
got_result = Convolver.convolve_fftw3( signal, kernel )
|
|
151
|
-
expect( got_result ).to be_narray_like expect_result
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
end
|
|
155
|
-
end
|
|
156
|
-
end
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
data/spec/convolve_spec.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
require 'helpers'
|
|
2
|
-
|
|
3
|
-
describe Convolver do
|
|
4
|
-
describe "#convolve" do
|
|
5
|
-
|
|
6
|
-
it "should work like the example in the README" do
|
|
7
|
-
a = NArray[ 0.3, 0.4, 0.5 ]
|
|
8
|
-
b = NArray[ 1.3, -0.5 ]
|
|
9
|
-
c = Convolver.convolve( a, b )
|
|
10
|
-
expect( c ).to be_narray_like NArray[ 0.19, 0.27 ]
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "should process convolutions of different sizes" do
|
|
14
|
-
# The variety here is to ensure all branches of optimisation algorithm
|
|
15
|
-
# are covered
|
|
16
|
-
[10,30,60,90,100,120,130,150,175,200].each do |asize|
|
|
17
|
-
[5,10,12,15,20,30,40,50].each do |bsize|
|
|
18
|
-
next unless bsize < asize
|
|
19
|
-
a = NArray.sfloat(asize,asize).random()
|
|
20
|
-
b = NArray.sfloat(bsize,bsize).random()
|
|
21
|
-
c = Convolver.convolve( a, b )
|
|
22
|
-
|
|
23
|
-
# We should always match output of convolve_basic irrespective
|
|
24
|
-
# of what the optimal choice of algorithm is (larger error allowed here due to rounding)
|
|
25
|
-
expect_result = Convolver.convolve_basic( a, b )
|
|
26
|
-
expect( c ).to be_narray_like( expect_result, 1e-6 )
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "should choose #convolve_basic for small inputs" do
|
|
32
|
-
a = NArray.sfloat(50,50).random()
|
|
33
|
-
b = NArray.sfloat(10,10).random()
|
|
34
|
-
expect(Convolver).to receive(:convolve_basic).once
|
|
35
|
-
expect(Convolver).to_not receive(:convolve_fftw3)
|
|
36
|
-
c = Convolver.convolve( a, b )
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
it "should choose #convolve_fftw3 for large inputs" do
|
|
40
|
-
a = NArray.sfloat(500,500).random()
|
|
41
|
-
b = NArray.sfloat(100,100).random()
|
|
42
|
-
expect(Convolver).to receive(:convolve_fftw3).once
|
|
43
|
-
expect(Convolver).to_not receive(:convolve_basic)
|
|
44
|
-
c = Convolver.convolve( a, b )
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
end
|