1#include "VVT-V2\peak_finder.h"
8void diff(std::vector<float> in, std::vector<float>& out)
10 out = std::vector<float>(in.size()-1);
12 for(
int i=1; i<in.size(); ++i)
13 out[i-1] = in[i] - in[i-1];
16void vectorElementsProduct(std::vector<float> a, std::vector<float> b, std::vector<float>& out)
18 out = std::vector<float>(a.size());
20 for(
int i=0; i<a.size(); ++i)
24void findIndicesLessThan(std::vector<float> in,
float threshold, std::vector<int>& indices)
26 for(
int i=0; i<in.size(); ++i)
28 indices.push_back(i+1);
31void selectElementsFromIndices(std::vector<float> in, std::vector<int> indices, std::vector<float>& out)
33 for(
int i=0; i<indices.size(); ++i)
34 out.push_back(in[indices[i]]);
37void selectElementsFromIndices(std::vector<int> in, std::vector<int> indices, std::vector<int>& out)
39 for(
int i=0; i<indices.size(); ++i)
40 out.push_back(in[indices[i]]);
43void signVector(std::vector<float> in, std::vector<int>& out)
45 out = std::vector<int>(in.size());
47 for(
int i=0; i<in.size(); ++i)
58void scalarProduct(
float scalar, std::vector<float> in, std::vector<float>& out)
60 out = std::vector<float>(in.size());
62 for(
int i=0; i<in.size(); ++i)
63 out[i] = scalar * in[i];
66void PeakFinder::findPeaks(std::vector<float> x0, std::vector<int>& peakInds,
bool includeEndpoints,
float extrema)
68 int minIdx = distance(x0.begin(), min_element(x0.begin(), x0.end()));
69 int maxIdx = distance(x0.begin(), max_element(x0.begin(), x0.end()));
71 float sel = (x0[maxIdx]-x0[minIdx])/4.0;
74 scalarProduct(extrema, x0, x0);
76 std::vector<float> 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;
83 vectorElementsProduct(dx0, dx0_1, dx0_2);
86 findIndicesLessThan(dx0_2, 0, ind);
95 selectElementsFromIndices(x0, ind, x);
96 x.insert(x.begin(), x0[0]);
97 x.insert(x.end(), x0[x0.size()-1]);
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];
108 selectElementsFromIndices(x0, ind, x);
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];
121 float tempMag = minMag;
122 bool foundPeak =
false;
130 std::vector<float> xSub0(x.begin(), x.begin()+3);
131 std::vector<float> xDiff;
134 std::vector<int> signDx;
135 signVector(xDiff, signDx);
139 if (signDx[0] == signDx[1])
141 x.erase(x.begin()+1);
142 ind.erase(ind.begin()+1);
148 if (signDx[0] == signDx[1])
151 ind.erase(ind.begin());
164 float maxPeaks = ceil((
float)len/2.0);
165 std::vector<int> peakLoc(maxPeaks,0);
166 std::vector<float> peakMag(maxPeaks,0.0);
184 if( x[ii-1] > tempMag && x[ii-1] > leftMin + sel )
197 if(!foundPeak && tempMag > sel + x[ii-1])
201 peakLoc[cInd-1] = tempLoc;
202 peakMag[cInd-1] = tempMag;
205 else if(x[ii-1] < leftMin)
213 if ( x[x.size()-1] > tempMag && x[x.size()-1] > leftMin + sel )
215 peakLoc[cInd-1] = len-1;
216 peakMag[cInd-1] = x[x.size()-1];
219 else if( !foundPeak && tempMag > minMag )
221 peakLoc[cInd-1] = tempLoc;
222 peakMag[cInd-1] = tempMag;
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 )
231 peakLoc[cInd-1] = len-1;
232 peakMag[cInd-1] = x[x.size()-1];
235 else if( !tempMag > minAux + sel)
237 peakLoc[cInd-1] = tempLoc;
238 peakMag[cInd-1] = tempMag;
246 std::vector<int> peakLocTmp(peakLoc.begin(), peakLoc.begin()+cInd-1);
247 selectElementsFromIndices(ind, peakLocTmp, peakInds);
void findPeaks(std::vector< float > x0, std::vector< int > &peakInds, bool includeEndpoints=true, float extrema=1)