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