SegmentSignalPy 0.1.3__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
C DLL/DLLExport.h ADDED
@@ -0,0 +1,11 @@
1
+ #include <stdio.h>
2
+ #include "SegmentSignalFunctions.h"
3
+
4
+ extern "C"
5
+ {
6
+ // Export our function to a DLL and handle some pointer/addresses handling.
7
+ __declspec(dllexport) void SegmentSignalWrapper(double LOG[], int NSAMPS, double F, int ORDER, int ORDER1, int RMODE, int NITER, int Q[], int* NQ, double FLTLOG[], double SEGLOG[], double R[], double* C, double* D, int* NACT, int* IER)
8
+ {
9
+ SegmentSignal(LOG, NSAMPS, F, ORDER, ORDER1, RMODE, NITER, Q, *NQ, FLTLOG, SEGLOG, R, *C, *D, *NACT, *IER);
10
+ }
11
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef NOISEVARIANCEESTIMATEMETHOD_H
2
+ #define NOISEVARIANCEESTIMATEMETHOD_H
3
+
4
+ enum class NoiseVarianceEstimateMethod
5
+ {
6
+ /// <summary>Point estimate.</summary>
7
+ Point = 0,
8
+
9
+ /// <summary>Smoothed estimate.</summary>
10
+ Smoothed = 1,
11
+
12
+ /// <summary>The number of types/items in the enumeration.</summary>
13
+ Length
14
+
15
+ }; // End enum.
16
+
17
+ #endif
@@ -0,0 +1,167 @@
1
+ #include "SegmentSignal.h"
2
+ #include "NoiseVarianceEstimateMethod.h"
3
+ #include "SegmentSignalFunctions.h"
4
+ #include <vector>
5
+ #include <cmath>
6
+
7
+ using namespace std;
8
+
9
+ namespace Algorithms
10
+ {
11
+ SegmentationResults* SegmentSignal::Segment(double signal[], int signalLength, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize)
12
+ {
13
+ return Segment(signal, signalLength, threshold, jumpSequenceWindowSize, noiseVarianceWindowSize, NoiseVarianceEstimateMethod::Point, 300);
14
+ }
15
+
16
+ SegmentationResults* SegmentSignal::Segment(double signal[], int signalLength, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod)
17
+ {
18
+ return Segment(signal, signalLength, threshold, jumpSequenceWindowSize, noiseVarianceWindowSize, noiseVarianceEstimateMethod, 300);
19
+ }
20
+
21
+ SegmentationResults* SegmentSignal::Segment(double signal[], int signalLength, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod, int maxSMLRIterations)
22
+ {
23
+ // Scalars which are need for output from the call to the algorithm.
24
+ int numberOfBinaryEvents = 0;
25
+ double jumpSequenceVariance = 0;
26
+ double segmentDensity = 0;
27
+ int iterations = 0;
28
+ int error = 0;
29
+
30
+ // We seem to need to create the array in the function immediately prior to calling the unmanaged code, otherwise the garbage collector
31
+ // gets cute and moves things around, which the unmanaged code takes offense to.
32
+ //double* signalToPass = new double[signalLength];
33
+ //for (int i = 0; i < signalLength; i++)
34
+ //{
35
+ // signalToPass[i] = signal[i];
36
+ //}
37
+
38
+
39
+ // Create the output arrays. After being populated by the call to the algorithm they are grouped, stored, and returned in the SegmenationResults data structure.
40
+ int* Q = new int[signalLength]; // Binary event sequence.
41
+ double* FLTLOG = new double[signalLength]; // Filtered signal.
42
+ double* SEGLOG = new double[signalLength]; // Segmented log.
43
+ double* R = new double[signalLength]; // Noise variance.
44
+
45
+ // Function call to the C DLL.
46
+ ::SegmentSignal(signal, signalLength, threshold, jumpSequenceWindowSize, noiseVarianceWindowSize, (int)noiseVarianceEstimateMethod, maxSMLRIterations, Q, numberOfBinaryEvents, FLTLOG, SEGLOG, R, jumpSequenceVariance, segmentDensity, iterations, error);
47
+
48
+ return new SegmentationResults(signalLength, Q, numberOfBinaryEvents, FLTLOG, SEGLOG, R, jumpSequenceVariance, segmentDensity, iterations, error);
49
+ }
50
+
51
+ SegmentationResults* SegmentSignal::Segment(vector<double> signal, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize)
52
+ {
53
+ return Segment(signal, threshold, jumpSequenceWindowSize, noiseVarianceWindowSize, NoiseVarianceEstimateMethod::Point, 300);
54
+ }
55
+
56
+ SegmentationResults* SegmentSignal::Segment(vector<double> signal, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod)
57
+ {
58
+ return Segment(signal, threshold, jumpSequenceWindowSize, noiseVarianceWindowSize, noiseVarianceEstimateMethod, 300);
59
+ }
60
+
61
+ SegmentationResults* SegmentSignal::Segment(vector<double> signal, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod, int maxSMLRIterations)
62
+ {
63
+ // Scalars which are need for output from the call to the algorithm.
64
+ int numberOfBinaryEvents = 0;
65
+ double jumpSequenceVariance = 0;
66
+ double segmentDensity = 0;
67
+ int iterations = 0;
68
+ int error = 0;
69
+
70
+ int signalLength = (int)signal.size();
71
+ double* signalToPass = new double[signalLength];
72
+ for (int i = 0; i < signalLength; i++)
73
+ {
74
+ signalToPass[i] = signal[i];
75
+ }
76
+
77
+ // Create the output arrays. After being populated by the call to the algorithm they are grouped, stored, and returned in the SegmenationResults data structure.
78
+ int* Q = new int[signalLength]; // Binary event sequence.
79
+ double* FLTLOG = new double[signalLength]; // Filtered signal.
80
+ double* SEGLOG = new double[signalLength]; // Segmented log.
81
+ double* R = new double[signalLength]; // Noise variance.
82
+
83
+
84
+ int estimateMethod = (int)noiseVarianceEstimateMethod;
85
+
86
+ // Function call to the C DLL.
87
+ ::SegmentSignal(signalToPass, signalLength, threshold, jumpSequenceWindowSize, noiseVarianceWindowSize, estimateMethod, maxSMLRIterations, Q, numberOfBinaryEvents, FLTLOG, SEGLOG, R, jumpSequenceVariance, segmentDensity, iterations, error);
88
+
89
+ return new SegmentationResults(signalLength, Q, numberOfBinaryEvents, FLTLOG, SEGLOG, R, jumpSequenceVariance, segmentDensity, iterations, error);
90
+ }
91
+
92
+ vector<array<int, 2>>* SegmentSignal::FindSignificantZones(int binaryEvents[], double xData[], int signalLength, double threshold)
93
+ {
94
+ return FindSignificantZones(binaryEvents, xData, signalLength, threshold, false);
95
+ }
96
+
97
+ vector<array<int, 2>>* SegmentSignal::FindSignificantZones(int binaryEvents[], double xData[], int signalLength, double threshold, bool includeBoundaries)
98
+ {
99
+ vector<array<int, 2>>* significantZones = new vector<array<int, 2>>();
100
+
101
+ // Find the first "0" entry which will mark the beginning of a zone.
102
+ int zoneStart = FindNextZero(binaryEvents, signalLength, 0);
103
+
104
+ for (int currentIndex = zoneStart+1; currentIndex < signalLength; currentIndex++)
105
+ {
106
+ if (binaryEvents[currentIndex])
107
+ {
108
+ CheckIfValidZone(xData, threshold, includeBoundaries, significantZones, zoneStart, currentIndex-1);
109
+
110
+ // Scan for the start of the next potential section.
111
+ zoneStart = FindNextZero(binaryEvents, signalLength, currentIndex);
112
+ currentIndex = zoneStart;
113
+ }
114
+ }
115
+
116
+ // If the last entry of the binary events is zero, we need to handle the final section.
117
+ if (!binaryEvents[signalLength-1])
118
+ {
119
+ CheckIfValidZone(xData, threshold, includeBoundaries, significantZones, zoneStart, signalLength-1);
120
+ }
121
+
122
+ // When including the boundaries (includeBoundaries==true), it is possible to have added data points before the beginning of the array
123
+ // and after the end. We need to check for and, if they exist, correct them.
124
+ if (significantZones->size() > 0)
125
+ {
126
+ if ((*significantZones)[0][0] < 0)
127
+ {
128
+ (*significantZones)[0][0] = 0;
129
+ }
130
+
131
+ if ((*significantZones)[significantZones->size()-1][1] >= signalLength)
132
+ {
133
+ (*significantZones)[significantZones->size()-1][1] = signalLength-1;
134
+ }
135
+ }
136
+
137
+ return significantZones;
138
+ }
139
+
140
+ int SegmentSignal::FindNextZero(int binaryEvents[], int signalLength, int currentIndex)
141
+ {
142
+ // Find the first zero.
143
+ while (binaryEvents[currentIndex] && currentIndex < signalLength-1)
144
+ {
145
+ currentIndex++;
146
+ }
147
+ return currentIndex;
148
+ }
149
+
150
+ void SegmentSignal::CheckIfValidZone(double xData[], double threshold, bool includeBoundaries, vector<array<int, 2>>* significantZones, int startIndex, int endIndex)
151
+ {
152
+ // Check to see if the threshold is met. If it met, we will store the section
153
+ // as a significant zone. If the threshold is not met, then the zone is not long
154
+ // enough so it is ignored and we scan ahead.
155
+ if (abs(xData[endIndex] - xData[startIndex]) > threshold)
156
+ {
157
+ if (includeBoundaries)
158
+ {
159
+ significantZones->push_back({ {startIndex-1, endIndex+1} });
160
+ }
161
+ else
162
+ {
163
+ significantZones->push_back({{startIndex, endIndex}});
164
+ }
165
+ }
166
+ }
167
+ } // End namespace.
@@ -0,0 +1,195 @@
1
+ #ifndef SEGMENTSIGNAL_H
2
+ #define SEGMENTSIGNAL_H
3
+
4
+ #include "NoiseVarianceEstimateMethod.h"
5
+ #include "SegmentationResults.h"
6
+ #include <vector>
7
+ #include <array>
8
+
9
+ using namespace std;
10
+
11
+ namespace Algorithms
12
+ {
13
+ /// <summary>
14
+ /// C++ interface for the C code.
15
+ /// </summary>
16
+ class SegmentSignal
17
+ {
18
+ public:
19
+ /// <summary>
20
+ /// Segment a signal using the Maximum Likelihood Estimation of Radhakrishnan, et al, 1991. Attempts to identify regions of the signal that are
21
+ /// considered "consistent." Assumes a signal that has a state which changes only at segment boundaries. The state change can be random and the
22
+ /// noise on top of the signal is modeled as Gaussian, but not necessarily stationary.
23
+ ///
24
+ /// Assumes a point estimate of the noise variance and an upper bound of 300 on the number of Single Most Likelihood Replacement iterations.
25
+ /// </summary>
26
+ /// <param name="signal">Input signal to be segmented.</param>
27
+ /// <param name="signalLength">Input signal to be segmented.</param>
28
+ /// <param name="threshold">Segmentation threshold.</param>
29
+ /// <param name="jumpSequenceWindowSize">Length of the moving average window sized used for smoothing the input well log to arrive at an initial estimate of the jump sequence variance.</param>
30
+ /// <param name="noiseVarianceWindowSize">Length of the moving average window used for smoothing the noise variances.</param>
31
+ /// <param name="noiseVarianceEstimateMethod">
32
+ /// Noise variance estimate option.
33
+ // rmode = 0 ==> Point estimate of noise variance.
34
+ // rmode = 1 ==> Noise estimates smoothed within segments.
35
+ /// </param>
36
+ /// <returns>A SegmentationResults instance which contains the algorithm output of binary events, segmented log, filtered log, et cetera.</returns>
37
+ static SegmentationResults* Segment(double signal[], int signalLength, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize);
38
+
39
+ /// <summary>
40
+ /// Segment a signal using the Maximum Likelihood Estimation of Radhakrishnan, et al, 1991. Attempts to identify regions of the signal that are
41
+ /// considered "consistent." Assumes a signal that has a state which changes only at segment boundaries. The state change can be random and the
42
+ /// noise on top of the signal is modeled as Gaussian, but not necessarily stationary.
43
+ ///
44
+ /// Assumes an upper bound of 300 on the number of Single Most Likelihood Replacement iterations.
45
+ /// </summary>
46
+ /// <param name="signal">Input signal to be segmented.</param>
47
+ /// <param name="signalLength">Input signal to be segmented.</param>
48
+ /// <param name="threshold">Segmentation threshold.</param>
49
+ /// <param name="jumpSequenceWindowSize">Length of the moving average window sized used for smoothing the input well log to arrive at an initial estimate of the jump sequence variance.</param>
50
+ /// <param name="noiseVarianceWindowSize">Length of the moving average window used for smoothing the noise variances.</param>
51
+ /// <param name="noiseVarianceEstimateMethod">
52
+ /// Noise variance estimate option.
53
+ // rmode = 0 ==> Point estimate of noise variance.
54
+ // rmode = 1 ==> Noise estimates smoothed within segments.
55
+ /// </param>
56
+ /// <returns>A SegmentationResults instance which contains the algorithm output of binary events, segmented log, filtered log, et cetera.</returns>
57
+ static SegmentationResults* Segment(double signal[], int signalLength, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod);
58
+
59
+ /// <summary>
60
+ /// Segment a signal using the Maximum Likelihood Estimation of Radhakrishnan, et al, 1991. Attempts to identify regions of the signal that are
61
+ /// considered "consistent." Assumes a signal that has a state which changes only at segment boundaries. The state change can be random and the
62
+ /// noise on top of the signal is modeled as Gaussian, but not necessarily stationary.
63
+ /// </summary>
64
+ /// <param name="signal">Input signal to be segmented.</param>
65
+ /// <param name="signalLength">Input signal to be segmented.</param>
66
+ /// <param name="threshold">Segmentation threshold.</param>
67
+ /// <param name="jumpSequenceWindowSize">Length of the moving average window sized used for smoothing the input well log to arrive at an initial estimate of the jump sequence variance.</param>
68
+ /// <param name="noiseVarianceWindowSize">Length of the moving average window used for smoothing the noise variances.</param>
69
+ /// <param name="noiseVarianceEstimateMethod">
70
+ /// Noise variance estimate option.
71
+ // rmode = 0 ==> Point estimate of noise variance.
72
+ // rmode = 1 ==> Noise estimates smoothed within segments.
73
+ /// </param>
74
+ /// <param name="maxSMLRIterations">Upper bound on the number of Single Most Likelihood Replacement iterations.</param>
75
+ /// <returns>A SegmentationResults instance which contains the algorithm output of binary events, segmented log, filtered log, et cetera.</returns>
76
+ static SegmentationResults* Segment(double signal[], int signalLength, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod, int maxSMLRIterations);
77
+
78
+ /// <summary>
79
+ /// Segment a signal using the Maximum Likelihood Estimation of Radhakrishnan, et al, 1991. Attempts to identify regions of the signal that are
80
+ /// considered "consistent." Assumes a signal that has a state which changes only at segment boundaries. The state change can be random and the
81
+ /// noise on top of the signal is modeled as Gaussian, but not necessarily stationary.
82
+ ///
83
+ /// Assumes a point estimate of the noise variance and an upper bound of 300 on the number of Single Most Likelihood Replacement iterations.
84
+ /// </summary>
85
+ /// <param name="signal">Input signal to be segmented.</param>
86
+ /// <param name="threshold">Segmentation threshold.</param>
87
+ /// <param name="jumpSequenceWindowSize">Length of the moving average window sized used for smoothing the input well log to arrive at an initial estimate of the jump sequence variance.</param>
88
+ /// <param name="noiseVarianceWindowSize">Length of the moving average window used for smoothing the noise variances.</param>
89
+ /// <param name="noiseVarianceEstimateMethod">
90
+ /// Noise variance estimate option.
91
+ // rmode = 0 ==> Point estimate of noise variance.
92
+ // rmode = 1 ==> Noise estimates smoothed within segments.
93
+ /// </param>
94
+ /// <returns>A SegmentationResults instance which contains the algorithm output of binary events, segmented log, filtered log, et cetera.</returns>
95
+ static SegmentationResults* Segment(vector<double> signal, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize);
96
+
97
+ /// <summary>
98
+ /// Segment a signal using the Maximum Likelihood Estimation of Radhakrishnan, et al, 1991. Attempts to identify regions of the signal that are
99
+ /// considered "consistent." Assumes a signal that has a state which changes only at segment boundaries. The state change can be random and the
100
+ /// noise on top of the signal is modeled as Gaussian, but not necessarily stationary.
101
+ ///
102
+ /// Assumes an upper bound of 300 on the number of Single Most Likelihood Replacement iterations.
103
+ /// </summary>
104
+ /// <param name="signal">Input signal to be segmented.</param>
105
+ /// <param name="threshold">Segmentation threshold.</param>
106
+ /// <param name="jumpSequenceWindowSize">Length of the moving average window sized used for smoothing the input well log to arrive at an initial estimate of the jump sequence variance.</param>
107
+ /// <param name="noiseVarianceWindowSize">Length of the moving average window used for smoothing the noise variances.</param>
108
+ /// <param name="noiseVarianceEstimateMethod">
109
+ /// Noise variance estimate option.
110
+ // rmode = 0 ==> Point estimate of noise variance.
111
+ // rmode = 1 ==> Noise estimates smoothed within segments.
112
+ /// </param>
113
+ /// <returns>A SegmentationResults instance which contains the algorithm output of binary events, segmented log, filtered log, et cetera.</returns>
114
+ static SegmentationResults* Segment(vector<double> signal, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod);
115
+
116
+ /// <summary>
117
+ /// Segment a signal using the Maximum Likelihood Estimation of Radhakrishnan, et al, 1991. Attempts to identify regions of the signal that are
118
+ /// considered "consistent." Assumes a signal that has a state which changes only at segment boundaries. The state change can be random and the
119
+ /// noise on top of the signal is modeled as Gaussian, but not necessarily stationary.
120
+ /// </summary>
121
+ /// <param name="signal">Input signal to be segmented.</param>
122
+ /// <param name="threshold">Segmentation threshold.</param>
123
+ /// <param name="jumpSequenceWindowSize">Length of the moving average window sized used for smoothing the input well log to arrive at an initial estimate of the jump sequence variance.</param>
124
+ /// <param name="noiseVarianceWindowSize">Length of the moving average window used for smoothing the noise variances.</param>
125
+ /// <param name="noiseVarianceEstimateMethod">
126
+ /// Noise variance estimate option.
127
+ // rmode = 0 ==> Point estimate of noise variance.
128
+ // rmode = 1 ==> Noise estimates smoothed within segments.
129
+ /// </param>
130
+ /// <param name="maxSMLRIterations">Upper bound on the number of Single Most Likelihood Replacement iterations.</param>
131
+ /// <returns>A SegmentationResults instance which contains the algorithm output of binary events, segmented log, filtered log, et cetera.</returns>
132
+ static SegmentationResults* Segment(vector<double> signal, double threshold, int jumpSequenceWindowSize, int noiseVarianceWindowSize, NoiseVarianceEstimateMethod noiseVarianceEstimateMethod, int maxSMLRIterations);
133
+
134
+ /// <summary>
135
+ /// Creates a list of indexes which indicate where the "significant zones" are in the results of the segmentation. A significant
136
+ /// zone is defined as a region between binary events (for example 1,0,0,0,1 is a region/zone of 3) that are longer than the
137
+ /// specified threshold.
138
+ ///
139
+ /// An example use for this algorithm would to be to first run the segmentation algorithm on the log/signal to get the results, then
140
+ /// use this algorithm to find the regions of interest.
141
+ ///
142
+ /// Since a log/signal fed to the segmentation algorithm is the dependent values (y values of a plot), the independent (x values)
143
+ /// must be supplied to this algorithm to enable evaluate the "length" of each zone.
144
+ /// </summary>
145
+ /// <param name="binaryEvents">Array of binary events (1s and 0s) which specify the boundaries of each zone.</param>
146
+ /// <param name="xData">Independent values associated with the log/signal fed to the Segment algorithm and produced the SegmentationResults.</param>
147
+ /// <param name="signalLength">Input signal to be segmented.</param>
148
+ /// <param name="threshold">Length a zone must be to be consider "significant." Zones shorter than this are ignored.</param>
149
+ /// <returns>A vector of arrays of length 2 indicating the zones. Each entry in the List is a pair indicating the starting and ending index of one significant zone.</returns>
150
+ static vector<array<int, 2>>* FindSignificantZones(int binaryEvents[], double xData[], int signalLength, double threshold);
151
+
152
+ /// <summary>
153
+ /// Creates a list of indexes which indicate where the "significant zones" are in the results of the segmentation. A significant
154
+ /// zone is defined as a region between binary events (for example 1,0,0,0,1 is a region/zone of 3) that are longer than the
155
+ /// specified threshold.
156
+ ///
157
+ /// An example use for this algorithm would to be to first run the segmentation algorithm on the log/signal to get the results, then
158
+ /// use this algorithm to find the regions of interest.
159
+ ///
160
+ /// Since a log/signal fed to the segmentation algorithm is the dependent values (y values of a plot), the independent (x values)
161
+ /// must be supplied to this algorithm to enable evaluate the "length" of each zone.
162
+ /// </summary>
163
+ /// <param name="binaryEvents">Array of binary events (1s and 0s) which specify the boundaries of each zone.</param>
164
+ /// <param name="xData">Independent values associated with the log/signal fed to the Segment algorithm and produced the SegmentationResults.</param>
165
+ /// <param name="signalLength">Input signal to be segmented.</param>
166
+ /// <param name="threshold">Length a zone must be to be consider "significant." Zones shorter than this are ignored.</param>
167
+ /// <param name="includeBoundaries">If true, the end data points are added as part of the zone. Does not change how zones are found.</param>
168
+ /// <returns>A vector of arrays of length 2 indicating the zones. Each entry in the List is a pair indicating the starting and ending index of one significant zone.</returns>
169
+ static vector<array<int, 2>>* FindSignificantZones(int binaryEvents[], double xData[], int signalLength, double threshold, bool includeBoundaries);
170
+
171
+ private:
172
+ /// <summary>
173
+ /// Scans the binary events for the next zero. Helper function to FindSignificantZones.
174
+ /// </summary>
175
+ /// <param name="binaryEvents">Binary event sequence array.</param>
176
+ /// <param name="signalLength">Input signal to be segmented.</param>
177
+ /// <param name="currentIndex">Index to start scanning from.</param>
178
+ /// <returns>Index of next zero.</returns>
179
+ static int FindNextZero(int binaryEvents[], int signalLength, int currentIndex);
180
+
181
+ /// <summary>
182
+ /// Checks to see if the threshold for being a significant zone is met. If it is, it is added to the list of significant zones.
183
+ /// </summary>
184
+ /// <param name="xData">Independent values associated with the log/signal fed to the Segment algorithm and produced the SegmentationResults.</param>
185
+ /// <param name="threshold">Length a zone must be to be consider "significant." Zones shorter than this are ignored.</param>
186
+ /// <param name="includeBoundaries">If true, the end data points are added as part of the zone. Does not change how zones are found.</param>
187
+ /// <param name="significantZones">List of significant zones.</param>
188
+ /// <param name="startIndex">Starting index of zone.</param>
189
+ /// <param name="endIndex">Ending index of the zone.</param>
190
+ static void CheckIfValidZone(double xData[], double threshold, bool includeBoundaries, vector<array<int, 2>>* significantZones, int startIndex, int endIndex);
191
+
192
+ }; // End class.
193
+ } // End namespace.
194
+
195
+ #endif