summaryrefslogtreecommitdiff
path: root/libs/qm-dsp/maths/MathUtilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/qm-dsp/maths/MathUtilities.cpp')
-rw-r--r--libs/qm-dsp/maths/MathUtilities.cpp131
1 files changed, 67 insertions, 64 deletions
diff --git a/libs/qm-dsp/maths/MathUtilities.cpp b/libs/qm-dsp/maths/MathUtilities.cpp
index a55252b365..cb35a2a7e0 100644
--- a/libs/qm-dsp/maths/MathUtilities.cpp
+++ b/libs/qm-dsp/maths/MathUtilities.cpp
@@ -16,6 +16,8 @@
#include "MathUtilities.h"
#include <iostream>
+#include <algorithm>
+#include <vector>
#include <cmath>
@@ -41,11 +43,11 @@ void MathUtilities::getAlphaNorm(const double *data, unsigned int len, unsigned
unsigned int i;
double temp = 0.0;
double a=0.0;
-
+
for( i = 0; i < len; i++)
{
temp = data[ i ];
-
+
a += ::pow( fabs(temp), double(alpha) );
}
a /= ( double )len;
@@ -60,11 +62,11 @@ double MathUtilities::getAlphaNorm( const std::vector <double> &data, unsigned i
unsigned int len = data.size();
double temp = 0.0;
double a=0.0;
-
+
for( i = 0; i < len; i++)
{
temp = data[ i ];
-
+
a += ::pow( fabs(temp), double(alpha) );
}
a /= ( double )len;
@@ -75,54 +77,27 @@ double MathUtilities::getAlphaNorm( const std::vector <double> &data, unsigned i
double MathUtilities::round(double x)
{
- double val = (double)floor(x + 0.5);
-
- return val;
+ if (x < 0) {
+ return -floor(-x + 0.5);
+ } else {
+ return floor(x + 0.5);
+ }
}
double MathUtilities::median(const double *src, unsigned int len)
{
- unsigned int i, j;
- double tmp = 0.0;
- double tempMedian;
- double medianVal;
-
- double* scratch = new double[ len ];//Vector < double > sortedX = Vector < double > ( size );
-
- for ( i = 0; i < len; i++ )
- {
- scratch[i] = src[i];
- }
-
- for ( i = 0; i < len - 1; i++ )
- {
- for ( j = 0; j < len - 1 - i; j++ )
- {
- if ( scratch[j + 1] < scratch[j] )
- {
- // compare the two neighbors
- tmp = scratch[j]; // swap a[j] and a[j+1]
- scratch[j] = scratch[j + 1];
- scratch[j + 1] = tmp;
- }
- }
- }
- int middle;
- if ( len % 2 == 0 )
- {
- middle = len / 2;
- tempMedian = ( scratch[middle] + scratch[middle - 1] ) / 2;
- }
- else
- {
- middle = ( int )floor( len / 2.0 );
- tempMedian = scratch[middle];
+ if (len == 0) return 0;
+
+ std::vector<double> scratch;
+ for (int i = 0; i < len; ++i) scratch.push_back(src[i]);
+ std::sort(scratch.begin(), scratch.end());
+
+ int middle = len/2;
+ if (len % 2 == 0) {
+ return (scratch[middle] + scratch[middle - 1]) / 2;
+ } else {
+ return scratch[middle];
}
-
- medianVal = tempMedian;
-
- delete [] scratch;
- return medianVal;
}
double MathUtilities::sum(const double *src, unsigned int len)
@@ -142,8 +117,10 @@ double MathUtilities::mean(const double *src, unsigned int len)
{
double retVal =0.0;
- double s = sum( src, len );
+ if (len == 0) return 0;
+ double s = sum( src, len );
+
retVal = s / (double)len;
return retVal;
@@ -154,8 +131,10 @@ double MathUtilities::mean(const std::vector<double> &src,
unsigned int count)
{
double sum = 0.;
-
- for (unsigned int i = 0; i < count; ++i)
+
+ if (count == 0) return 0;
+
+ for (int i = 0; i < (int)count; ++i)
{
sum += src[start + i];
}
@@ -172,7 +151,7 @@ void MathUtilities::getFrameMinMax(const double *data, unsigned int len, double
*min = *max = 0;
return;
}
-
+
*min = data[0];
*max = data[0];
@@ -188,7 +167,7 @@ void MathUtilities::getFrameMinMax(const double *data, unsigned int len, double
{
*max = temp ;
}
-
+
}
}
@@ -197,7 +176,7 @@ int MathUtilities::getMax( double* pData, unsigned int Length, double* pMax )
unsigned int index = 0;
unsigned int i;
double temp = 0.0;
-
+
double max = pData[0];
for( i = 0; i < Length; i++)
@@ -209,7 +188,7 @@ int MathUtilities::getMax( double* pData, unsigned int Length, double* pMax )
max = temp ;
index = i;
}
-
+
}
if (pMax) *pMax = max;
@@ -223,7 +202,7 @@ int MathUtilities::getMax( const std::vector<double> & data, double* pMax )
unsigned int index = 0;
unsigned int i;
double temp = 0.0;
-
+
double max = data[0];
for( i = 0; i < data.size(); i++)
@@ -235,7 +214,7 @@ int MathUtilities::getMax( const std::vector<double> & data, double* pMax )
max = temp ;
index = i;
}
-
+
}
if (pMax) *pMax = max;
@@ -265,7 +244,7 @@ void MathUtilities::circShift( double* pData, int length, int shift)
int MathUtilities::compareInt (const void * a, const void * b)
{
- return ( *(const int*)a - *(const int*)b );
+ return ( *(int*)a - *(int*)b );
}
void MathUtilities::normalise(double *data, int length, NormaliseType type)
@@ -316,9 +295,9 @@ void MathUtilities::normalise(std::vector<double> &data, NormaliseType type)
case NormaliseUnitSum:
{
double sum = 0.0;
- for (unsigned int i = 0; i < data.size(); ++i) sum += data[i];
+ for (int i = 0; i < (int)data.size(); ++i) sum += data[i];
if (sum != 0.0) {
- for (unsigned int i = 0; i < data.size(); ++i) data[i] /= sum;
+ for (int i = 0; i < (int)data.size(); ++i) data[i] /= sum;
}
}
break;
@@ -326,11 +305,11 @@ void MathUtilities::normalise(std::vector<double> &data, NormaliseType type)
case NormaliseUnitMax:
{
double max = 0.0;
- for (unsigned int i = 0; i < data.size(); ++i) {
+ for (int i = 0; i < (int)data.size(); ++i) {
if (fabs(data[i]) > max) max = fabs(data[i]);
}
if (max != 0.0) {
- for (unsigned int i = 0; i < data.size(); ++i) data[i] /= max;
+ for (int i = 0; i < (int)data.size(); ++i) data[i] /= max;
}
}
break;
@@ -344,7 +323,7 @@ void MathUtilities::adaptiveThreshold(std::vector<double> &data)
if (sz == 0) return;
std::vector<double> smoothed(sz);
-
+
int p_pre = 8;
int p_post = 7;
@@ -365,7 +344,7 @@ void MathUtilities::adaptiveThreshold(std::vector<double> &data)
bool
MathUtilities::isPowerOfTwo(int x)
{
- if (x < 2) return false;
+ if (x < 1) return false;
if (x & (x-1)) return false;
return true;
}
@@ -374,6 +353,7 @@ int
MathUtilities::nextPowerOfTwo(int x)
{
if (isPowerOfTwo(x)) return x;
+ if (x < 1) return 1;
int n = 1;
while (x) { x >>= 1; n <<= 1; }
return n;
@@ -383,6 +363,7 @@ int
MathUtilities::previousPowerOfTwo(int x)
{
if (isPowerOfTwo(x)) return x;
+ if (x < 1) return 1;
int n = 1;
x >>= 1;
while (x) { x >>= 1; n <<= 1; }
@@ -393,8 +374,30 @@ int
MathUtilities::nearestPowerOfTwo(int x)
{
if (isPowerOfTwo(x)) return x;
- int n0 = previousPowerOfTwo(x), n1 = nearestPowerOfTwo(x);
+ int n0 = previousPowerOfTwo(x), n1 = nextPowerOfTwo(x);
if (x - n0 < n1 - x) return n0;
else return n1;
}
+double
+MathUtilities::factorial(int x)
+{
+ if (x < 0) return 0;
+ double f = 1;
+ for (int i = 1; i <= x; ++i) {
+ f = f * i;
+ }
+ return f;
+}
+
+int
+MathUtilities::gcd(int a, int b)
+{
+ int c = a % b;
+ if (c == 0) {
+ return b;
+ } else {
+ return gcd(b, c);
+ }
+}
+