67{
68 int minIdx = distance(x0.begin(), min_element(x0.begin(), x0.end()));
69 int maxIdx = distance(x0.begin(), max_element(x0.begin(), x0.end()));
70
71 float sel = (x0[maxIdx]-x0[minIdx])/4.0;
72 int len0 = x0.size();
73
74 scalarProduct(extrema, x0, x0);
75
76 std::vector<float> dx;
77 diff(x0, dx);
78 replace(dx.begin(), dx.end(), 0.0f, -PeakFinder::EPS);
79 std::vector<float> dx0(dx.begin(), dx.end()-1);
80 std::vector<float> dx0_1(dx.begin()+1, dx.end());
81 std::vector<float> dx0_2;
82
83 vectorElementsProduct(dx0, dx0_1, dx0_2);
84
85 std::vector<int> ind;
86 findIndicesLessThan(dx0_2, 0, ind);
87 std::vector<float> x;
88 float leftMin;
89 int minMagIdx;
90 float minMag;
91
92 if(includeEndpoints)
93 {
94
95 selectElementsFromIndices(x0, ind, x);
96 x.insert(x.begin(), x0[0]);
97 x.insert(x.end(), x0[x0.size()-1]);
98
99 ind.insert(ind.begin(), 1);
100 ind.insert(ind.end(), len0);
101 minMagIdx = distance(x.begin(), std::min_element(x.begin(), x.end()));
102 minMag = x[minMagIdx];
103
104 leftMin = minMag;
105 }
106 else
107 {
108 selectElementsFromIndices(x0, ind, x);
109 if(x.size()>2)
110 {
111 minMagIdx = distance(x.begin(), std::min_element(x.begin(), x.end()));
112 minMag = x[minMagIdx];
113 leftMin = x[0]<x0[0]?x[0]:x0[0];
114 }
115 }
116
117 int len = x.size();
118
119 if(len>2)
120 {
121 float tempMag = minMag;
122 bool foundPeak = false;
123 int ii;
124
125 if(includeEndpoints)
126 {
127
128
129
130 std::vector<float> xSub0(x.begin(), x.begin()+3);
131 std::vector<float> xDiff;
132 diff(xSub0, xDiff);
133
134 std::vector<int> signDx;
135 signVector(xDiff, signDx);
136
137 if (signDx[0] <= 0)
138 {
139 if (signDx[0] == signDx[1])
140 {
141 x.erase(x.begin()+1);
142 ind.erase(ind.begin()+1);
143 len = len-1;
144 }
145 }
146 else
147 {
148 if (signDx[0] == signDx[1])
149 {
150 x.erase(x.begin());
151 ind.erase(ind.begin());
152 len = len-1;
153 }
154 }
155 }
156
157
158 if ( x[0] >= x[1] )
159 ii = 0;
160 else
161 ii = 1;
162
163
164 float maxPeaks = ceil((float)len/2.0);
165 std::vector<int> peakLoc(maxPeaks,0);
166 std::vector<float> peakMag(maxPeaks,0.0);
167 int cInd = 1;
168 int tempLoc = 0;
169
170 while(ii < len)
171 {
172 ii = ii+1;
173
174
175 if(foundPeak)
176 {
177 tempMag = minMag;
178 foundPeak = false;
179 }
180
181
182
183
184 if( x[ii-1] > tempMag && x[ii-1] > leftMin + sel )
185 {
186 tempLoc = ii-1;
187 tempMag = x[ii-1];
188 }
189
190
191 if(ii == len)
192 break;
193
194 ii = ii+1;
195
196
197 if(!foundPeak && tempMag > sel + x[ii-1])
198 {
199 foundPeak = true;
200 leftMin = x[ii-1];
201 peakLoc[cInd-1] = tempLoc;
202 peakMag[cInd-1] = tempMag;
203 cInd = cInd+1;
204 }
205 else if(x[ii-1] < leftMin)
206 leftMin = x[ii-1];
207
208 }
209
210
211 if(includeEndpoints)
212 {
213 if ( x[x.size()-1] > tempMag && x[x.size()-1] > leftMin + sel )
214 {
215 peakLoc[cInd-1] = len-1;
216 peakMag[cInd-1] = x[x.size()-1];
217 cInd = cInd + 1;
218 }
219 else if( !foundPeak && tempMag > minMag )
220 {
221 peakLoc[cInd-1] = tempLoc;
222 peakMag[cInd-1] = tempMag;
223 cInd = cInd + 1;
224 }
225 }
226 else if(!foundPeak)
227 {
228 float minAux = x0[x0.size()-1]<x[x.size()-1]?x0[x0.size()-1]:x[x.size()-1];
229 if ( x[x.size()-1] > tempMag && x[x.size()-1] > leftMin + sel )
230 {
231 peakLoc[cInd-1] = len-1;
232 peakMag[cInd-1] = x[x.size()-1];
233 cInd = cInd + 1;
234 }
235 else if( !tempMag > minAux + sel)
236 {
237 peakLoc[cInd-1] = tempLoc;
238 peakMag[cInd-1] = tempMag;
239 cInd = cInd + 1;
240 }
241 }
242
243
244 if( cInd > 0 )
245 {
246 std::vector<int> peakLocTmp(peakLoc.begin(), peakLoc.begin()+cInd-1);
247 selectElementsFromIndices(ind, peakLocTmp, peakInds);
248 }
249
250 }
251
252
253
254
255}