annotate maths/MathUtilities.cpp @ 102:37449f085a4c

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