Original: C # simple optimization of peak-seeking algorithm (including Edge peak, minimum peak, peak distance)
The principle of core peak search algorithm reference Ronny, Link: The peak of the projection curve to find,
C # Translation Principle code reference sowhat4999, Link: C # translate Findpeaks method in MATLAB
Ancestors planted trees, posterity. Thank the original author for a detailed explanation.
Here first to paste the translation code (slightly modified the sowhat4999 code in several parameters)
// Calling Methods list<Double> data = new list<double>{856 Ten317}; List<int> index = getpeaksindex (trendsign (Onediff (Constant.data)));
//First Peak Search (base peak distance of 1) algorithmPrivate Double[] Onediff (list<Double>data) { Double[] result =New Double[Data. Count-1]; for(inti =0; I < result. Length; i++) {Result[i]= Data[i +1] -Data[i]; } returnresult;}Private int[] Trendsign (Double[] data) { int[] Sign =New int[Data. Length]; for(inti =0; I < sign. Length; i++) { if(Data[i] >0) Sign[i] =1; Else if(Data[i] = =0) Sign[i] =0; ElseSign[i] =-1; } for(inti = sign. Length-1; I >=0; i--) { if(Sign[i] = =0&& i = = sign. Length-1) {Sign[i]=1; } Else if(Sign[i] = =0) { if(Sign[i +1] >=0) {Sign[i]=1; } Else{Sign[i]= -1; } } } returnSign ;}Privatelist<int> Getpeaksindex (int[] diff) {List<int> data =Newlist<int>(); for(inti =0; I! = diff. Length-1; i++) { if(Diff[i +1]-diff[i] = =-2) {data. ADD (i+1); } } returnData//equivalent to the subscript of the original array}
The above method does not take the peak distance, winger, peak situation into account, but has given us a complete idea of the future generations.
Analysis of the peak distance:
We can understand the above method as the peak distance of 1 of the peak-finding algorithm, when we need to complete the peak distance of 2 peaks, we need to determine
Data[i] is greater than data[i+1],data[i+2],data[i-1],data[i-2]
Similarly, in this way the number of points is 100000, the peak distance is 1000 of the peak, you need to do 100000 of the 1000 square operations, which obviously takes a lot of time to calculate.
We cannot change the peak distance (that is, the Power Index 1000) during the optimization process, but we can change the size of the points (that is, the base 100000). The result is a reduction of the computational amount.
The peak distance of 1 is now determined by the peak-finding method.
Data[i] is greater than data[i+1],data[i-1]
and return the index column corresponding to the peak
The peak distance is 2 o'clock, we only need to judge the contents of the index column again (only in the judgement of the peak distance of 1 to win the point, it is possible in the peak distance of 2 to win the judgment)
Data[i] is greater than data[i+2],data[i-2]
At this point you will find that the base we need to traverse is not the original 100000, but the number of peak-seeking sequences that were last returned.
//Calling Methodslist<Double> data =Newlist<Double>{ -,8, the,5,6,Ten,Ten,3,1, -,7}; //Peak Distance intDispeak =3;//the foot mark obtained when the peak distance is 1list<int> index =Getpeaksindex (Trendsign (Onediff (YAxis))); //the judgments that have been made intLevel =1; //Algorithm for extending the range range of the peak distance while(Dispeak >Level ) { level++; List<int> result =dopeakinstance (data, Index, level); Index=NULL; Index=result; }
Algorithm for extending the peak-seeking range
Private list<int> dopeakinstance (list<double> data, list<int> index, int level)
{
Equivalent to the subscript of the original array
list<int> result = new list<int> ();
for (int i = 0; i < index. Count; i++)
{
Determine if the nether and upper bounds are exceeded
if (Index[i]-level>=0&&index[i] + level < data. Count)
{
if (Data[index[i] + level] <= data[index[i] "&& data[index[i]-level] <= Data[index[i]])
{
Result. ADD (Index[i]);
}
}
}
return result;
}
Winger Situation Analysis:
Reading the above two algorithms carefully, you will find that the algorithm has an unavoidable problem such as:
The peak distance is 3, when the peak header order (point 0, point 1, point 2) cannot be compared forward, resulting in no peak calculation. Trailing points are not involved in the peak calculation because they cannot be compared backwards.
In this case, we must first understand that, because the above situation is not involved in the comparison of the order, the header has a maximum of only one peak, the tail at most only one peak.
Well, then we'll just add it, and we'll be flattered.
//Gets the maximum peak (0,dispeak) point order and (Date.countfj-dispeak,data.count) Order of the data both sides intTopIndex =0; intBottomindex = yaxis.count-1; for(inti =0; i < Dispeak; i++) { if(Yaxis[i] >=Yaxis[topindex]) {TopIndex=i; } if(yaxis[yaxis.count-1-I] >=Yaxis[bottomindex]) {Bottomindex= Yaxis.count-1-i; } } //determine if conditional search conditions are met (first backward point comparison, trailing forward point comparison, comparison of dispeak points) intNewtopindex =TopIndex; intNewbottomindex =Bottomindex; for(inti =0; I <= dispeak; i++) { if(Yaxis[topindex + i] >=Yaxis[topindex]) {Newtopindex= TopIndex +i; } if(Yaxis[bottomindex-i] >=Yaxis[bottomindex]) {Newbottomindex= Bottomindex-i; }} TopIndex=Newtopindex; Bottomindex=Newbottomindex; //add to result sequence if(TopIndex <=dispeak) {Index. Insert (0, TopIndex); } if(Bottomindex >= Xaxis.count-dispeak) {Index. ADD (Bottomindex); }
Finally, it is the simplest peak judgment. Just a little bit better than that.
//Minimum Peak intMinpeakvalue =Ten; List<int> Finalresult =Newlist<int>(); for(inti =0; I < index. Count; i++) { if(Yaxis[index[i]] >=minpeakvalue) {Finalresult. ADD (Index[i]); }} Index=NULL; Index= Finalresult;
C # Simple optimization of peak-seeking algorithm (including Edge peak, minimum peak, peak distance)