Mercurial > hg > beatroot-vamp
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 |