annotate maths/MathUtilities.h @ 194:26daede606a8

Add L^p norms, doc, tests
author Chris Cannam
date Wed, 07 Oct 2015 11:14:16 +0100
parents e4a57215ddee
children
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 #ifndef MATHUTILITIES_H
cannam@0 17 #define MATHUTILITIES_H
cannam@0 18
cannam@0 19 #include <vector>
cannam@0 20
cannam@79 21 #include "nan-inf.h"
cannam@79 22
Chris@152 23 /**
Chris@152 24 * Static helper functions for simple mathematical calculations.
Chris@152 25 */
cannam@0 26 class MathUtilities
cannam@0 27 {
cannam@0 28 public:
Chris@152 29 /**
Chris@152 30 * Round x to the nearest integer.
Chris@152 31 */
cannam@0 32 static double round( double x );
cannam@34 33
Chris@152 34 /**
Chris@152 35 * Return through min and max pointers the highest and lowest
Chris@152 36 * values in the given array of the given length.
Chris@152 37 */
Chris@189 38 static void getFrameMinMax( const double* data, int len, double* min, double* max );
cannam@34 39
Chris@152 40 /**
Chris@152 41 * Return the mean of the given array of the given length.
Chris@152 42 */
Chris@189 43 static double mean( const double* src, int len );
Chris@152 44
Chris@152 45 /**
Chris@152 46 * Return the mean of the subset of the given vector identified by
Chris@152 47 * start and count.
Chris@152 48 */
cannam@54 49 static double mean( const std::vector<double> &data,
Chris@189 50 int start, int count );
Chris@152 51
Chris@152 52 /**
Chris@152 53 * Return the sum of the values in the given array of the given
Chris@152 54 * length.
Chris@152 55 */
Chris@189 56 static double sum( const double* src, int len );
Chris@152 57
Chris@152 58 /**
Chris@152 59 * Return the median of the values in the given array of the given
Chris@152 60 * length. If the array is even in length, the returned value will
Chris@152 61 * be half-way between the two values adjacent to median.
Chris@152 62 */
Chris@189 63 static double median( const double* src, int len );
cannam@34 64
Chris@152 65 /**
Chris@152 66 * The principle argument function. Map the phase angle ang into
Chris@152 67 * the range [-pi,pi).
Chris@152 68 */
cannam@0 69 static double princarg( double ang );
Chris@152 70
Chris@152 71 /**
Chris@152 72 * Floating-point division modulus: return x % y.
Chris@152 73 */
cannam@0 74 static double mod( double x, double y);
cannam@34 75
Chris@194 76 /**
Chris@194 77 * The alpha norm is the alpha'th root of the mean alpha'th power
Chris@194 78 * magnitude. For example if alpha = 2 this corresponds to the RMS
Chris@194 79 * of the input data, and when alpha = 1 this is the mean
Chris@194 80 * magnitude.
Chris@194 81 */
Chris@189 82 static void getAlphaNorm(const double *data, int len, int alpha, double* ANorm);
Chris@194 83
Chris@194 84 /**
Chris@194 85 * The alpha norm is the alpha'th root of the mean alpha'th power
Chris@194 86 * magnitude. For example if alpha = 2 this corresponds to the RMS
Chris@194 87 * of the input data, and when alpha = 1 this is the mean
Chris@194 88 * magnitude.
Chris@194 89 */
Chris@189 90 static double getAlphaNorm(const std::vector <double> &data, int alpha );
cannam@34 91
cannam@34 92 enum NormaliseType {
cannam@34 93 NormaliseNone,
cannam@34 94 NormaliseUnitSum,
cannam@34 95 NormaliseUnitMax
cannam@34 96 };
cannam@34 97
Chris@123 98 static void normalise(double *data, int length,
Chris@123 99 NormaliseType n = NormaliseUnitMax);
cannam@34 100
Chris@123 101 static void normalise(std::vector<double> &data,
Chris@123 102 NormaliseType n = NormaliseUnitMax);
cannam@54 103
Chris@152 104 /**
Chris@194 105 * Calculate the L^p norm of a vector. Equivalent to MATLAB's
Chris@194 106 * norm(data, p).
Chris@194 107 */
Chris@194 108 static double getLpNorm(const std::vector<double> &data,
Chris@194 109 int p);
Chris@194 110
Chris@194 111 /**
Chris@194 112 * Normalise a vector by dividing through by its L^p norm. If the
Chris@194 113 * norm is below the given threshold, the unit vector for that
Chris@194 114 * norm is returned. p may be 0, in which case no normalisation
Chris@194 115 * happens and the data is returned unchanged.
Chris@194 116 */
Chris@194 117 static std::vector<double> normaliseLp(const std::vector<double> &data,
Chris@194 118 int p,
Chris@194 119 double threshold = 1e-6);
Chris@194 120
Chris@194 121 /**
Chris@152 122 * Threshold the input/output vector data against a moving-mean
Chris@152 123 * average filter.
Chris@152 124 */
cannam@54 125 static void adaptiveThreshold(std::vector<double> &data);
cannam@55 126
Chris@194 127 static void circShift( double* data, int length, int shift);
Chris@194 128
Chris@194 129 static int getMax( double* data, int length, double* max = 0 );
Chris@194 130 static int getMax( const std::vector<double> &data, double* max = 0 );
Chris@194 131 static int compareInt(const void * a, const void * b);
Chris@194 132
Chris@152 133 /**
Chris@152 134 * Return true if x is 2^n for some integer n >= 0.
Chris@152 135 */
cannam@55 136 static bool isPowerOfTwo(int x);
Chris@123 137
Chris@152 138 /**
Chris@152 139 * Return the next higher integer power of two from x, e.g. 1300
Chris@152 140 * -> 2048, 2048 -> 2048.
Chris@152 141 */
Chris@152 142 static int nextPowerOfTwo(int x);
Chris@152 143
Chris@152 144 /**
Chris@152 145 * Return the next lower integer power of two from x, e.g. 1300 ->
Chris@152 146 * 1024, 2048 -> 2048.
Chris@152 147 */
Chris@152 148 static int previousPowerOfTwo(int x);
Chris@152 149
Chris@152 150 /**
Chris@152 151 * Return the nearest integer power of two to x, e.g. 1300 -> 1024,
Chris@152 152 * 12 -> 16 (not 8; if two are equidistant, the higher is returned).
Chris@152 153 */
Chris@152 154 static int nearestPowerOfTwo(int x);
Chris@152 155
Chris@152 156 /**
Chris@152 157 * Return x!
Chris@152 158 */
Chris@135 159 static double factorial(int x); // returns double in case it is large
Chris@125 160
Chris@152 161 /**
Chris@152 162 * Return the greatest common divisor of natural numbers a and b.
Chris@152 163 */
Chris@125 164 static int gcd(int a, int b);
cannam@0 165 };
cannam@0 166
cannam@0 167 #endif