1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
6 Centre for Digital Music, Queen Mary, University of London.
7 This file 2005-2006 Christian Landone.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version. See the file
13 COPYING included with this distribution for more information.
16 #include "MathUtilities.h"
22 double MathUtilities::mod(double x, double y)
24 double a = floor( x / y );
26 double b = x - ( y * a );
30 double MathUtilities::princarg(double ang)
34 ValOut = mod( ang + M_PI, -2 * M_PI ) + M_PI;
39 void MathUtilities::getAlphaNorm(const double *data, unsigned int len, unsigned int alpha, double* ANorm)
45 for( i = 0; i < len; i++)
49 a += ::pow( fabs(temp), double(alpha) );
52 a = ::pow( a, ( 1.0 / (double) alpha ) );
57 double MathUtilities::getAlphaNorm( const std::vector <double> &data, unsigned int alpha )
60 unsigned int len = data.size();
64 for( i = 0; i < len; i++)
68 a += ::pow( fabs(temp), double(alpha) );
71 a = ::pow( a, ( 1.0 / (double) alpha ) );
76 double MathUtilities::round(double x)
78 double val = (double)floor(x + 0.5);
83 double MathUtilities::median(const double *src, unsigned int len)
90 double* scratch = new double[ len ];//Vector < double > sortedX = Vector < double > ( size );
92 for ( i = 0; i < len; i++ )
97 for ( i = 0; i < len - 1; i++ )
99 for ( j = 0; j < len - 1 - i; j++ )
101 if ( scratch[j + 1] < scratch[j] )
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;
114 tempMedian = ( scratch[middle] + scratch[middle - 1] ) / 2;
118 middle = ( int )floor( len / 2.0 );
119 tempMedian = scratch[middle];
122 medianVal = tempMedian;
128 double MathUtilities::sum(const double *src, unsigned int len)
133 for( i = 0; i < len; i++)
141 double MathUtilities::mean(const double *src, unsigned int len)
145 double s = sum( src, len );
147 retVal = s / (double)len;
152 double MathUtilities::mean(const std::vector<double> &src,
158 for (unsigned int i = 0; i < count; ++i)
160 sum += src[start + i];
166 void MathUtilities::getFrameMinMax(const double *data, unsigned int len, double *min, double *max)
179 for( i = 0; i < len; i++)
195 int MathUtilities::getMax( double* pData, unsigned int Length, double* pMax )
197 unsigned int index = 0;
201 double max = pData[0];
203 for( i = 0; i < Length; i++)
215 if (pMax) *pMax = max;
221 int MathUtilities::getMax( const std::vector<double> & data, double* pMax )
223 unsigned int index = 0;
227 double max = data[0];
229 for( i = 0; i < data.size(); i++)
241 if (pMax) *pMax = max;
247 void MathUtilities::circShift( double* pData, int length, int shift)
249 shift = shift % length;
253 for( i = 0; i < shift; i++)
255 temp=*(pData + length - 1);
257 for( n = length-2; n >= 0; n--)
259 *(pData+n+1)=*(pData+n);
266 int MathUtilities::compareInt (const void * a, const void * b)
268 return ( *(const int*)a - *(const int*)b );
271 void MathUtilities::normalise(double *data, int length, NormaliseType type)
275 case NormaliseNone: return;
277 case NormaliseUnitSum:
280 for (int i = 0; i < length; ++i) {
284 for (int i = 0; i < length; ++i) {
291 case NormaliseUnitMax:
294 for (int i = 0; i < length; ++i) {
295 if (fabs(data[i]) > max) {
300 for (int i = 0; i < length; ++i) {
310 void MathUtilities::normalise(std::vector<double> &data, NormaliseType type)
314 case NormaliseNone: return;
316 case NormaliseUnitSum:
319 for (unsigned int i = 0; i < data.size(); ++i) sum += data[i];
321 for (unsigned int i = 0; i < data.size(); ++i) data[i] /= sum;
326 case NormaliseUnitMax:
329 for (unsigned int i = 0; i < data.size(); ++i) {
330 if (fabs(data[i]) > max) max = fabs(data[i]);
333 for (unsigned int i = 0; i < data.size(); ++i) data[i] /= max;
341 void MathUtilities::adaptiveThreshold(std::vector<double> &data)
343 int sz = int(data.size());
346 std::vector<double> smoothed(sz);
351 for (int i = 0; i < sz; ++i) {
353 int first = std::max(0, i - p_pre);
354 int last = std::min(sz - 1, i + p_post);
356 smoothed[i] = mean(data, first, last - first + 1);
359 for (int i = 0; i < sz; i++) {
360 data[i] -= smoothed[i];
361 if (data[i] < 0.0) data[i] = 0.0;
366 MathUtilities::isPowerOfTwo(int x)
368 if (x < 2) return false;
369 if (x & (x-1)) return false;
374 MathUtilities::nextPowerOfTwo(int x)
376 if (isPowerOfTwo(x)) return x;
378 while (x) { x >>= 1; n <<= 1; }
383 MathUtilities::previousPowerOfTwo(int x)
385 if (isPowerOfTwo(x)) return x;
388 while (x) { x >>= 1; n <<= 1; }
393 MathUtilities::nearestPowerOfTwo(int x)
395 if (isPowerOfTwo(x)) return x;
396 int n0 = previousPowerOfTwo(x), n1 = nearestPowerOfTwo(x);
397 if (x - n0 < n1 - x) return n0;