Mercurial > hg > qm-dsp
comparison maths/MathUtilities.cpp @ 123:a37635bbb2c1
Some (but not all) MathUtilities unit tests, and accompanying fixes
author | Chris Cannam |
---|---|
date | Fri, 04 Oct 2013 18:34:30 +0100 |
parents | 37449f085a4c |
children | 5351b5e9ad9f |
comparison
equal
deleted
inserted
replaced
122:2b5b37255db2 | 123:a37635bbb2c1 |
---|---|
14 */ | 14 */ |
15 | 15 |
16 #include "MathUtilities.h" | 16 #include "MathUtilities.h" |
17 | 17 |
18 #include <iostream> | 18 #include <iostream> |
19 #include <algorithm> | |
20 #include <vector> | |
19 #include <cmath> | 21 #include <cmath> |
20 | 22 |
21 | 23 |
22 double MathUtilities::mod(double x, double y) | 24 double MathUtilities::mod(double x, double y) |
23 { | 25 { |
73 return a; | 75 return a; |
74 } | 76 } |
75 | 77 |
76 double MathUtilities::round(double x) | 78 double MathUtilities::round(double x) |
77 { | 79 { |
78 double val = (double)floor(x + 0.5); | 80 if (x < 0) { |
79 | 81 return -floor(-x + 0.5); |
80 return val; | 82 } else { |
83 return floor(x + 0.5); | |
84 } | |
81 } | 85 } |
82 | 86 |
83 double MathUtilities::median(const double *src, unsigned int len) | 87 double MathUtilities::median(const double *src, unsigned int len) |
84 { | 88 { |
85 unsigned int i, j; | 89 if (len == 0) return 0; |
86 double tmp = 0.0; | 90 |
87 double tempMedian; | 91 std::vector<double> scratch; |
88 double medianVal; | 92 for (int i = 0; i < len; ++i) scratch.push_back(src[i]); |
89 | 93 std::sort(scratch.begin(), scratch.end()); |
90 double* scratch = new double[ len ];//Vector < double > sortedX = Vector < double > ( size ); | 94 |
91 | 95 int middle = len/2; |
92 for ( i = 0; i < len; i++ ) | 96 if (len % 2 == 0) { |
93 { | 97 return (scratch[middle] + scratch[middle - 1]) / 2; |
94 scratch[i] = src[i]; | 98 } else { |
95 } | 99 return scratch[middle]; |
96 | 100 } |
97 for ( i = 0; i < len - 1; i++ ) | |
98 { | |
99 for ( j = 0; j < len - 1 - i; j++ ) | |
100 { | |
101 if ( scratch[j + 1] < scratch[j] ) | |
102 { | |
103 // compare the two neighbors | |
104 tmp = scratch[j]; // swap a[j] and a[j+1] | |
105 scratch[j] = scratch[j + 1]; | |
106 scratch[j + 1] = tmp; | |
107 } | |
108 } | |
109 } | |
110 int middle; | |
111 if ( len % 2 == 0 ) | |
112 { | |
113 middle = len / 2; | |
114 tempMedian = ( scratch[middle] + scratch[middle - 1] ) / 2; | |
115 } | |
116 else | |
117 { | |
118 middle = ( int )floor( len / 2.0 ); | |
119 tempMedian = scratch[middle]; | |
120 } | |
121 | |
122 medianVal = tempMedian; | |
123 | |
124 delete [] scratch; | |
125 return medianVal; | |
126 } | 101 } |
127 | 102 |
128 double MathUtilities::sum(const double *src, unsigned int len) | 103 double MathUtilities::sum(const double *src, unsigned int len) |
129 { | 104 { |
130 unsigned int i ; | 105 unsigned int i ; |
139 } | 114 } |
140 | 115 |
141 double MathUtilities::mean(const double *src, unsigned int len) | 116 double MathUtilities::mean(const double *src, unsigned int len) |
142 { | 117 { |
143 double retVal =0.0; | 118 double retVal =0.0; |
119 | |
120 if (len == 0) return 0; | |
144 | 121 |
145 double s = sum( src, len ); | 122 double s = sum( src, len ); |
146 | 123 |
147 retVal = s / (double)len; | 124 retVal = s / (double)len; |
148 | 125 |
153 unsigned int start, | 130 unsigned int start, |
154 unsigned int count) | 131 unsigned int count) |
155 { | 132 { |
156 double sum = 0.; | 133 double sum = 0.; |
157 | 134 |
135 if (count == 0) return 0; | |
136 | |
158 for (int i = 0; i < (int)count; ++i) | 137 for (int i = 0; i < (int)count; ++i) |
159 { | 138 { |
160 sum += src[start + i]; | 139 sum += src[start + i]; |
161 } | 140 } |
162 | 141 |
363 } | 342 } |
364 | 343 |
365 bool | 344 bool |
366 MathUtilities::isPowerOfTwo(int x) | 345 MathUtilities::isPowerOfTwo(int x) |
367 { | 346 { |
368 if (x < 2) return false; | 347 if (x < 1) return false; |
369 if (x & (x-1)) return false; | 348 if (x & (x-1)) return false; |
370 return true; | 349 return true; |
371 } | 350 } |
372 | 351 |
373 int | 352 int |
374 MathUtilities::nextPowerOfTwo(int x) | 353 MathUtilities::nextPowerOfTwo(int x) |
375 { | 354 { |
376 if (isPowerOfTwo(x)) return x; | 355 if (isPowerOfTwo(x)) return x; |
356 if (x < 1) return 1; | |
377 int n = 1; | 357 int n = 1; |
378 while (x) { x >>= 1; n <<= 1; } | 358 while (x) { x >>= 1; n <<= 1; } |
379 return n; | 359 return n; |
380 } | 360 } |
381 | 361 |
382 int | 362 int |
383 MathUtilities::previousPowerOfTwo(int x) | 363 MathUtilities::previousPowerOfTwo(int x) |
384 { | 364 { |
385 if (isPowerOfTwo(x)) return x; | 365 if (isPowerOfTwo(x)) return x; |
366 if (x < 1) return 1; | |
386 int n = 1; | 367 int n = 1; |
387 x >>= 1; | 368 x >>= 1; |
388 while (x) { x >>= 1; n <<= 1; } | 369 while (x) { x >>= 1; n <<= 1; } |
389 return n; | 370 return n; |
390 } | 371 } |
391 | 372 |
392 int | 373 int |
393 MathUtilities::nearestPowerOfTwo(int x) | 374 MathUtilities::nearestPowerOfTwo(int x) |
394 { | 375 { |
395 if (isPowerOfTwo(x)) return x; | 376 if (isPowerOfTwo(x)) return x; |
396 int n0 = previousPowerOfTwo(x), n1 = nearestPowerOfTwo(x); | 377 int n0 = previousPowerOfTwo(x), n1 = nextPowerOfTwo(x); |
397 if (x - n0 < n1 - x) return n0; | 378 if (x - n0 < n1 - x) return n0; |
398 else return n1; | 379 else return n1; |
399 } | 380 } |
400 | 381 |
382 int | |
383 MathUtilities::factorial(int x) | |
384 { | |
385 if (x < 0) return 0; | |
386 int f = 1; | |
387 for (int i = 1; i <= x; ++i) { | |
388 f = f * i; | |
389 } | |
390 return f; | |
391 } | |
392 |