Esempio n. 1
0
        public HypothesisTest GetHypothesisTestResult()
        {
            // We are comparing the mean of sample means for a significant difference between the distributions

            // H0: there is no difference in the distribution of packets between marked and unmarked batches
            // H1: there is a difference between the batches

            /*******************************************************************************************
             *
             * Note: we need a test to verify that the following data (DisplayStatistic) has been updated
             *
             *******************************************************************************************/
            HypothesisTest ht = new HypothesisTest();
            //// Update the K-S statistics object
            //_KsStatistics.MarkedMean = markedMeanOfMeans;
            //_KsStatistics.MarkedStdDev = markedStdDevMeanOfMeans;
            ////_KsStatistics.MarkedMean = markedCumulativeStats.PacketCountMean;
            ////_KsStatistics.MarkedStdDev = markedCumulativeStats.PacketCountStandardDeviation;
            //_KsStatistics.MarkedIntervalCount = TrimIntervals == true ? markedCumulativeStats.IntervalCountTrimmed : markedCumulativeStats.IntervalCount;
            //_KsStatistics.UnmarkedMean = unmarkedMeanOfMeans;
            //_KsStatistics.UnmarkedStdDev = unmarkedStdDevMeanOfMeans;
            ////_KsStatistics.UnmarkedMean = unmarkedCumulativeStats.PacketCountMean;
            ////_KsStatistics.UnmarkedStdDev = unmarkedCumulativeStats.PacketCountStandardDeviation;
            //_KsStatistics.UnmarkedIntervalCount = TrimIntervals == true ? unmarkedCumulativeStats.IntervalCountTrimmed : unmarkedCumulativeStats.IntervalCount;

            ProcessCapturePackets pcp = new ProcessCapturePackets();
            DisplayStatistic markedStatistics = new DisplayStatistic();
            DisplayStatistic unmarkedStatistics = new DisplayStatistic();
            markedStatistics = pcp.GetCumulativeMarkedDisplayStatistics();
            unmarkedStatistics = pcp.GetCumulativeUnmarkedDisplayStatistics();

            MeansTestStatistic _MeansTestStatistic = new MeansTestStatistic(AnalysisConfiguration.Alpha, AnalysisConfiguration.Zvalue);
            if (markedStatistics != null)
            {
                _MeansTestStatistic.MarkedMean = markedStatistics.MeanOfMeans;
                _MeansTestStatistic.MarkedStdDev = markedStatistics.MeanOfMeansStandardDeviation;
                _MeansTestStatistic.MarkedIntervalCount = _TrimZeroPacketIntervals == true ? markedStatistics.TrimmedIntervalCount : markedStatistics.IntervalCount;
            }
            if (unmarkedStatistics != null)
            {
                _MeansTestStatistic.UnmarkedMean = unmarkedStatistics.MeanOfMeans;
                _MeansTestStatistic.UnmarkedStdDev = unmarkedStatistics.MeanOfMeansStandardDeviation;
                _MeansTestStatistic.UnmarkedIntervalCount = _TrimZeroPacketIntervals == true ? unmarkedStatistics.TrimmedIntervalCount : unmarkedStatistics.IntervalCount;
            }

            // Test the difference in the distribution means
            decimal meanDifference = _MeansTestStatistic.MeanDifference;
            decimal sigmaDifference = _MeansTestStatistic.SigmaDifference;

            // Single-tail test (if there is a difference in the means it will be a positive value)
            // Z value for alpha = 5% significance level:

            // Test result: true = reject H0 - difference of means has only 5% probability of occurring if H0 is true
            // Note: standard deviation = SigmaDifference * Zvalue
            ht.MeansTestResult = _MeansTestStatistic.MeanDifference > _MeansTestStatistic.StandardDeviation ? true : false;
            ht.MeansVarianceStandardDeviation = _MeansTestStatistic.StandardDeviation;
            ht.MeanOfMeansVariance = _MeansTestStatistic.MeanDifference;

            return ht;
        }
