Mercurial > hg > qm-dsp
comparison maths/MathUtilities.cpp @ 418:d583feeeed7a
Add L^p norms, doc, tests
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 07 Oct 2015 11:14:16 +0100 |
parents | 7e8d1f26b098 |
children | fa407c1d9923 |
comparison
equal
deleted
inserted
replaced
417:fa851e147e3f | 418:d583feeeed7a |
---|---|
18 #include <iostream> | 18 #include <iostream> |
19 #include <algorithm> | 19 #include <algorithm> |
20 #include <vector> | 20 #include <vector> |
21 #include <cmath> | 21 #include <cmath> |
22 | 22 |
23 using namespace std; | |
23 | 24 |
24 double MathUtilities::mod(double x, double y) | 25 double MathUtilities::mod(double x, double y) |
25 { | 26 { |
26 double a = floor( x / y ); | 27 double a = floor( x / y ); |
27 | 28 |
54 a = ::pow( a, ( 1.0 / (double) alpha ) ); | 55 a = ::pow( a, ( 1.0 / (double) alpha ) ); |
55 | 56 |
56 *ANorm = a; | 57 *ANorm = a; |
57 } | 58 } |
58 | 59 |
59 double MathUtilities::getAlphaNorm( const std::vector <double> &data, int alpha ) | 60 double MathUtilities::getAlphaNorm( const vector <double> &data, int alpha ) |
60 { | 61 { |
61 int i; | 62 int i; |
62 int len = data.size(); | 63 int len = data.size(); |
63 double temp = 0.0; | 64 double temp = 0.0; |
64 double a=0.0; | 65 double a=0.0; |
65 | 66 |
66 for( i = 0; i < len; i++) | 67 for( i = 0; i < len; i++) |
67 { | 68 { |
68 temp = data[ i ]; | 69 temp = data[ i ]; |
69 | |
70 a += ::pow( fabs(temp), double(alpha) ); | 70 a += ::pow( fabs(temp), double(alpha) ); |
71 } | 71 } |
72 a /= ( double )len; | 72 a /= ( double )len; |
73 a = ::pow( a, ( 1.0 / (double) alpha ) ); | 73 a = ::pow( a, ( 1.0 / (double) alpha ) ); |
74 | 74 |
86 | 86 |
87 double MathUtilities::median(const double *src, int len) | 87 double MathUtilities::median(const double *src, int len) |
88 { | 88 { |
89 if (len == 0) return 0; | 89 if (len == 0) return 0; |
90 | 90 |
91 std::vector<double> scratch; | 91 vector<double> scratch; |
92 for (int i = 0; i < len; ++i) scratch.push_back(src[i]); | 92 for (int i = 0; i < len; ++i) scratch.push_back(src[i]); |
93 std::sort(scratch.begin(), scratch.end()); | 93 sort(scratch.begin(), scratch.end()); |
94 | 94 |
95 int middle = len/2; | 95 int middle = len/2; |
96 if (len % 2 == 0) { | 96 if (len % 2 == 0) { |
97 return (scratch[middle] + scratch[middle - 1]) / 2; | 97 return (scratch[middle] + scratch[middle - 1]) / 2; |
98 } else { | 98 } else { |
124 retVal = s / (double)len; | 124 retVal = s / (double)len; |
125 | 125 |
126 return retVal; | 126 return retVal; |
127 } | 127 } |
128 | 128 |
129 double MathUtilities::mean(const std::vector<double> &src, | 129 double MathUtilities::mean(const vector<double> &src, |
130 int start, | 130 int start, |
131 int count) | 131 int count) |
132 { | 132 { |
133 double sum = 0.; | 133 double sum = 0.; |
134 | 134 |
195 | 195 |
196 | 196 |
197 return index; | 197 return index; |
198 } | 198 } |
199 | 199 |
200 int MathUtilities::getMax( const std::vector<double> & data, double* pMax ) | 200 int MathUtilities::getMax( const vector<double> & data, double* pMax ) |
201 { | 201 { |
202 int index = 0; | 202 int index = 0; |
203 int i; | 203 int i; |
204 double temp = 0.0; | 204 double temp = 0.0; |
205 | 205 |
284 break; | 284 break; |
285 | 285 |
286 } | 286 } |
287 } | 287 } |
288 | 288 |
289 void MathUtilities::normalise(std::vector<double> &data, NormaliseType type) | 289 void MathUtilities::normalise(vector<double> &data, NormaliseType type) |
290 { | 290 { |
291 switch (type) { | 291 switch (type) { |
292 | 292 |
293 case NormaliseNone: return; | 293 case NormaliseNone: return; |
294 | 294 |
315 break; | 315 break; |
316 | 316 |
317 } | 317 } |
318 } | 318 } |
319 | 319 |
320 void MathUtilities::adaptiveThreshold(std::vector<double> &data) | 320 double MathUtilities::getLpNorm(const vector<double> &data, int p) |
321 { | |
322 double tot = 0.0; | |
323 for (int i = 0; i < int(data.size()); ++i) { | |
324 tot += abs(pow(data[i], p)); | |
325 } | |
326 return pow(tot, 1.0 / p); | |
327 } | |
328 | |
329 vector<double> MathUtilities::normaliseLp(const vector<double> &data, | |
330 int p, | |
331 double threshold) | |
332 { | |
333 int n = int(data.size()); | |
334 if (n == 0 || p == 0) return data; | |
335 double norm = getLpNorm(data, p); | |
336 if (norm < threshold) { | |
337 return vector<double>(n, 1.0 / pow(n, 1.0 / p)); // unit vector | |
338 } | |
339 vector<double> out(n); | |
340 for (int i = 0; i < n; ++i) { | |
341 out[i] = data[i] / norm; | |
342 } | |
343 return out; | |
344 } | |
345 | |
346 void MathUtilities::adaptiveThreshold(vector<double> &data) | |
321 { | 347 { |
322 int sz = int(data.size()); | 348 int sz = int(data.size()); |
323 if (sz == 0) return; | 349 if (sz == 0) return; |
324 | 350 |
325 std::vector<double> smoothed(sz); | 351 vector<double> smoothed(sz); |
326 | 352 |
327 int p_pre = 8; | 353 int p_pre = 8; |
328 int p_post = 7; | 354 int p_post = 7; |
329 | 355 |
330 for (int i = 0; i < sz; ++i) { | 356 for (int i = 0; i < sz; ++i) { |
331 | 357 |
332 int first = std::max(0, i - p_pre); | 358 int first = max(0, i - p_pre); |
333 int last = std::min(sz - 1, i + p_post); | 359 int last = min(sz - 1, i + p_post); |
334 | 360 |
335 smoothed[i] = mean(data, first, last - first + 1); | 361 smoothed[i] = mean(data, first, last - first + 1); |
336 } | 362 } |
337 | 363 |
338 for (int i = 0; i < sz; i++) { | 364 for (int i = 0; i < sz; i++) { |