convolver 0.3.1 → 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 +28 -7
- 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 +20 -10
- data/lib/convolver/version.rb +3 -1
- data/lib/convolver.rb +41 -61
- 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 +17 -17
- metadata +23 -114
- data/.travis.yml +0 -11
- data/spec/convolve_basic_spec.rb +0 -84
- data/spec/convolve_fftw3_spec.rb +0 -161
- data/spec/convolve_spec.rb +0 -31
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'helpers'
|
|
4
|
+
|
|
5
|
+
describe Convolver do
|
|
6
|
+
describe '#convolve_fftw3' do
|
|
7
|
+
it 'works like the example in the README' do
|
|
8
|
+
a = NArray[0.3, 0.4, 0.5]
|
|
9
|
+
b = NArray[1.3, -0.5]
|
|
10
|
+
c = described_class.convolve_fftw3(a, b)
|
|
11
|
+
expect(c).to be_narray_like NArray[0.19, 0.27]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'convolves 1D arrays with a variety of signal and kernel lengths' do
|
|
15
|
+
a = NArray[0.3]
|
|
16
|
+
b = NArray[-0.7]
|
|
17
|
+
c = described_class.convolve_fftw3(a, b)
|
|
18
|
+
expect(c).to be_narray_like NArray[-0.21]
|
|
19
|
+
|
|
20
|
+
a = NArray[0.3, 0.4, 0.5, 0.2]
|
|
21
|
+
b = NArray[-0.7]
|
|
22
|
+
c = described_class.convolve_fftw3(a, b)
|
|
23
|
+
expect(c).to be_narray_like NArray[-0.21, -0.28, -0.35, -0.14]
|
|
24
|
+
|
|
25
|
+
a = NArray[0.3, 0.4, 0.5, 0.2]
|
|
26
|
+
b = NArray[1.1, -0.7]
|
|
27
|
+
c = described_class.convolve_fftw3(a, b)
|
|
28
|
+
expect(c).to be_narray_like NArray[0.05, 0.09, 0.41]
|
|
29
|
+
|
|
30
|
+
a = NArray[0.3, 0.4, 0.5, 0.2]
|
|
31
|
+
b = NArray[1.1, -0.7, -0.2]
|
|
32
|
+
c = described_class.convolve_fftw3(a, b)
|
|
33
|
+
expect(c).to be_narray_like NArray[-0.05, 0.05]
|
|
34
|
+
|
|
35
|
+
a = NArray[0.3, 0.4, 0.5, 0.2, 0.6]
|
|
36
|
+
b = NArray[1.1, -0.7]
|
|
37
|
+
c = described_class.convolve_fftw3(a, b)
|
|
38
|
+
expect(c).to be_narray_like NArray[0.05, 0.09, 0.41, -0.2]
|
|
39
|
+
|
|
40
|
+
a = NArray[0.3, 0.4, 0.5, 0.2, 0.6]
|
|
41
|
+
b = NArray[1.1, -0.7, 2.1]
|
|
42
|
+
c = described_class.convolve_fftw3(a, b)
|
|
43
|
+
expect(c).to be_narray_like NArray[1.1, 0.51, 1.67]
|
|
44
|
+
|
|
45
|
+
a = NArray[0.3, 0.4, 0.5, 0.2, 0.6]
|
|
46
|
+
b = NArray[0.6, -0.5, -0.4, 0.7]
|
|
47
|
+
c = described_class.convolve_fftw3(a, b)
|
|
48
|
+
expect(c).to be_narray_like NArray[-0.08, 0.33]
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'calculates a 2D convolution' do
|
|
52
|
+
a = NArray[[0.3, 0.4, 0.5], [0.6, 0.8, 0.2], [0.9, 1.0, 0.1]]
|
|
53
|
+
b = NArray[[1.2, -0.5], [0.5, -1.3]]
|
|
54
|
+
c = described_class.convolve_fftw3(a, b)
|
|
55
|
+
expect(c).to be_narray_like NArray[[-0.58, 0.37], [-0.53, 1.23]]
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'calculates a 3D convolution' do
|
|
59
|
+
# 5x4x3
|
|
60
|
+
a = NArray[
|
|
61
|
+
[[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],
|
|
62
|
+
[0.5, 0.9, 0.2, 0.1, 0.6]],
|
|
63
|
+
[[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],
|
|
64
|
+
[0.1, 0.9, 0.7, 0.1, 0.3]],
|
|
65
|
+
[[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],
|
|
66
|
+
[0.2, 0.5, 0.4, 0.7, 0.2]]
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
# 3x3x3
|
|
70
|
+
b = NArray[
|
|
71
|
+
[[-0.9, 1.2, 0.8], [0.9, 0.1, -0.5], [1.1, 0.1, -1.1]],
|
|
72
|
+
[[-0.2, -1.0, 1.4], [-1.4, 0.0, 1.3], [0.3, 1.0, -0.5]],
|
|
73
|
+
[[0.6, 0.0, 0.7], [-0.7, 1.1, 1.2], [1.3, 0.7, 0.0]]
|
|
74
|
+
]
|
|
75
|
+
|
|
76
|
+
# Should be 3x2x1
|
|
77
|
+
c = described_class.convolve_fftw3(a, b)
|
|
78
|
+
expect(c).to be_narray_like NArray[[[5.51, 3.04, 4.3], [3.04, 6.31, 3.87]]]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it 'calculates a 4D convolution' do
|
|
82
|
+
# 3x4x5x3
|
|
83
|
+
a = NArray[
|
|
84
|
+
[[[0.5, 0.4, 0.9], [0.1, 0.9, 0.8], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]],
|
|
85
|
+
[[0.0, 0.4, 0.0], [0.2, 0.3, 0.8], [0.6, 0.3, 0.2], [0.7, 0.4, 0.3]],
|
|
86
|
+
[[0.3, 0.3, 0.1], [0.6, 0.9, 0.4], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]],
|
|
87
|
+
[[0.0, 0.4, 0.0], [0.2, 0.3, 0.8], [0.6, 0.3, 0.2], [0.7, 0.4, 0.3]],
|
|
88
|
+
[[0.3, 0.3, 0.1], [0.6, 0.9, 0.4], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]]],
|
|
89
|
+
[[[0.5, 0.4, 0.9], [0.1, 0.9, 0.8], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]],
|
|
90
|
+
[[0.0, 0.4, 0.0], [0.2, 0.3, 0.8], [0.6, 0.3, 0.2], [0.7, 0.4, 0.3]],
|
|
91
|
+
[[0.3, 0.3, 0.1], [0.6, 0.9, 0.4], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]],
|
|
92
|
+
[[0.0, 0.4, 0.0], [0.2, 0.3, 0.8], [0.6, 0.3, 0.2], [0.7, 0.4, 0.3]],
|
|
93
|
+
[[0.3, 0.3, 0.1], [0.6, 0.9, 0.4], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]]],
|
|
94
|
+
[[[0.5, 0.4, 0.9], [0.1, 0.9, 0.8], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]],
|
|
95
|
+
[[0.0, 0.4, 0.0], [0.2, 0.3, 0.8], [0.6, 0.3, 0.2], [0.7, 0.4, 0.3]],
|
|
96
|
+
[[0.3, 0.3, 0.1], [0.6, 0.9, 0.4], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]],
|
|
97
|
+
[[0.0, 0.4, 0.0], [0.2, 0.3, 0.8], [0.6, 0.3, 0.2], [0.7, 0.4, 0.3]],
|
|
98
|
+
[[0.3, 0.3, 0.1], [0.6, 0.9, 0.4], [0.4, 0.0, 0.1], [0.8, 0.3, 0.4]]] ]
|
|
99
|
+
|
|
100
|
+
# 2x3x3x2
|
|
101
|
+
b = NArray[ [
|
|
102
|
+
[[1.1, 0.6], [1.2, 0.6], [0.8, 0.1]], [[-0.4, 0.8], [0.5, 0.4], [1.2, 0.2]],
|
|
103
|
+
[[0.8, 0.2], [0.5, 0.0], [1.4, 1.3]]
|
|
104
|
+
],
|
|
105
|
+
[[[1.1, 0.6], [1.2, 0.6], [0.8, 0.1]], [[-0.4, 0.8], [0.5, 0.4], [1.2, 0.2]],
|
|
106
|
+
[[0.8, 0.2], [0.5, 0.0], [1.4, 1.3]]] ]
|
|
107
|
+
|
|
108
|
+
# Should be 2x2x3x2
|
|
109
|
+
c = described_class.convolve_fftw3(a, b)
|
|
110
|
+
expect(c).to be_narray_like NArray[
|
|
111
|
+
[[[8.5, 8.2], [11.34, 9.68]], [[7.68, 6.56], [11.24, 7.16]], [[9.14, 6.54], [12.44, 9.2]]],
|
|
112
|
+
[[[8.5, 8.2], [11.34, 9.68]], [[7.68, 6.56], [11.24, 7.16]], [[9.14, 6.54], [12.44, 9.2]]]
|
|
113
|
+
]
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe 'compared with #convolve' do
|
|
117
|
+
it 'produces same results for 1D arrays' do
|
|
118
|
+
(1..30).each do |signal_length|
|
|
119
|
+
(1..signal_length).each do |kernel_length|
|
|
120
|
+
signal = NArray.sfloat(signal_length).random
|
|
121
|
+
kernel = NArray.sfloat(kernel_length).random
|
|
122
|
+
expect_result = described_class.convolve_basic(signal, kernel)
|
|
123
|
+
got_result = described_class.convolve_fftw3(signal, kernel)
|
|
124
|
+
expect(got_result).to be_narray_like expect_result
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it 'produces same results for 2D arrays' do
|
|
130
|
+
(3..10).each do |signal_x|
|
|
131
|
+
((signal_x - 2)..(signal_x + 2)).each do |signal_y|
|
|
132
|
+
(1..signal_x).each do |kernel_x|
|
|
133
|
+
(1..signal_y).each do |kernel_y|
|
|
134
|
+
signal = NArray.sfloat(signal_x, signal_y).random
|
|
135
|
+
kernel = NArray.sfloat(kernel_x, kernel_y).random
|
|
136
|
+
expect_result = described_class.convolve_basic(signal, kernel)
|
|
137
|
+
got_result = described_class.convolve_fftw3(signal, kernel)
|
|
138
|
+
expect(got_result).to be_narray_like expect_result
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it 'produces same results for 3D arrays' do
|
|
146
|
+
(3..5).each do |signal_x|
|
|
147
|
+
((signal_x - 2)..(signal_x + 2)).each do |signal_y|
|
|
148
|
+
((signal_x - 2)..(signal_x + 2)).each do |signal_z|
|
|
149
|
+
(1..signal_x).each do |kernel_x|
|
|
150
|
+
(1..signal_y).each do |kernel_y|
|
|
151
|
+
(1..signal_z).each do |kernel_z|
|
|
152
|
+
signal = NArray.sfloat(signal_x, signal_y, signal_z).random
|
|
153
|
+
kernel = NArray.sfloat(kernel_x, kernel_y, kernel_z).random
|
|
154
|
+
expect_result = described_class.convolve_basic(signal, kernel)
|
|
155
|
+
got_result = described_class.convolve_fftw3(signal, kernel)
|
|
156
|
+
expect(got_result).to be_narray_like expect_result
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'helpers'
|
|
4
|
+
|
|
5
|
+
describe Convolver do
|
|
6
|
+
describe '#convolve' do
|
|
7
|
+
it 'works like the example in the README' do
|
|
8
|
+
a = NArray[0.3, 0.4, 0.5]
|
|
9
|
+
b = NArray[1.3, -0.5]
|
|
10
|
+
c = described_class.convolve(a, b)
|
|
11
|
+
expect(c).to be_narray_like NArray[0.19, 0.27]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'processes convolutions of different sizes' do
|
|
15
|
+
# The variety here is to ensure all branches of optimisation algorithm
|
|
16
|
+
# are covered
|
|
17
|
+
[10, 30, 60, 90, 100, 120, 130, 150, 175, 200].each do |asize|
|
|
18
|
+
[5, 10, 12, 15, 20, 30, 40, 50].each do |bsize|
|
|
19
|
+
next unless bsize < asize
|
|
20
|
+
|
|
21
|
+
a = NArray.sfloat(asize, asize).random
|
|
22
|
+
b = NArray.sfloat(bsize, bsize).random
|
|
23
|
+
c = described_class.convolve(a, b)
|
|
24
|
+
|
|
25
|
+
# We should always match output of convolve_basic irrespective
|
|
26
|
+
# of what the optimal choice of algorithm is (larger error allowed here due to rounding)
|
|
27
|
+
expect_result = described_class.convolve_basic(a, b)
|
|
28
|
+
expect(c).to be_narray_like(expect_result, 1e-6)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'chooses #convolve_basic for small inputs' do
|
|
34
|
+
a = NArray.sfloat(50, 50).random
|
|
35
|
+
b = NArray.sfloat(10, 10).random
|
|
36
|
+
allow(described_class).to receive(:convolve_basic)
|
|
37
|
+
allow(described_class).to receive(:convolve_fftw3)
|
|
38
|
+
described_class.convolve(a, b)
|
|
39
|
+
expect(described_class).to have_received(:convolve_basic).once
|
|
40
|
+
expect(described_class).not_to have_received(:convolve_fftw3)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'chooses #convolve_fftw3 for large inputs' do
|
|
44
|
+
a = NArray.sfloat(500, 500).random
|
|
45
|
+
b = NArray.sfloat(100, 100).random
|
|
46
|
+
allow(described_class).to receive(:convolve_fftw3)
|
|
47
|
+
allow(described_class).to receive(:convolve_basic)
|
|
48
|
+
described_class.convolve(a, b)
|
|
49
|
+
expect(described_class).to have_received(:convolve_fftw3).once
|
|
50
|
+
expect(described_class).not_to have_received(:convolve_basic)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/spec/helpers.rb
CHANGED
|
@@ -1,43 +1,43 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
# convolver/spec/helpers.rb
|
|
4
|
+
require 'simplecov'
|
|
5
|
+
SimpleCov.start
|
|
6
|
+
|
|
2
7
|
require 'convolver'
|
|
3
|
-
require 'mocha/api'
|
|
4
8
|
|
|
5
9
|
# Matcher compares NArrays numerically
|
|
6
|
-
RSpec::Matchers.define :be_narray_like do |expected_narray|
|
|
10
|
+
RSpec::Matchers.define :be_narray_like do |expected_narray, mse = 1e-9|
|
|
7
11
|
match do |given|
|
|
8
12
|
@error = nil
|
|
9
|
-
if !
|
|
10
|
-
@error =
|
|
13
|
+
if !given.is_a?(NArray)
|
|
14
|
+
@error = 'Wrong class.'
|
|
11
15
|
elsif given.shape != expected_narray.shape
|
|
12
|
-
@error =
|
|
16
|
+
@error = 'Shapes are different.'
|
|
13
17
|
else
|
|
14
18
|
d = given - expected_narray
|
|
15
|
-
difference =
|
|
16
|
-
if difference >
|
|
17
|
-
@error = "Numerical difference with mean square error #{difference}"
|
|
18
|
-
end
|
|
19
|
+
difference = (d * d).sum / d.size
|
|
20
|
+
@error = "Numerical difference with mean square error #{difference}" if difference > mse
|
|
19
21
|
end
|
|
20
22
|
@given = given.clone
|
|
21
23
|
|
|
22
|
-
if @error
|
|
23
|
-
@expected = expected_narray.clone
|
|
24
|
-
end
|
|
24
|
+
@expected = expected_narray.clone if @error
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
!@error
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
failure_message do
|
|
30
30
|
"NArray does not match supplied example. #{@error}
|
|
31
31
|
Expected: #{@expected.inspect}
|
|
32
32
|
Got: #{@given.inspect}"
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
failure_message_when_negated do
|
|
36
36
|
"NArray is too close to unwanted example.
|
|
37
37
|
Unwanted: #{@given.inspect}"
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
description do |
|
|
41
|
-
|
|
40
|
+
description do |_given, _expected|
|
|
41
|
+
'numerically very close to example'
|
|
42
42
|
end
|
|
43
43
|
end
|
metadata
CHANGED
|
@@ -1,127 +1,42 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: convolver
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Neil Slater
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: narray
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - '>='
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: 0.6.0.8
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - '>='
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: 0.6.0.8
|
|
27
12
|
- !ruby/object:Gem::Dependency
|
|
28
13
|
name: fftw3
|
|
29
14
|
requirement: !ruby/object:Gem::Requirement
|
|
30
15
|
requirements:
|
|
31
|
-
- -
|
|
16
|
+
- - ">="
|
|
32
17
|
- !ruby/object:Gem::Version
|
|
33
18
|
version: '0.3'
|
|
34
19
|
type: :runtime
|
|
35
20
|
prerelease: false
|
|
36
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
22
|
requirements:
|
|
38
|
-
- -
|
|
23
|
+
- - ">="
|
|
39
24
|
- !ruby/object:Gem::Version
|
|
40
25
|
version: '0.3'
|
|
41
26
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
|
44
|
-
requirements:
|
|
45
|
-
- - '>='
|
|
46
|
-
- !ruby/object:Gem::Version
|
|
47
|
-
version: 0.8.7.2
|
|
48
|
-
type: :development
|
|
49
|
-
prerelease: false
|
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
-
requirements:
|
|
52
|
-
- - '>='
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
version: 0.8.7.2
|
|
55
|
-
- !ruby/object:Gem::Dependency
|
|
56
|
-
name: bundler
|
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
|
58
|
-
requirements:
|
|
59
|
-
- - '>='
|
|
60
|
-
- !ruby/object:Gem::Version
|
|
61
|
-
version: '1.3'
|
|
62
|
-
type: :development
|
|
63
|
-
prerelease: false
|
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
-
requirements:
|
|
66
|
-
- - '>='
|
|
67
|
-
- !ruby/object:Gem::Version
|
|
68
|
-
version: '1.3'
|
|
69
|
-
- !ruby/object:Gem::Dependency
|
|
70
|
-
name: rspec
|
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
|
72
|
-
requirements:
|
|
73
|
-
- - '>='
|
|
74
|
-
- !ruby/object:Gem::Version
|
|
75
|
-
version: 2.13.0
|
|
76
|
-
type: :development
|
|
77
|
-
prerelease: false
|
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
-
requirements:
|
|
80
|
-
- - '>='
|
|
81
|
-
- !ruby/object:Gem::Version
|
|
82
|
-
version: 2.13.0
|
|
83
|
-
- !ruby/object:Gem::Dependency
|
|
84
|
-
name: mocha
|
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
|
86
|
-
requirements:
|
|
87
|
-
- - '>='
|
|
88
|
-
- !ruby/object:Gem::Version
|
|
89
|
-
version: 0.14.0
|
|
90
|
-
type: :development
|
|
91
|
-
prerelease: false
|
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
-
requirements:
|
|
94
|
-
- - '>='
|
|
95
|
-
- !ruby/object:Gem::Version
|
|
96
|
-
version: 0.14.0
|
|
97
|
-
- !ruby/object:Gem::Dependency
|
|
98
|
-
name: rake
|
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
|
100
|
-
requirements:
|
|
101
|
-
- - '>='
|
|
102
|
-
- !ruby/object:Gem::Version
|
|
103
|
-
version: 1.9.1
|
|
104
|
-
type: :development
|
|
105
|
-
prerelease: false
|
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
-
requirements:
|
|
108
|
-
- - '>='
|
|
109
|
-
- !ruby/object:Gem::Version
|
|
110
|
-
version: 1.9.1
|
|
111
|
-
- !ruby/object:Gem::Dependency
|
|
112
|
-
name: rake-compiler
|
|
27
|
+
name: narray
|
|
113
28
|
requirement: !ruby/object:Gem::Requirement
|
|
114
29
|
requirements:
|
|
115
|
-
- -
|
|
30
|
+
- - ">="
|
|
116
31
|
- !ruby/object:Gem::Version
|
|
117
|
-
version: 0.8
|
|
118
|
-
type: :
|
|
32
|
+
version: 0.6.0.8
|
|
33
|
+
type: :runtime
|
|
119
34
|
prerelease: false
|
|
120
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
36
|
requirements:
|
|
122
|
-
- -
|
|
37
|
+
- - ">="
|
|
123
38
|
- !ruby/object:Gem::Version
|
|
124
|
-
version: 0.8
|
|
39
|
+
version: 0.6.0.8
|
|
125
40
|
description: Convolution for NArray
|
|
126
41
|
email:
|
|
127
42
|
- slobo777@gmail.com
|
|
@@ -130,8 +45,9 @@ extensions:
|
|
|
130
45
|
- ext/convolver/extconf.rb
|
|
131
46
|
extra_rdoc_files: []
|
|
132
47
|
files:
|
|
133
|
-
- .
|
|
134
|
-
- .
|
|
48
|
+
- ".github/workflows/ci.yml"
|
|
49
|
+
- ".gitignore"
|
|
50
|
+
- ".rubocop.yml"
|
|
135
51
|
- Gemfile
|
|
136
52
|
- LICENSE.txt
|
|
137
53
|
- README.md
|
|
@@ -145,37 +61,30 @@ files:
|
|
|
145
61
|
- ext/convolver/narray_shared.h
|
|
146
62
|
- lib/convolver.rb
|
|
147
63
|
- lib/convolver/version.rb
|
|
148
|
-
- spec/
|
|
149
|
-
- spec/
|
|
150
|
-
- spec/
|
|
64
|
+
- spec/convolver_basic_spec.rb
|
|
65
|
+
- spec/convolver_fftw3_spec.rb
|
|
66
|
+
- spec/convolver_spec.rb
|
|
151
67
|
- spec/helpers.rb
|
|
152
68
|
homepage: http://github.com/neilslater/convolver
|
|
153
69
|
licenses:
|
|
154
70
|
- MIT
|
|
155
|
-
metadata:
|
|
156
|
-
|
|
71
|
+
metadata:
|
|
72
|
+
rubygems_mfa_required: 'true'
|
|
157
73
|
rdoc_options: []
|
|
158
74
|
require_paths:
|
|
159
75
|
- lib
|
|
160
76
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
161
77
|
requirements:
|
|
162
|
-
- -
|
|
78
|
+
- - ">="
|
|
163
79
|
- !ruby/object:Gem::Version
|
|
164
|
-
version: '
|
|
80
|
+
version: '3.2'
|
|
165
81
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
166
82
|
requirements:
|
|
167
|
-
- -
|
|
83
|
+
- - ">="
|
|
168
84
|
- !ruby/object:Gem::Version
|
|
169
85
|
version: '0'
|
|
170
86
|
requirements: []
|
|
171
|
-
|
|
172
|
-
rubygems_version: 2.1.8
|
|
173
|
-
signing_key:
|
|
87
|
+
rubygems_version: 4.0.1
|
|
174
88
|
specification_version: 4
|
|
175
89
|
summary: Convolution for NArray
|
|
176
|
-
test_files:
|
|
177
|
-
- spec/convolve_basic_spec.rb
|
|
178
|
-
- spec/convolve_fftw3_spec.rb
|
|
179
|
-
- spec/convolve_spec.rb
|
|
180
|
-
- spec/helpers.rb
|
|
181
|
-
has_rdoc:
|
|
90
|
+
test_files: []
|
data/.travis.yml
DELETED
data/spec/convolve_basic_spec.rb
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
require 'helpers'
|
|
2
|
-
|
|
3
|
-
describe Convolver do
|
|
4
|
-
describe "#convolve_basic" 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_basic( a, b )
|
|
10
|
-
c.should be_narray_like NArray[ 0.19, 0.27 ]
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "should calculate a 2D convolution" do
|
|
14
|
-
a = NArray[ [ 0.3, 0.4, 0.5 ], [ 0.6, 0.8, 0.2 ], [ 0.9, 1.0, 0.1 ] ]
|
|
15
|
-
b = NArray[ [ 1.2, -0.5 ], [ 0.5, -1.3 ] ]
|
|
16
|
-
c = Convolver.convolve_basic( a, b )
|
|
17
|
-
c.should be_narray_like NArray[ [ -0.58, 0.37 ], [ -0.53, 1.23 ] ]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "should calculate a 2D convolution with rectangular arrays" do
|
|
21
|
-
a = NArray[ [ 0.3, 0.4, 0.5, 0.3, 0.4 ], [ 0.6, 0.8, 0.2, 0.8, 0.2 ],
|
|
22
|
-
[ 0.9, 1.0, 0.1, 0.9, 1.0 ], [ 0.5, 0.9, 0.3, 0.2, 0.8 ], [ 0.7, 0.1, 0.3, 0.0, 0.1 ],
|
|
23
|
-
[ 0.4, 0.5, 0.6, 0.7, 0.8 ], [ 0.5, 0.4, 0.3, 0.2, 0.1 ] ]
|
|
24
|
-
b = NArray[ [ 1.2, -0.5, 0.2 ], [ 1.8, 0.5, -1.3 ] ]
|
|
25
|
-
c = Convolver.convolve_basic( a, b )
|
|
26
|
-
c.should be_narray_like NArray[ [ 1.48, 0.79, 1.03 ], [ 2.35, 1.7, -0.79 ], [ 1.56, 2.84, -0.53 ],
|
|
27
|
-
[ 1.13, 1.3, 0.83 ], [ 1.04, 0.26, 0.77 ], [ 1.06, 1.05, 1.04 ] ]
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "should calculate a 3D convolution" do
|
|
31
|
-
# 5x4x3
|
|
32
|
-
a = NArray[
|
|
33
|
-
[ [ 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 ] ],
|
|
34
|
-
[ [ 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 ] ],
|
|
35
|
-
[ [ 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 ] ]
|
|
36
|
-
]
|
|
37
|
-
|
|
38
|
-
# 3x3x3
|
|
39
|
-
b = NArray[
|
|
40
|
-
[ [ -0.9, 1.2, 0.8 ], [ 0.9, 0.1, -0.5 ], [ 1.1, 0.1, -1.1 ] ],
|
|
41
|
-
[ [ -0.2, -1.0, 1.4 ], [ -1.4, 0.0, 1.3 ], [ 0.3, 1.0, -0.5 ] ],
|
|
42
|
-
[ [ 0.6, 0.0, 0.7 ], [ -0.7, 1.1, 1.2 ], [ 1.3, 0.7, 0.0 ] ]
|
|
43
|
-
]
|
|
44
|
-
|
|
45
|
-
# Should be 3x2x1
|
|
46
|
-
c = Convolver.convolve_basic( a, b )
|
|
47
|
-
c.should be_narray_like NArray[ [ [ 5.51, 3.04, 4.3 ], [ 3.04, 6.31, 3.87 ] ] ]
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "should calculate a 4D convolution" do
|
|
51
|
-
# 3x4x5x3
|
|
52
|
-
a = NArray[
|
|
53
|
-
[ [ [ 0.5, 0.4, 0.9 ], [ 0.1, 0.9, 0.8 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
54
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
55
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
56
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
57
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ] ],
|
|
58
|
-
[ [ [ 0.5, 0.4, 0.9 ], [ 0.1, 0.9, 0.8 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
59
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
60
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
61
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
62
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ] ],
|
|
63
|
-
[ [ [ 0.5, 0.4, 0.9 ], [ 0.1, 0.9, 0.8 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
64
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
65
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ],
|
|
66
|
-
[ [ 0.0, 0.4, 0.0 ], [ 0.2, 0.3, 0.8 ], [ 0.6, 0.3, 0.2 ], [ 0.7, 0.4, 0.3 ] ],
|
|
67
|
-
[ [ 0.3, 0.3, 0.1 ], [ 0.6, 0.9, 0.4 ], [ 0.4, 0.0, 0.1 ], [ 0.8, 0.3, 0.4 ] ] ] ]
|
|
68
|
-
|
|
69
|
-
# 2x3x3x2
|
|
70
|
-
b = NArray[ [
|
|
71
|
-
[ [ 1.1, 0.6 ], [ 1.2, 0.6 ], [ 0.8, 0.1 ] ], [ [ -0.4, 0.8 ], [ 0.5, 0.4 ], [ 1.2, 0.2 ] ],
|
|
72
|
-
[ [ 0.8, 0.2 ], [ 0.5, 0.0 ], [ 1.4, 1.3 ] ] ],
|
|
73
|
-
[ [ [ 1.1, 0.6 ], [ 1.2, 0.6 ], [ 0.8, 0.1 ] ], [ [ -0.4, 0.8 ], [ 0.5, 0.4 ], [ 1.2, 0.2 ] ],
|
|
74
|
-
[ [ 0.8, 0.2 ], [ 0.5, 0.0 ], [ 1.4, 1.3 ] ] ] ]
|
|
75
|
-
|
|
76
|
-
# Should be 2x2x3x2
|
|
77
|
-
c = Convolver.convolve_basic( a, b )
|
|
78
|
-
c.should be_narray_like NArray[
|
|
79
|
-
[ [ [ 8.5, 8.2 ], [ 11.34, 9.68 ] ], [ [ 7.68, 6.56 ], [ 11.24, 7.16 ] ], [ [ 9.14, 6.54 ], [ 12.44, 9.2 ] ] ],
|
|
80
|
-
[ [ [ 8.5, 8.2 ], [ 11.34, 9.68 ] ], [ [ 7.68, 6.56 ], [ 11.24, 7.16 ] ], [ [ 9.14, 6.54 ], [ 12.44, 9.2 ] ] ]
|
|
81
|
-
]
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|