c@241: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ c@241: c@241: /* c@241: QM DSP Library c@241: c@241: Centre for Digital Music, Queen Mary, University of London. c@309: This file 2005-2006 Christian Landone. c@309: c@309: This program is free software; you can redistribute it and/or c@309: modify it under the terms of the GNU General Public License as c@309: published by the Free Software Foundation; either version 2 of the c@309: License, or (at your option) any later version. See the file c@309: COPYING included with this distribution for more information. c@241: */ c@241: c@241: #ifndef MATHUTILITIES_H c@241: #define MATHUTILITIES_H c@241: c@241: #include c@241: c@304: #include "nan-inf.h" c@304: c@377: /** c@377: * Static helper functions for simple mathematical calculations. c@377: */ c@241: class MathUtilities c@241: { cannam@477: public: c@377: /** c@377: * Round x to the nearest integer. c@377: */ c@241: static double round( double x ); c@259: c@377: /** c@377: * Return through min and max pointers the highest and lowest c@377: * values in the given array of the given length. c@377: */ cannam@477: static void getFrameMinMax( const double* data, int len, cannam@477: double* min, double* max ); c@259: c@377: /** c@377: * Return the mean of the given array of the given length. c@377: */ c@414: static double mean( const double* src, int len ); c@377: c@377: /** c@377: * Return the mean of the subset of the given vector identified by c@377: * start and count. c@377: */ c@279: static double mean( const std::vector &data, c@414: int start, int count ); c@377: c@377: /** c@377: * Return the sum of the values in the given array of the given c@377: * length. c@377: */ c@414: static double sum( const double* src, int len ); c@377: c@377: /** c@377: * Return the median of the values in the given array of the given c@377: * length. If the array is even in length, the returned value will c@377: * be half-way between the two values adjacent to median. c@377: */ c@414: static double median( const double* src, int len ); c@259: c@377: /** c@377: * The principle argument function. Map the phase angle ang into c@377: * the range [-pi,pi). c@377: */ c@241: static double princarg( double ang ); c@377: c@377: /** c@377: * Floating-point division modulus: return x % y. c@377: */ c@241: static double mod( double x, double y); c@259: c@418: /** c@418: * The alpha norm is the alpha'th root of the mean alpha'th power c@418: * magnitude. For example if alpha = 2 this corresponds to the RMS c@418: * of the input data, and when alpha = 1 this is the mean c@418: * magnitude. c@418: */ cannam@477: static void getAlphaNorm(const double *data, int len, int alpha, double* ANorm); c@418: c@418: /** c@418: * The alpha norm is the alpha'th root of the mean alpha'th power c@418: * magnitude. For example if alpha = 2 this corresponds to the RMS c@418: * of the input data, and when alpha = 1 this is the mean c@418: * magnitude. c@418: */ c@414: static double getAlphaNorm(const std::vector &data, int alpha ); c@259: c@259: enum NormaliseType { c@259: NormaliseNone, c@259: NormaliseUnitSum, c@259: NormaliseUnitMax c@259: }; c@259: c@348: static void normalise(double *data, int length, c@348: NormaliseType n = NormaliseUnitMax); c@259: c@348: static void normalise(std::vector &data, c@348: NormaliseType n = NormaliseUnitMax); c@279: c@377: /** c@418: * Calculate the L^p norm of a vector. Equivalent to MATLAB's c@418: * norm(data, p). c@418: */ c@418: static double getLpNorm(const std::vector &data, c@418: int p); c@418: c@418: /** c@418: * Normalise a vector by dividing through by its L^p norm. If the c@418: * norm is below the given threshold, the unit vector for that c@418: * norm is returned. p may be 0, in which case no normalisation c@418: * happens and the data is returned unchanged. c@418: */ c@418: static std::vector normaliseLp(const std::vector &data, c@418: int p, c@418: double threshold = 1e-6); c@418: c@418: /** c@377: * Threshold the input/output vector data against a moving-mean c@377: * average filter. c@377: */ c@279: static void adaptiveThreshold(std::vector &data); c@280: cannam@477: static void circShift( double* data, int length, int shift); c@418: cannam@477: static int getMax( double* data, int length, double* max = 0 ); cannam@477: static int getMax( const std::vector &data, double* max = 0 ); cannam@477: static int compareInt(const void * a, const void * b); c@418: c@377: /** c@377: * Return true if x is 2^n for some integer n >= 0. c@377: */ c@280: static bool isPowerOfTwo(int x); c@348: c@377: /** c@377: * Return the next higher integer power of two from x, e.g. 1300 c@377: * -> 2048, 2048 -> 2048. c@377: */ c@377: static int nextPowerOfTwo(int x); c@377: c@377: /** c@377: * Return the next lower integer power of two from x, e.g. 1300 -> c@377: * 1024, 2048 -> 2048. c@377: */ c@377: static int previousPowerOfTwo(int x); c@377: c@377: /** c@377: * Return the nearest integer power of two to x, e.g. 1300 -> 1024, c@377: * 12 -> 16 (not 8; if two are equidistant, the higher is returned). c@377: */ c@377: static int nearestPowerOfTwo(int x); c@377: c@377: /** c@377: * Return x! c@377: */ c@360: static double factorial(int x); // returns double in case it is large c@350: c@377: /** c@377: * Return the greatest common divisor of natural numbers a and b. c@377: */ c@350: static int gcd(int a, int b); c@241: }; c@241: c@241: #endif