comparison 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
comparison
equal deleted inserted replaced
14:f1252b6a7cf5 15:887c629502a9
16 #include "Peaks.h" 16 #include "Peaks.h"
17 17
18 int Peaks::pre = 3; 18 int Peaks::pre = 3;
19 int Peaks::post = 1; 19 int Peaks::post = 1;
20 20
21
22 int Peaks::findPeaks(const vector<double> &data, vector<int> peaks, int width) {
23 int peakCount = 0;
24 int maxp = 0;
25 int mid = 0;
26 int end = data.size();
27 while (mid < end) {
28 int i = mid - width;
29 if (i < 0)
30 i = 0;
31 int stop = mid + width + 1;
32 if (stop > data.size())
33 stop = data.size();
34 maxp = i;
35 for (i++; i < stop; i++)
36 if (data[i] > data[maxp])
37 maxp = i;
38 if (maxp == mid) {
39 int j;
40 for (j = peakCount; j > 0; j--) {
41 if (data[maxp] <= data[peaks[j-1]])
42 break;
43 else if (j < peaks.size())
44 peaks[j] = peaks[j-1];
45 }
46 if (j != peaks.size())
47 peaks[j] = maxp;
48 if (peakCount != peaks.size())
49 peakCount++;
50 }
51 mid++;
52 }
53 return peakCount;
54 } // findPeaks()
55
56 vector<int> Peaks::findPeaks(const vector<double> &data, int width,
57 double threshold, double decayRate, bool isRelative) {
58 vector<int> peaks;
59 int maxp = 0;
60 int mid = 0;
61 int end = data.size();
62 double av = data[0];
63 while (mid < end) {
64 av = decayRate * av + (1 - decayRate) * data[mid];
65 if (av < data[mid])
66 av = data[mid];
67 int i = mid - width;
68 if (i < 0)
69 i = 0;
70 int stop = mid + width + 1;
71 if (stop > data.size())
72 stop = data.size();
73 maxp = i;
74 for (i++; i < stop; i++)
75 if (data[i] > data[maxp])
76 maxp = i;
77 if (maxp == mid) {
78 if (overThreshold(data, maxp, width, threshold, isRelative,av)){
79 peaks.push_back(maxp);
80 }
81 }
82 mid++;
83 }
84 return peaks;
85 } // findPeaks()
86
87 double Peaks::expDecayWithHold(double av, double decayRate,
88 const vector<double> &data, int start, int stop) {
89 while (start < stop) {
90 av = decayRate * av + (1 - decayRate) * data[start];
91 if (av < data[start])
92 av = data[start];
93 start++;
94 }
95 return av;
96 } // expDecayWithHold()
97
98 bool Peaks::overThreshold(const vector<double> &data, int index, int width,
99 double threshold, bool isRelative,
100 double av) {
101 if (data[index] < av)
102 return false;
103 if (isRelative) {
104 int iStart = index - pre * width;
105 if (iStart < 0)
106 iStart = 0;
107 int iStop = index + post * width;
108 if (iStop > data.size())
109 iStop = data.size();
110 double sum = 0;
111 int count = iStop - iStart;
112 while (iStart < iStop)
113 sum += data[iStart++];
114 return (data[index] > sum / count + threshold);
115 } else
116 return (data[index] > threshold);
117 } // overThreshold()
118
119 void Peaks::normalise(vector<double> &data) {
120 double sx = 0;
121 double sxx = 0;
122 for (int i = 0; i < data.size(); i++) {
123 sx += data[i];
124 sxx += data[i] * data[i];
125 }
126 double mean = sx / data.size();
127 double sd = sqrt((sxx - sx * mean) / data.size());
128 if (sd == 0)
129 sd = 1; // all data[i] == mean -> 0; avoids div by 0
130 for (int i = 0; i < data.size(); i++) {
131 data[i] = (data[i] - mean) / sd;
132 }
133 } // normalise()
134
135 /** Uses an n-point linear regression to estimate the slope of data.
136 * @param data input data
137 * @param hop spacing of data points
138 * @param n length of linear regression
139 * @param slope output data
140 */
141 void Peaks::getSlope(const vector<double> &data, double hop, int n,
142 vector<double> &slope) {
143 int i = 0, j = 0;
144 double t;
145 double sx = 0, sxx = 0, sy = 0, sxy = 0;
146 for ( ; i < n; i++) {
147 t = i * hop;
148 sx += t;
149 sxx += t * t;
150 sy += data[i];
151 sxy += t * data[i];
152 }
153 double delta = n * sxx - sx * sx;
154 for ( ; j < n / 2; j++)
155 slope[j] = (n * sxy - sx * sy) / delta;
156 for ( ; j < data.size() - (n + 1) / 2; j++, i++) {
157 slope[j] = (n * sxy - sx * sy) / delta;
158 sy += data[i] - data[i - n];
159 sxy += hop * (n * data[i] - sy);
160 }
161 for ( ; j < data.size(); j++)
162 slope[j] = (n * sxy - sx * sy) / delta;
163 } // getSlope()
164
165 int Peaks::imin(const vector<double> &arr) {
166 int i = 0;
167 for (int j = 1; j < arr.size(); j++)
168 if (arr[j] < arr[i])
169 i = j;
170 return i;
171 } // imin()
172
173 int Peaks::imax(const vector<double> &arr) {
174 int i = 0;
175 for (int j = 1; j < arr.size(); j++)
176 if (arr[j] > arr[i])
177 i = j;
178 return i;
179 } // imax()
180