Mercurial > hg > beatroot-vamp
diff Peaks.cpp @ 15:887c629502a9
refactor: pull method implementations into .cpp files
author | Chris Cannam |
---|---|
date | Wed, 12 Oct 2011 10:55:52 +0100 |
parents | 4f6626f9ffac |
children | 55969570044e |
line wrap: on
line diff
--- a/Peaks.cpp Fri Oct 07 14:07:42 2011 +0100 +++ b/Peaks.cpp Wed Oct 12 10:55:52 2011 +0100 @@ -18,3 +18,163 @@ int Peaks::pre = 3; int Peaks::post = 1; + +int Peaks::findPeaks(const vector<double> &data, vector<int> peaks, int width) { + int peakCount = 0; + int maxp = 0; + int mid = 0; + int end = data.size(); + while (mid < end) { + int i = mid - width; + if (i < 0) + i = 0; + int stop = mid + width + 1; + if (stop > data.size()) + stop = data.size(); + maxp = i; + for (i++; i < stop; i++) + if (data[i] > data[maxp]) + maxp = i; + if (maxp == mid) { + int j; + for (j = peakCount; j > 0; j--) { + if (data[maxp] <= data[peaks[j-1]]) + break; + else if (j < peaks.size()) + peaks[j] = peaks[j-1]; + } + if (j != peaks.size()) + peaks[j] = maxp; + if (peakCount != peaks.size()) + peakCount++; + } + mid++; + } + return peakCount; +} // findPeaks() + +vector<int> Peaks::findPeaks(const vector<double> &data, int width, + double threshold, double decayRate, bool isRelative) { + vector<int> peaks; + int maxp = 0; + int mid = 0; + int end = data.size(); + double av = data[0]; + while (mid < end) { + av = decayRate * av + (1 - decayRate) * data[mid]; + if (av < data[mid]) + av = data[mid]; + int i = mid - width; + if (i < 0) + i = 0; + int stop = mid + width + 1; + if (stop > data.size()) + stop = data.size(); + maxp = i; + for (i++; i < stop; i++) + if (data[i] > data[maxp]) + maxp = i; + if (maxp == mid) { + if (overThreshold(data, maxp, width, threshold, isRelative,av)){ + peaks.push_back(maxp); + } + } + mid++; + } + return peaks; +} // findPeaks() + +double Peaks::expDecayWithHold(double av, double decayRate, + const vector<double> &data, int start, int stop) { + while (start < stop) { + av = decayRate * av + (1 - decayRate) * data[start]; + if (av < data[start]) + av = data[start]; + start++; + } + return av; +} // expDecayWithHold() + +bool Peaks::overThreshold(const vector<double> &data, int index, int width, + double threshold, bool isRelative, + double av) { + if (data[index] < av) + return false; + if (isRelative) { + int iStart = index - pre * width; + if (iStart < 0) + iStart = 0; + int iStop = index + post * width; + if (iStop > data.size()) + iStop = data.size(); + double sum = 0; + int count = iStop - iStart; + while (iStart < iStop) + sum += data[iStart++]; + return (data[index] > sum / count + threshold); + } else + return (data[index] > threshold); +} // overThreshold() + +void Peaks::normalise(vector<double> &data) { + double sx = 0; + double sxx = 0; + for (int i = 0; i < data.size(); i++) { + sx += data[i]; + sxx += data[i] * data[i]; + } + double mean = sx / data.size(); + double sd = sqrt((sxx - sx * mean) / data.size()); + if (sd == 0) + sd = 1; // all data[i] == mean -> 0; avoids div by 0 + for (int i = 0; i < data.size(); i++) { + data[i] = (data[i] - mean) / sd; + } +} // normalise() + +/** Uses an n-point linear regression to estimate the slope of data. + * @param data input data + * @param hop spacing of data points + * @param n length of linear regression + * @param slope output data + */ +void Peaks::getSlope(const vector<double> &data, double hop, int n, + vector<double> &slope) { + int i = 0, j = 0; + double t; + double sx = 0, sxx = 0, sy = 0, sxy = 0; + for ( ; i < n; i++) { + t = i * hop; + sx += t; + sxx += t * t; + sy += data[i]; + sxy += t * data[i]; + } + double delta = n * sxx - sx * sx; + for ( ; j < n / 2; j++) + slope[j] = (n * sxy - sx * sy) / delta; + for ( ; j < data.size() - (n + 1) / 2; j++, i++) { + slope[j] = (n * sxy - sx * sy) / delta; + sy += data[i] - data[i - n]; + sxy += hop * (n * data[i] - sy); + } + for ( ; j < data.size(); j++) + slope[j] = (n * sxy - sx * sy) / delta; +} // getSlope() + +int Peaks::imin(const vector<double> &arr) { + int i = 0; + for (int j = 1; j < arr.size(); j++) + if (arr[j] < arr[i]) + i = j; + return i; +} // imin() + +int Peaks::imax(const vector<double> &arr) { + int i = 0; + for (int j = 1; j < arr.size(); j++) + if (arr[j] > arr[i]) + i = j; + return i; +} // imax() +