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++) {