Esempio n. 2
0
        public void CalculateHypothesisTestResults()
        {
            // Only perform these calculations if files have been processed and a pair of files (marked and unmarked) are available

            bool IsDirty = false;
            bool HasValues = false;
            HypothesisTest ht = new HypothesisTest();
            ProcessCapturePackets pcp = new ProcessCapturePackets();
            int markedFileCount = pcp.GetProcessedFilesCountMarked();
            int unmarkedFileCount = pcp.GetProcessedFilesCountUnmarked();

            ht = pcp.GetHypothesisTestResults();
            if (ht != null)
            {
                HasValues = ht.HasValues;
            }

            //if (markedFileCount >= 1 && unmarkedFileCount >= 1 && (markedFileCount + unmarkedFileCount) % 2 == 0)
            if (markedFileCount >= 1 && unmarkedFileCount >= 1)
            {
                // Get mean of means test results
                HypothesisTest htMeans = new HypothesisTest();
                //htMeans = GetMeansHypothesisTestResult();
                MeansHypothesisTest mht = new MeansHypothesisTest(_TrimZeroPacketIntervals);
                htMeans = mht.GetHypothesisTestResult();
                ht.MeansTestResult = htMeans.MeansTestResult;
                ht.MeanOfMeansVariance = htMeans.MeanOfMeansVariance;
                ht.MeansVarianceStandardDeviation = htMeans.MeansVarianceStandardDeviation;

                if(AnalysisConfiguration.HypothesisTestType == HypothesisTestType.MeansTest && htMeans.MeansTestResult)
                {
                    AnalysisConfiguration.FoundCoresidentVm = true;
                }
                else
                {
                    AnalysisConfiguration.FoundCoresidentVm = false;
                }

                if (AnalysisConfiguration.HypothesisTestType == HypothesisTestType.KsTestStep)
                {
                    // Get the K-S test results (using step function between probability data points)
                    HypothesisTest htKsStep = new HypothesisTest();
                    //htKsStep = GetKsStepHypothesisTestResult();
                    KsStepHypothesisTest ksht = new KsStepHypothesisTest();
                    htKsStep = ksht.GetHypothesisTestResult();
                    ht.KsStatistic = htKsStep.KsStatistic;
                    ht.MaxCpdVariance = htKsStep.MaxCpdVariance;
                    ht.KsTestResult = htKsStep.KsTestResult;
                    ht.HasValues = true;
                    IsDirty = true;

                    if(htKsStep.KsTestResult)
                    {
                        AnalysisConfiguration.FoundCoresidentVm = true;
                    }
                    else
                    {
                        AnalysisConfiguration.FoundCoresidentVm = false;
                    }
                }
                //else
                else if(AnalysisConfiguration.HypothesisTestType == HypothesisTestType.KsTestLinear)
                {
                    // Default: Get the K-S test results (using linear extrapolation between probability data points)
                    HypothesisTest htKsLinear = new HypothesisTest();
                    //htKsLinear = GetKsLinearHypothesisTestResult();
                    KsLinearHypothesisTest klht = new KsLinearHypothesisTest();
                    htKsLinear = klht.GetHypothesisTestResult();
                    ht.KsStatistic = htKsLinear.KsStatistic;
                    ht.MaxCpdVariance = htKsLinear.MaxCpdVariance;
                    ht.KsTestResult = htKsLinear.KsTestResult;
                    ht.HasValues = true;
                    IsDirty = true;

                    if (htKsLinear.KsTestResult)
                    {
                        AnalysisConfiguration.FoundCoresidentVm = true;
                    }
                    else
                    {
                        AnalysisConfiguration.FoundCoresidentVm = false;
                    }
                }
            }
            else if(!HasValues)
            {
                // Default values - only if we haven't previously calculated hypothesis test results
                ht.MeanOfMeansVariance = 0;
                ht.MeansVarianceStandardDeviation = 0;
                ht.MeansTestResult = false;
                ht.KsTestResult = false;
                ht.HasValues = false;
                IsDirty = true;
            }

            if (IsDirty)
            {
                // Save the test results
                pcp.DeleteHypothesisTestResults();
                pcp.InsertHypothesisTestResults(ht);
            }
        }
