convolver 0.3.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.
@@ -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
- expect( c ).to 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
- expect( c ).to 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
- expect( c ).to 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
- expect( c ).to 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
- expect( c ).to 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
@@ -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
@@ -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
data/spec/helpers.rb DELETED
@@ -1,46 +0,0 @@
1
- # convolver/spec/helpers.rb
2
- require 'coveralls'
3
-
4
- Coveralls.wear!
5
-
6
- require 'convolver'
7
-
8
- # Matcher compares NArrays numerically
9
- RSpec::Matchers.define :be_narray_like do |expected_narray, mse = 1e-9|
10
- match do |given|
11
- @error = nil
12
- if ! given.is_a?(NArray)
13
- @error = "Wrong class."
14
- elsif given.shape != expected_narray.shape
15
- @error = "Shapes are different."
16
- else
17
- d = given - expected_narray
18
- difference = ( d * d ).sum / d.size
19
- if difference > mse
20
- @error = "Numerical difference with mean square error #{difference}"
21
- end
22
- end
23
- @given = given.clone
24
-
25
- if @error
26
- @expected = expected_narray.clone
27
- end
28
-
29
- ! @error
30
- end
31
-
32
- failure_message do
33
- "NArray does not match supplied example. #{@error}
34
- Expected: #{@expected.inspect}
35
- Got: #{@given.inspect}"
36
- end
37
-
38
- failure_message_when_negated do
39
- "NArray is too close to unwanted example.
40
- Unwanted: #{@given.inspect}"
41
- end
42
-
43
- description do |given, expected|
44
- "numerically very close to example"
45
- end
46
- end