annotate maths/MathUtilities.cpp @ 79:054c384d860d

* Solaris build fixes
author cannam
date Mon, 14 Sep 2009 13:01:44 +0000
parents d72fcd34d9a7
children e5907ae6de17
rev   line source
cannam@0 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@0 2
cannam@0 3 /*
cannam@0 4 QM DSP Library
cannam@0 5
cannam@0 6 Centre for Digital Music, Queen Mary, University of London.
cannam@0 7 This file copyright 2005-2006 Christian Landone.
cannam@0 8 All rights reserved.
cannam@0 9 */
cannam@0 10
cannam@0 11 #include "MathUtilities.h"
cannam@0 12
cannam@0 13 #include <iostream>
cannam@0 14 #include <cmath>
cannam@0 15
cannam@0 16
cannam@0 17 double MathUtilities::mod(double x, double y)
cannam@0 18 {
cannam@0 19 double a = floor( x / y );
cannam@0 20
cannam@0 21 double b = x - ( y * a );
cannam@0 22 return b;
cannam@0 23 }
cannam@0 24
cannam@0 25 double MathUtilities::princarg(double ang)
cannam@0 26 {
cannam@0 27 double ValOut;
cannam@0 28
cannam@0 29 ValOut = mod( ang + M_PI, -2 * M_PI ) + M_PI;
cannam@0 30
cannam@0 31 return ValOut;
cannam@0 32 }
cannam@0 33
cannam@0 34 void MathUtilities::getAlphaNorm(const double *data, unsigned int len, unsigned int alpha, double* ANorm)
cannam@0 35 {
cannam@0 36 unsigned int i;
cannam@0 37 double temp = 0.0;
cannam@0 38 double a=0.0;
cannam@0 39
cannam@0 40 for( i = 0; i < len; i++)
cannam@0 41 {
cannam@0 42 temp = data[ i ];
cannam@0 43
cannam@79 44 a += ::pow( fabs(temp), double(alpha) );
cannam@0 45 }
cannam@0 46 a /= ( double )len;
cannam@0 47 a = ::pow( a, ( 1.0 / (double) alpha ) );
cannam@0 48
cannam@0 49 *ANorm = a;
cannam@0 50 }
cannam@0 51
cannam@0 52 double MathUtilities::getAlphaNorm( const std::vector <double> &data, unsigned int alpha )
cannam@0 53 {
cannam@0 54 unsigned int i;
cannam@0 55 unsigned int len = data.size();
cannam@0 56 double temp = 0.0;
cannam@0 57 double a=0.0;
cannam@0 58
cannam@0 59 for( i = 0; i < len; i++)
cannam@0 60 {
cannam@0 61 temp = data[ i ];
cannam@0 62
cannam@79 63 a += ::pow( fabs(temp), double(alpha) );
cannam@0 64 }
cannam@0 65 a /= ( double )len;
cannam@0 66 a = ::pow( a, ( 1.0 / (double) alpha ) );
cannam@0 67
cannam@0 68 return a;
cannam@0 69 }
cannam@0 70
cannam@0 71 double MathUtilities::round(double x)
cannam@0 72 {
cannam@0 73 double val = (double)floor(x + 0.5);
cannam@0 74
cannam@0 75 return val;
cannam@0 76 }
cannam@0 77
cannam@0 78 double MathUtilities::median(const double *src, unsigned int len)
cannam@0 79 {
cannam@0 80 unsigned int i, j;
cannam@0 81 double tmp = 0.0;
cannam@0 82 double tempMedian;
cannam@0 83 double medianVal;
cannam@0 84
cannam@0 85 double* scratch = new double[ len ];//Vector < double > sortedX = Vector < double > ( size );
cannam@0 86
cannam@0 87 for ( i = 0; i < len; i++ )
cannam@0 88 {
cannam@0 89 scratch[i] = src[i];
cannam@0 90 }
cannam@0 91
cannam@0 92 for ( i = 0; i < len - 1; i++ )
cannam@0 93 {
cannam@0 94 for ( j = 0; j < len - 1 - i; j++ )
cannam@0 95 {
cannam@0 96 if ( scratch[j + 1] < scratch[j] )
cannam@0 97 {
cannam@0 98 // compare the two neighbors
cannam@0 99 tmp = scratch[j]; // swap a[j] and a[j+1]
cannam@0 100 scratch[j] = scratch[j + 1];
cannam@0 101 scratch[j + 1] = tmp;
cannam@0 102 }
cannam@0 103 }
cannam@0 104 }
cannam@0 105 int middle;
cannam@0 106 if ( len % 2 == 0 )
cannam@0 107 {
cannam@0 108 middle = len / 2;
cannam@0 109 tempMedian = ( scratch[middle] + scratch[middle - 1] ) / 2;
cannam@0 110 }
cannam@0 111 else
cannam@0 112 {
cannam@0 113 middle = ( int )floor( len / 2.0 );
cannam@0 114 tempMedian = scratch[middle];
cannam@0 115 }
cannam@0 116
cannam@0 117 medianVal = tempMedian;
cannam@0 118
cannam@0 119 delete [] scratch;
cannam@0 120 return medianVal;
cannam@0 121 }
cannam@0 122
cannam@0 123 double MathUtilities::sum(const double *src, unsigned int len)
cannam@0 124 {
cannam@0 125 unsigned int i ;
cannam@0 126 double retVal =0.0;
cannam@0 127
cannam@0 128 for( i = 0; i < len; i++)
cannam@0 129 {
cannam@0 130 retVal += src[ i ];
cannam@0 131 }
cannam@0 132
cannam@0 133 return retVal;
cannam@0 134 }
cannam@0 135
cannam@0 136 double MathUtilities::mean(const double *src, unsigned int len)
cannam@0 137 {
cannam@0 138 double retVal =0.0;
cannam@0 139
cannam@0 140 double s = sum( src, len );
cannam@0 141
cannam@0 142 retVal = s / (double)len;
cannam@0 143
cannam@0 144 return retVal;
cannam@0 145 }
cannam@0 146
cannam@54 147 double MathUtilities::mean(const std::vector<double> &src,
cannam@54 148 unsigned int start,
cannam@54 149 unsigned int count)
cannam@54 150 {
cannam@54 151 double sum = 0.;
cannam@54 152
cannam@54 153 for (int i = 0; i < count; ++i)
cannam@54 154 {
cannam@54 155 sum += src[start + i];
cannam@54 156 }
cannam@54 157
cannam@54 158 return sum / count;
cannam@54 159 }
cannam@54 160
cannam@0 161 void MathUtilities::getFrameMinMax(const double *data, unsigned int len, double *min, double *max)
cannam@0 162 {
cannam@0 163 unsigned int i;
cannam@0 164 double temp = 0.0;
cannam@0 165 double a=0.0;
cannam@58 166
cannam@58 167 if (len == 0) {
cannam@58 168 *min = *max = 0;
cannam@58 169 return;
cannam@58 170 }
cannam@0 171
cannam@0 172 *min = data[0];
cannam@0 173 *max = data[0];
cannam@0 174
cannam@0 175 for( i = 0; i < len; i++)
cannam@0 176 {
cannam@0 177 temp = data[ i ];
cannam@0 178
cannam@0 179 if( temp < *min )
cannam@0 180 {
cannam@0 181 *min = temp ;
cannam@0 182 }
cannam@0 183 if( temp > *max )
cannam@0 184 {
cannam@0 185 *max = temp ;
cannam@0 186 }
cannam@0 187
cannam@0 188 }
cannam@0 189 }
cannam@7 190
cannam@7 191 int MathUtilities::getMax( double* pData, unsigned int Length, double* pMax )
cannam@7 192 {
cannam@7 193 unsigned int index = 0;
cannam@7 194 unsigned int i;
cannam@7 195 double temp = 0.0;
cannam@7 196
cannam@7 197 double max = pData[0];
cannam@7 198
cannam@7 199 for( i = 0; i < Length; i++)
cannam@7 200 {
cannam@7 201 temp = pData[ i ];
cannam@7 202
cannam@7 203 if( temp > max )
cannam@7 204 {
cannam@7 205 max = temp ;
cannam@7 206 index = i;
cannam@7 207 }
cannam@7 208
cannam@7 209 }
cannam@7 210
cannam@54 211 if (pMax) *pMax = max;
cannam@54 212
cannam@54 213
cannam@54 214 return index;
cannam@54 215 }
cannam@54 216
cannam@54 217 int MathUtilities::getMax( const std::vector<double> & data, double* pMax )
cannam@54 218 {
cannam@54 219 unsigned int index = 0;
cannam@54 220 unsigned int i;
cannam@54 221 double temp = 0.0;
cannam@54 222
cannam@54 223 double max = data[0];
cannam@54 224
cannam@54 225 for( i = 0; i < data.size(); i++)
cannam@54 226 {
cannam@54 227 temp = data[ i ];
cannam@54 228
cannam@54 229 if( temp > max )
cannam@54 230 {
cannam@54 231 max = temp ;
cannam@54 232 index = i;
cannam@54 233 }
cannam@54 234
cannam@54 235 }
cannam@54 236
cannam@54 237 if (pMax) *pMax = max;
cannam@7 238
cannam@7 239
cannam@7 240 return index;
cannam@7 241 }
cannam@7 242
cannam@7 243 void MathUtilities::circShift( double* pData, int length, int shift)
cannam@7 244 {
cannam@7 245 shift = shift % length;
cannam@7 246 double temp;
cannam@7 247 int i,n;
cannam@7 248
cannam@7 249 for( i = 0; i < shift; i++)
cannam@7 250 {
cannam@7 251 temp=*(pData + length - 1);
cannam@7 252
cannam@7 253 for( n = length-2; n >= 0; n--)
cannam@7 254 {
cannam@7 255 *(pData+n+1)=*(pData+n);
cannam@7 256 }
cannam@7 257
cannam@7 258 *pData = temp;
cannam@7 259 }
cannam@7 260 }
cannam@7 261
cannam@7 262 int MathUtilities::compareInt (const void * a, const void * b)
cannam@7 263 {
cannam@7 264 return ( *(int*)a - *(int*)b );
cannam@7 265 }
cannam@7 266
cannam@34 267 void MathUtilities::normalise(double *data, int length, NormaliseType type)
cannam@34 268 {
cannam@34 269 switch (type) {
cannam@34 270
cannam@34 271 case NormaliseNone: return;
cannam@34 272
cannam@34 273 case NormaliseUnitSum:
cannam@34 274 {
cannam@34 275 double sum = 0.0;
cannam@34 276 for (int i = 0; i < length; ++i) {
cannam@34 277 sum += data[i];
cannam@34 278 }
cannam@34 279 if (sum != 0.0) {
cannam@34 280 for (int i = 0; i < length; ++i) {
cannam@34 281 data[i] /= sum;
cannam@34 282 }
cannam@34 283 }
cannam@34 284 }
cannam@34 285 break;
cannam@34 286
cannam@34 287 case NormaliseUnitMax:
cannam@34 288 {
cannam@34 289 double max = 0.0;
cannam@34 290 for (int i = 0; i < length; ++i) {
cannam@34 291 if (fabs(data[i]) > max) {
cannam@34 292 max = fabs(data[i]);
cannam@34 293 }
cannam@34 294 }
cannam@34 295 if (max != 0.0) {
cannam@34 296 for (int i = 0; i < length; ++i) {
cannam@34 297 data[i] /= max;
cannam@34 298 }
cannam@34 299 }
cannam@34 300 }
cannam@34 301 break;
cannam@34 302
cannam@34 303 }
cannam@34 304 }
cannam@34 305
cannam@34 306 void MathUtilities::normalise(std::vector<double> &data, NormaliseType type)
cannam@34 307 {
cannam@34 308 switch (type) {
cannam@34 309
cannam@34 310 case NormaliseNone: return;
cannam@34 311
cannam@34 312 case NormaliseUnitSum:
cannam@34 313 {
cannam@34 314 double sum = 0.0;
cannam@34 315 for (int i = 0; i < data.size(); ++i) sum += data[i];
cannam@34 316 if (sum != 0.0) {
cannam@34 317 for (int i = 0; i < data.size(); ++i) data[i] /= sum;
cannam@34 318 }
cannam@34 319 }
cannam@34 320 break;
cannam@34 321
cannam@34 322 case NormaliseUnitMax:
cannam@34 323 {
cannam@34 324 double max = 0.0;
cannam@34 325 for (int i = 0; i < data.size(); ++i) {
cannam@34 326 if (fabs(data[i]) > max) max = fabs(data[i]);
cannam@34 327 }
cannam@34 328 if (max != 0.0) {
cannam@34 329 for (int i = 0; i < data.size(); ++i) data[i] /= max;
cannam@34 330 }
cannam@34 331 }
cannam@34 332 break;
cannam@34 333
cannam@34 334 }
cannam@34 335 }
cannam@34 336
cannam@54 337 void MathUtilities::adaptiveThreshold(std::vector<double> &data)
cannam@54 338 {
cannam@54 339 int sz = int(data.size());
cannam@54 340 if (sz == 0) return;
cannam@54 341
cannam@54 342 std::vector<double> smoothed(sz);
cannam@54 343
cannam@54 344 int p_pre = 8;
cannam@54 345 int p_post = 7;
cannam@54 346
cannam@54 347 for (int i = 0; i < sz; ++i) {
cannam@54 348
cannam@54 349 int first = std::max(0, i - p_pre);
cannam@54 350 int last = std::min(sz - 1, i + p_post);
cannam@54 351
cannam@54 352 smoothed[i] = mean(data, first, last - first + 1);
cannam@54 353 }
cannam@54 354
cannam@54 355 for (int i = 0; i < sz; i++) {
cannam@54 356 data[i] -= smoothed[i];
cannam@54 357 if (data[i] < 0.0) data[i] = 0.0;
cannam@54 358 }
cannam@54 359 }
cannam@34 360
cannam@55 361 bool
cannam@55 362 MathUtilities::isPowerOfTwo(int x)
cannam@55 363 {
cannam@55 364 if (x < 2) return false;
cannam@55 365 if (x & (x-1)) return false;
cannam@55 366 return true;
cannam@55 367 }
cannam@55 368
cannam@55 369 int
cannam@55 370 MathUtilities::nextPowerOfTwo(int x)
cannam@55 371 {
cannam@55 372 if (isPowerOfTwo(x)) return x;
cannam@55 373 int n = 1;
cannam@55 374 while (x) { x >>= 1; n <<= 1; }
cannam@55 375 return n;
cannam@55 376 }
cannam@55 377
cannam@55 378 int
cannam@55 379 MathUtilities::previousPowerOfTwo(int x)
cannam@55 380 {
cannam@55 381 if (isPowerOfTwo(x)) return x;
cannam@55 382 int n = 1;
cannam@55 383 x >>= 1;
cannam@55 384 while (x) { x >>= 1; n <<= 1; }
cannam@55 385 return n;
cannam@55 386 }
cannam@55 387
cannam@55 388 int
cannam@55 389 MathUtilities::nearestPowerOfTwo(int x)
cannam@55 390 {
cannam@55 391 if (isPowerOfTwo(x)) return x;
cannam@55 392 int n0 = previousPowerOfTwo(x), n1 = nearestPowerOfTwo(x);
cannam@55 393 if (x - n0 < n1 - x) return n0;
cannam@55 394 else return n1;
cannam@55 395 }
cannam@55 396