Merge branch 'aybe-patch-2' of feature/vcpkg_docs
[aubio.git] / python / tests / test_specdesc.py
1 #! /usr/bin/env python
2
3 from numpy.testing import TestCase, assert_equal, assert_almost_equal
4 from numpy import random, arange, log, zeros
5 from aubio import specdesc, cvec, float_type
6
7 methods = ["default",
8      "energy",
9      "hfc",
10      "complex",
11      "phase",
12      "specdiff",
13      "kl",
14      "mkl",
15      "specflux",
16      "centroid",
17      "spread",
18      "skewness",
19      "kurtosis",
20      "slope",
21      "decrease",
22      "rolloff"]
23 buf_size = 2048
24
25 class aubio_specdesc(TestCase):
26
27     def test_members(self):
28         o = specdesc()
29
30         for method in methods:
31             o = specdesc(method, buf_size)
32             assert_equal ([o.buf_size, o.method], [buf_size, method])
33
34             spec = cvec(buf_size)
35             spec.norm[0] = 1
36             spec.norm[1] = 1./2.
37             #print "%20s" % method, str(o(spec))
38             o(spec)
39             spec.norm = random.random_sample((len(spec.norm),)).astype(float_type)
40             spec.phas = random.random_sample((len(spec.phas),)).astype(float_type)
41             #print "%20s" % method, str(o(spec))
42             assert (o(spec) != 0.)
43
44     def test_phase(self):
45         o = specdesc("phase", buf_size)
46         spec = cvec(buf_size)
47         # phase of zeros is zero
48         assert_equal (o(spec), 0.)
49         spec.phas = random.random_sample((len(spec.phas),)).astype(float_type)
50         # phase of random is not zero
51         spec.norm[:] = 1
52         assert (o(spec) != 0.)
53
54     def test_specdiff(self):
55         o = specdesc("phase", buf_size)
56         spec = cvec(buf_size)
57         # specdiff of zeros is zero
58         assert_equal (o(spec), 0.)
59         spec.phas = random.random_sample((len(spec.phas),)).astype(float_type)
60         # phase of random is not zero
61         spec.norm[:] = 1
62         assert (o(spec) != 0.)
63     
64     def test_hfc(self):
65         o = specdesc("hfc")
66         c = cvec()
67         assert_equal( 0., o(c))
68         a = arange(c.length, dtype=float_type)
69         c.norm = a
70         assert_equal (a, c.norm)
71         assert_equal ( sum(a*(a+1)), o(c))
72
73     def test_complex(self):
74         o = specdesc("complex")
75         c = cvec()
76         assert_equal( 0., o(c))
77         a = arange(c.length, dtype=float_type)
78         c.norm = a
79         assert_equal (a, c.norm)
80         # the previous run was on zeros, so previous frames are still 0
81         # so we have sqrt ( abs ( r2 ^ 2) ) == r2
82         assert_equal ( sum(a), o(c))
83         # second time. c.norm = a, so, r1 = r2, and the euclidian distance is 0
84         assert_equal ( 0, o(c))
85
86     def test_kl(self):
87         o = specdesc("kl")
88         c = cvec()
89         assert_equal( 0., o(c))
90         a = arange(c.length, dtype=float_type)
91         c.norm = a
92         assert_almost_equal( sum(a * log(1.+ a/1.e-1 ) ) / o(c), 1., decimal=6)
93
94     def test_mkl(self):
95         o = specdesc("mkl")
96         c = cvec()
97         assert_equal( 0., o(c))
98         a = arange(c.length, dtype=float_type)
99         c.norm = a
100         assert_almost_equal( sum(log(1.+ a/1.e-1 ) ) / o(c), 1, decimal=6)
101
102     def test_specflux(self):
103         o = specdesc("specflux")
104         c = cvec()
105         assert_equal( 0., o(c))
106         a = arange(c.length, dtype=float_type)
107         c.norm = a
108         assert_equal( sum(a), o(c))
109         assert_equal( 0, o(c))
110         c.norm = zeros(c.length, dtype=float_type)
111         assert_equal( 0, o(c))
112
113     def test_centroid(self):
114         o = specdesc("centroid")
115         c = cvec()
116         # make sure centroid of zeros is zero
117         assert_equal( 0., o(c))
118         a = arange(c.length, dtype=float_type)
119         c.norm = a
120         centroid = sum(a*a) / sum(a)
121         assert_almost_equal (centroid, o(c), decimal = 2)
122
123         c.norm = a * .5 
124         assert_almost_equal (centroid, o(c), decimal = 2)
125
126     def test_spread(self):
127         o = specdesc("spread")
128         c = cvec(1024)
129         ramp = arange(c.length, dtype=float_type)
130         assert_equal( 0., o(c))
131
132         a = ramp
133         c.norm = a
134         centroid = sum(a*a) / sum(a)
135         spread = sum( a * pow(ramp - centroid, 2.) ) / sum(a)
136         assert_almost_equal (o(c), spread, decimal = 1)
137
138     def test_skewness(self):
139         o = specdesc("skewness")
140         c = cvec()
141         assert_equal( 0., o(c))
142         a = arange(c.length, dtype=float_type)
143         c.norm = a
144         centroid = sum(a*a) / sum(a)
145         spread = sum( (a - centroid)**2 *a) / sum(a)
146         skewness = sum( (a - centroid)**3 *a) / sum(a) / spread **1.5
147         assert_almost_equal (skewness, o(c), decimal = 2)
148
149         c.norm = a * 3
150         assert_almost_equal (skewness, o(c), decimal = 2)
151
152     def test_kurtosis(self):
153         o = specdesc("kurtosis")
154         c = cvec()
155         assert_equal( 0., o(c))
156         a = arange(c.length, dtype=float_type)
157         c.norm = a
158         centroid = sum(a*a) / sum(a)
159         spread = sum( (a - centroid)**2 *a) / sum(a)
160         kurtosis = sum( (a - centroid)**4 *a) / sum(a) / spread **2
161         assert_almost_equal (kurtosis, o(c), decimal = 2)
162
163     def test_slope(self):
164         o = specdesc("slope")
165         c = cvec()
166         assert_equal( 0., o(c))
167         a = arange(c.length * 2, 0, -2, dtype=float_type)
168         k = arange(c.length, dtype=float_type)
169         c.norm = a
170         num = len(a) * sum(k*a) - sum(k)*sum(a)
171         den = (len(a) * sum(k**2) - sum(k)**2)
172         slope = num/den/sum(a)
173         assert_almost_equal (slope, o(c), decimal = 5)
174
175         a = arange(0, c.length * 2, +2, dtype=float_type)
176         c.norm = a
177         num = len(a) * sum(k*a) - sum(k)*sum(a)
178         den = (len(a) * sum(k**2) - sum(k)**2)
179         slope = num/den/sum(a)
180         assert_almost_equal (slope, o(c), decimal = 5)
181
182         a = arange(0, c.length * 2, +2, dtype=float_type)
183         c.norm = a * 2
184         assert_almost_equal (slope, o(c), decimal = 5)
185
186     def test_decrease(self):
187         o = specdesc("decrease")
188         c = cvec()
189         assert_equal( 0., o(c))
190         a = arange(c.length * 2, 0, -2, dtype=float_type)
191         k = arange(c.length, dtype=float_type)
192         c.norm = a
193         decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:]) 
194         assert_almost_equal (decrease, o(c), decimal = 5)
195
196         a = arange(0, c.length * 2, +2, dtype=float_type)
197         c.norm = a
198         decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:]) 
199         assert_almost_equal (decrease, o(c), decimal = 5)
200
201         a = arange(0, c.length * 2, +2, dtype=float_type)
202         c.norm = a * 2
203         decrease = sum((a[1:] - a [0]) / k[1:]) / sum(a[1:]) 
204         assert_almost_equal (decrease, o(c), decimal = 5)
205
206     def test_rolloff(self):
207         o = specdesc("rolloff")
208         c = cvec()
209         assert_equal( 0., o(c))
210         a = arange(c.length * 2, 0, -2, dtype=float_type)
211         c.norm = a
212         cumsum = .95*sum(a*a)
213         i = 0; rollsum = 0
214         while rollsum < cumsum:
215             rollsum += a[i]*a[i]
216             i+=1
217         rolloff = i 
218         assert_equal (rolloff, o(c))
219
220 class aubio_specdesc_wrong(TestCase):
221
222     def test_negative(self):
223         with self.assertRaises(ValueError):
224             specdesc("default", -10)
225
226     def test_unknown(self):
227         with self.assertRaises(RuntimeError):
228             specdesc("unknown", 512)
229
230 if __name__ == '__main__':
231     from unittest import main
232     main()