Esempio n. 3
0
        private void RefreshKsStatistics()
        {
            // Reset the backcolor for Reject H0? cell in K-S column of grid
            _AnalysisDataGridView.Rows[8].Cells[7].Style.BackColor = Color.White;

            //bool KS_result = GetHypothesisTestResult(_KsStatistics.UnmarkedMean, _KsStatistics.MarkedMean, _KsStatistics.UnmarkedStdDev, _KsStatistics.MarkedStdDev, _KsStatistics.UnmarkedIntervalCount, _KsStatistics.MarkedIntervalCount);
            //bool KS_result = GetHypothesisTestResult(_KsStatistics.UnmarkedMean, _KsStatistics.MarkedMean, _KsStatistics.UnmarkedStdDev, _KsStatistics.MarkedStdDev, _KsStatistics.UnmarkedIntervalCount, _KsStatistics.MarkedIntervalCount);

            ProcessCapturePackets pcp = new ProcessCapturePackets();
            HypothesisTest ht = new HypothesisTest();

            ht = pcp.GetHypothesisTestResults();

            int row = 0;
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = string.Format("{0:N2}", ht.MaxCpdVariance);
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = string.Format("{0:N2}", ht.KsStatistic);
            _AnalysisDataGridView.Rows[row++].Cells[7].Value = string.Format("{0:P1}", AnalysisConfiguration.Alpha);
            Font font = new Font(_AnalysisDataGridView.DefaultCellStyle.Font.FontFamily, _AnalysisDataGridView.Font.Size, FontStyle.Bold);
            _AnalysisDataGridView.Rows[row].Cells[7].Style.Font = font;
            _AnalysisDataGridView.Rows[row].Cells[7].Value = ht.KsTestResult.ToString();
            _AnalysisDataGridView.Rows[row].Cells[7].Style.BackColor = ht.KsTestResult == true ? Color.LightGreen : Color.LightCoral;
        }
