public static void DoFilterMonotony(this TableFunction tableFunction) { int length = tableFunction.X.Length; double lastXStart = tableFunction.X[0]; Monotony lastMonotony = CheckMonotony(tableFunction.Y[0], tableFunction.Y[1]); Monotony monotony = lastMonotony; for (int i = 2; i < length; i++) { monotony = CheckMonotony(tableFunction.Y[i - 1], tableFunction.Y[i]); if (lastMonotony == monotony) { continue; } else { tableFunction.cutsMonotonies.Add(new CutMomotony(lastXStart, tableFunction.X[i - 1], lastMonotony)); lastMonotony = monotony; lastXStart = tableFunction.X[i]; } } tableFunction.cutsMonotonies.Add(new CutMomotony(lastXStart, tableFunction.X[length - 1], lastMonotony)); }
/// <summary> /// Clasifies an extreme point acording to monotony /// </summary> /// <param name="previous">Monotony of the previous interval</param> /// <param name="current">Monotony of the current interval</param> /// <returns>Extreme point type</returns> private static ExtremeType GetExtremeType(Monotony previous, Monotony current) { if (previous == Monotony.Grow && current == Monotony.Stable || previous == Monotony.Grow && current == Monotony.Abate || previous == Monotony.Stable && current == Monotony.Abate) { return(ExtremeType.Max); } if (previous == Monotony.Abate && current == Monotony.Stable || previous == Monotony.Abate && current == Monotony.Grow || previous == Monotony.Stable && current == Monotony.Grow) { return(ExtremeType.Min); } return(ExtremeType.None); }
/// <summary> /// Finds peaks and valleys in certain histogram /// </summary> /// <param name="histogram">Histogram involved</param> /// <returns>Histogram's peaks and valleys</returns> /// <remarks>Does not perform histogram normalization</remarks> public static KeyValuePair <List <KeyValuePair <int, int> >, List <KeyValuePair <int, int> > > HistFind(double[] histogram) { // using var because static types are so darn long var peaks = new List <KeyValuePair <int, int> >(); var valleys = new List <KeyValuePair <int, int> >(); var result = new KeyValuePair <List <KeyValuePair <int, int> >, List <KeyValuePair <int, int> > >(peaks, valleys); // setting interval size int dx = Dx; // this is because there's always point shared betwwen intervals int offset = dx - 1; // there can not exist peaks or valleys (there's at most one interval) if (dx < 2 || histogram.Length < 2 * offset + 1) { return(result); } // setting the smoothness of the curve int smoothness = Smoothness; // Ip: previous interval (Ip = [a, b]) // Ic: current interval (Ic = [b, c]) int a = 0; int b = offset; int c = b + offset; // analyzing Ip monotony Monotony ip_monotony = FindMonotony(histogram[a], histogram[b], dx); // setting previous extreme point ExtremeType previous_extreme = ExtremeType.None; int previous_extreme_index = 1; if (ip_monotony == Monotony.Abate) { previous_extreme = ExtremeType.Max; } else if (ip_monotony == Monotony.Grow) { previous_extreme = ExtremeType.Min; } // setting current extreme point ExtremeType current_extreme = ExtremeType.None; int current_extreme_index = 0; // setting the first extreme point of the last registered shift ExtremeType previous_shift_extreme = ExtremeType.None; int previous_shift_extreme_index = 0; // while the current interval is in range while (c < histogram.Length) { // analyzing the monotony in Ic Monotony ic_monotony = FindMonotony(histogram[b], histogram[c], dx); // if there was a change in the monotony => there's a extreme if (ip_monotony != ic_monotony) { // classifying the new extreme founded current_extreme = GetExtremeType(ip_monotony, ic_monotony); current_extreme_index = b; // if there was a shift indeed if (current_extreme != previous_extreme /*&& previous_extreme != ExtremeType.None*/) { // if this is not the first shift and phenomenon is smooth enough if (previous_shift_extreme != ExtremeType.None && (current_extreme_index - previous_shift_extreme_index) / dx >= smoothness) { // we are in the presence of a VALLEY if (previous_shift_extreme == ExtremeType.Max && current_extreme == ExtremeType.Max) { valleys.Add(new KeyValuePair <int, int>(previous_shift_extreme_index, current_extreme_index)); } // we are in the presence of a PEAK else if (previous_shift_extreme == ExtremeType.Min && current_extreme == ExtremeType.Min) { peaks.Add(new KeyValuePair <int, int>(previous_shift_extreme_index, current_extreme_index)); } } // update previous shift extreme previous_shift_extreme = previous_extreme; previous_shift_extreme_index = previous_extreme_index; } // updating previous extreme point previous_extreme = current_extreme; previous_extreme_index = current_extreme_index; } // updating intervals a = b; b = c; c += offset; // updating last interval monotony ip_monotony = ic_monotony; } return(result); }
public CutMomotony(double xStart, double xEnd, Monotony monotony) { this.xStart = xStart; this.xEnd = xEnd; this.monotony = monotony; }