Esempio n. 4
0
        private void RefreshCumulativeBatchStatistics()
        {
            // Get the cumulative interval counts
            ProcessCapturePackets pcp = new ProcessCapturePackets();
            //BindingList<CumulativeInterval> cumulativeIntervals = new BindingList<CumulativeInterval>();
            //cumulativeIntervals = pcp.GetCumulativeIntervals();

            //// Get the batch intervals
            //BindingList<BatchIntervalMarked> unmarkedBatchIntervals = new BindingList<BatchIntervalMarked>();
            //BindingList<BatchIntervalMarked> markedBatchIntervals = new BindingList<BatchIntervalMarked>();

            //foreach (CumulativeInterval ci in cumulativeIntervals)
            //{
            //    if (ci.Marked)
            //    {
            //        BatchIntervalMarked bim = new BatchIntervalMarked();
            //        bim.BatchIntervalId = 0;
            //        bim.CaptureBatchId = 0;
            //        bim.IntervalNumber = ci.CumulativeIntervalNumber;
            //        bim.Marked = CaptureState.Marked;
            //        bim.PacketCount = ci.PacketCount;
            //        markedBatchIntervals.Add(bim);
            //    }
            //    else
            //    {
            //        BatchIntervalMarked bim = new BatchIntervalMarked();
            //        bim.BatchIntervalId = 0;
            //        bim.CaptureBatchId = 0;
            //        bim.IntervalNumber = ci.CumulativeIntervalNumber;
            //        bim.Marked = CaptureState.Unmarked;
            //        bim.PacketCount = ci.PacketCount;
            //        unmarkedBatchIntervals.Add(bim);
            //    }
            //}

            //BatchStatistics markedCumulativeStats = new BatchStatistics();
            //BatchStatistics unmarkedCumulativeStats = new BatchStatistics();
            //decimal markedMeanOfMeans = 0;
            //decimal markedStdDevMeanOfMeans = 0;
            //decimal unmarkedMeanOfMeans = 0;
            //decimal unmarkedStdDevMeanOfMeans = 0;

            //AnalysisEngine ae = new AnalysisEngine();

            // Get the marked cumulative statistics
            DisplayStatistic markedCumulativeStats = new DisplayStatistic();
            markedCumulativeStats = pcp.GetCumulativeMarkedDisplayStatistics();

            if (markedCumulativeStats != null)
            {
                //if(markedBatchIntervals.Count > 0)
                //{
                //    markedCumulativeStats = ae.CalculateBatchStatistics(markedBatchIntervals,CaptureState.Marked, BatchType.Cumulative);
                //    markedMeanOfMeans = pcp.CalculateMeanOfMeans(CaptureState.Marked, TrimIntervals ? true : false);
                //    markedStdDevMeanOfMeans = pcp.CalculateStdDevForMeanOfMeans(CaptureState.Marked, TrimIntervals ? true : false);

                // Load up the table
                // Cumulative marked column
                int row = 0;
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = markedCumulativeStats.IntervalCount;
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = TrimIntervals == true ? markedCumulativeStats.TrimmedIntervalCount.ToString() : "N/A";
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = string.Format("{0:N2}", markedCumulativeStats.MeanPacketsPerInterval);
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = string.Format("{0:N2}", markedCumulativeStats.StandardDeviation);
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = markedCumulativeStats.MinPacketsPerInterval;
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = markedCumulativeStats.MaxPacketsPerInterval;
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = string.Format("{0:N2}", markedCumulativeStats.MeanOfMeans);
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = "N/A";
                _AnalysisDataGridView.Rows[row++].Cells[5].Value = "N/A";
                //}
            }

            // Get the marked cumulative statistics
            DisplayStatistic unmarkedCumulativeStats = new DisplayStatistic();
            unmarkedCumulativeStats = pcp.GetCumulativeUnmarkedDisplayStatistics();

            if (unmarkedCumulativeStats != null)
            {
                //if (unmarkedBatchIntervals.Count > 0)
                //{
                //    unmarkedCumulativeStats = ae.CalculateBatchStatistics(unmarkedBatchIntervals, CaptureState.Marked, BatchType.Cumulative);
                //    unmarkedMeanOfMeans = pcp.CalculateMeanOfMeans(CaptureState.Unmarked, TrimIntervals ? true : false);
                //    unmarkedStdDevMeanOfMeans = pcp.CalculateStdDevForMeanOfMeans(CaptureState.Unmarked, TrimIntervals ? true : false);

                // Load up the table
                // Cumulative unmarked column
                int row = 0;
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = unmarkedCumulativeStats.IntervalCount;
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = TrimIntervals == true ? unmarkedCumulativeStats.TrimmedIntervalCount.ToString() : "N/A";
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = string.Format("{0:N2}", unmarkedCumulativeStats.MeanPacketsPerInterval);
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = string.Format("{0:N2}", unmarkedCumulativeStats.StandardDeviation);
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = unmarkedCumulativeStats.MinPacketsPerInterval;
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = unmarkedCumulativeStats.MaxPacketsPerInterval;
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = string.Format("{0:N2}", unmarkedCumulativeStats.MeanOfMeans);
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = "N/A";
                _AnalysisDataGridView.Rows[row++].Cells[4].Value = "N/A";
                //}
            }

            //if (markedBatchIntervals.Count > 0 && unmarkedBatchIntervals.Count > 0)
            if (markedCumulativeStats != null && unmarkedCumulativeStats != null)
            {
                // Get the Hypothesis Test results
                HypothesisTest ht = new HypothesisTest();
                ht = pcp.GetHypothesisTestResults();

                // Specify font for hypothesis test result fields
                Font font = new Font(_AnalysisDataGridView.DefaultCellStyle.Font.FontFamily, _AnalysisDataGridView.Font.Size, FontStyle.Bold);

                // Cumulative variance column
                int row = 0;
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = unmarkedCumulativeStats.IntervalCount - markedCumulativeStats.IntervalCount;
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = TrimIntervals == true ? (unmarkedCumulativeStats.TrimmedIntervalCount - markedCumulativeStats.TrimmedIntervalCount).ToString() : "N/A";
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = string.Format("{0:N2}", (unmarkedCumulativeStats.MeanPacketsPerInterval - markedCumulativeStats.MeanPacketsPerInterval));
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = string.Format("{0:N2}", (unmarkedCumulativeStats.StandardDeviation - markedCumulativeStats.StandardDeviation));
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = unmarkedCumulativeStats.MinPacketsPerInterval - markedCumulativeStats.MinPacketsPerInterval;
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = unmarkedCumulativeStats.MaxPacketsPerInterval - markedCumulativeStats.MaxPacketsPerInterval;
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = string.Format("{0:N2}", (unmarkedCumulativeStats.MeanOfMeans - markedCumulativeStats.MeanOfMeans));
                _AnalysisDataGridView.Rows[row++].Cells[6].Value = string.Format("{0:P1}", AnalysisConfiguration.Alpha);
                // Means test results
                _AnalysisDataGridView.Rows[row].Cells[6].Style.Font = font;
                _AnalysisDataGridView.Rows[row].Cells[6].Value = ht.MeansTestResult == true ? "True" : "False";
                _AnalysisDataGridView.Rows[row].Cells[6].Style.BackColor = ht.MeansTestResult == true ? Color.LightGreen : Color.LightCoral;

                //// Update the K-S statistics column
                //row = 0;
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = string.Format("{0:N2}", ht.MeansVarianceStandardDeviation);
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = "N/A";
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = string.Format("{0:N2}", ht.MeanOfMeansVariance);
                //_AnalysisDataGridView.Rows[row++].Cells[7].Value = string.Format("{0:P1}", AnalysisConfiguration.Alpha);
                //// K-S test results
                //_AnalysisDataGridView.Rows[row].Cells[7].Style.Font = font;
                //_AnalysisDataGridView.Rows[row].Cells[7].Value = ht.KsTestResult == true ? "True" : "False";
                //_AnalysisDataGridView.Rows[row].Cells[7].Style.BackColor = ht.KsTestResult == true ? Color.LightGreen : Color.LightCoral;
            }

            //// Update the K-S statistics object
            //_KsStatistics.MarkedMean = markedMeanOfMeans;
            //_KsStatistics.MarkedStdDev = markedStdDevMeanOfMeans;
            ////_KsStatistics.MarkedMean = markedCumulativeStats.PacketCountMean;
            ////_KsStatistics.MarkedStdDev = markedCumulativeStats.PacketCountStandardDeviation;
            //_KsStatistics.MarkedIntervalCount = TrimIntervals == true ? markedCumulativeStats.IntervalCountTrimmed : markedCumulativeStats.IntervalCount;
            //_KsStatistics.UnmarkedMean = unmarkedMeanOfMeans;
            //_KsStatistics.UnmarkedStdDev = unmarkedStdDevMeanOfMeans;
            ////_KsStatistics.UnmarkedMean = unmarkedCumulativeStats.PacketCountMean;
            ////_KsStatistics.UnmarkedStdDev = unmarkedCumulativeStats.PacketCountStandardDeviation;
            //_KsStatistics.UnmarkedIntervalCount = TrimIntervals == true ? unmarkedCumulativeStats.IntervalCountTrimmed : unmarkedCumulativeStats.IntervalCount;
        }
 public void InsertHypothesisTestResults(HypothesisTest testResults)
 {
     DisplayStatisticsData dsd = new DisplayStatisticsData();
     dsd.InsertHypothesisTestResults(testResults);
 }
 public HypothesisTest GetHypothesisTestResults()
 {
     HypothesisTest ht = new HypothesisTest();
     DisplayStatisticsData dsd = new DisplayStatisticsData();
     ht = dsd.GetHypothesisTestResults();
     if (ht != null)
     {
         return ht;
     }
     else
     {
         return new HypothesisTest();
     }
 }
 public void InsertHypothesisTestResults(HypothesisTest testResults)
 {
     using (var context = new PacketAnalysisEntity())
     {
         context.HypothesisTests.Add(testResults);
         context.SaveChanges();
     }
 }
        public HypothesisTest GetHypothesisTestResults()
        {
            HypothesisTest ht = new HypothesisTest();

            using (var context = new PacketAnalysisEntity())
            {
                var testResults = (from t in context.HypothesisTests select t).FirstOrDefault();
                ht = testResults as HypothesisTest;
            }
            return ht;
        }
        public HypothesisTest GetHypothesisTestResult()
        {
            HypothesisTest ht = new HypothesisTest(); ;

            // Get cumulative probability distribution data and find the max difference between marked and unmarked distributions
            ProcessCapturePackets pcp = new ProcessCapturePackets();
            BindingList<CumulativeProbabilityDistribution> markedCPD = new BindingList<CumulativeProbabilityDistribution>();
            BindingList<CumulativeProbabilityDistribution> unmarkedCPD = new BindingList<CumulativeProbabilityDistribution>();
            markedCPD = pcp.GetCumulativeProbabilityDistributionData(CaptureState.Marked);
            unmarkedCPD = pcp.GetCumulativeProbabilityDistributionData(CaptureState.Unmarked);

            if (markedCPD.Count > 0 && unmarkedCPD.Count > 0)
            {
                decimal maxVariance = 0M;
                int intervalCount = 0;

                // Only compare intervals from each distribution with a corresponding interval in the other distribution
                if (unmarkedCPD.Count > markedCPD.Count)
                {
                    intervalCount = markedCPD.Count;
                }
                else
                {
                    intervalCount = unmarkedCPD.Count;
                }

                // Expand each distribution into equal discrete steps for comparison of cumulative probabilities
                // First, find the largest cumulative packet count (= interval)
                int maxPacketCount = 0;
                if (markedCPD[markedCPD.Count - 1].Interval >= unmarkedCPD[unmarkedCPD.Count - 1].Interval)
                {
                    maxPacketCount = markedCPD[markedCPD.Count - 1].Interval;
                }
                else
                {
                    maxPacketCount = unmarkedCPD[unmarkedCPD.Count - 1].Interval;
                }

                // Second, expand the packet counts by interpolating between packet counts (intervals) using an average probability
                // for each packet count in the range and successively adding up to the next packet count (interval); add these
                // interpolated packets to a dictionary; outcome is a dictionary for each distribution containing packet counts and
                // probabilities from packet count = 0 to packet count = largest packet count (interval) of both distributions and
                // the associated probabilities for each packet count.  We are basically calculating a linear estimate of packet
                // counts and probabilities between each packet count and probability in the actual distributions.

                //// Third, check for packet counts that are less than the maximum packet count and assign a probability of 1
                //// to any that are found

                ExpandPacketCountLinear markedExpPktCount = new ExpandPacketCountLinear(markedCPD, maxPacketCount);
                ExpandPacketCountLinear unmarkedExpPktCount = new ExpandPacketCountLinear(unmarkedCPD, maxPacketCount);
                SortedDictionary<int, decimal> markedCPDExpanded = new SortedDictionary<int, decimal>();
                SortedDictionary<int, decimal> unmarkedCPDExpanded = new SortedDictionary<int, decimal>();
                //markedCPDExpanded = ExpandPacketCount(markedCPD, maxPacketCount);
                //unmarkedCPDExpanded = ExpandPacketCount(unmarkedCPD, maxPacketCount);
                markedCPDExpanded = markedExpPktCount.ExpandPacketCount();
                unmarkedCPDExpanded = unmarkedExpPktCount.ExpandPacketCount();

                // Find the maximum variance between the cumulative probabilities in each distribution
                for (int i = 0; i < maxPacketCount; i++)
                {
                    #region Debug
            #if(DEBUG)
                    System.Diagnostics.Debug.WriteLine("unmarkedCPDExpanded[{0}]:[{1}] - markedCPDExpanded[{2}]:[{3}] = {4}", i, unmarkedCPDExpanded[i], i, markedCPDExpanded[i], Math.Abs(unmarkedCPDExpanded[i] - markedCPDExpanded[i]));
            #endif
                    #endregion
                    if (Math.Abs(unmarkedCPDExpanded[i] - markedCPDExpanded[i]) > maxVariance)
                    {
                        maxVariance = Math.Abs(unmarkedCPDExpanded[i] - markedCPDExpanded[i]);
                    }
                }

                // Multiply by the square root of the sample size factor
                maxVariance = maxVariance * Convert.ToDecimal(Math.Sqrt((markedCPD.Count * unmarkedCPD.Count) / (markedCPD.Count + unmarkedCPD.Count)));

                // Compare the maximum variance with the hypothesis test threshold
                // For significance level alpha = 0.05, the K-S statistic is computed as 1.36/N^(1/2), where N is the number of samples
                decimal ksStatistic = Convert.ToDecimal(1.36 / Math.Pow(intervalCount, 0.5));
                ht.KsStatistic = ksStatistic;
                ht.MaxCpdVariance = maxVariance;
                if (maxVariance > ksStatistic)
                {
                    // Reject the null hypothesis
                    ht.KsTestResult = true;
                }
            }
            else
            {
                // Not enough data to perform the test
                ht.KsStatistic = 0;
                ht.MaxCpdVariance = 0;
                ht.KsTestResult = false;
            }
            return ht;
        }