private EmpiricalDistribution GetSimulatedDistribution(ISampleableDistribution <double> hypothesizedDistribution, bool reestimate, int iterations, KolmogorovSmirnovTestHypothesis alternate) { double[] samples = new double[iterations]; if (reestimate) { Parallel.For(0, iterations, i => { double[] s = hypothesizedDistribution.Generate(samples: NumberOfSamples); Vector.Sort <double>(s); var fittable = (IFittableDistribution <double>)hypothesizedDistribution.Clone(); fittable.Fit(s); samples[i] = KolmogorovSmirnovTest.GetStatistic((double[])s, (IDistribution <double>)fittable, alternate); }); } else { Parallel.For(0, iterations, i => { double[] s = hypothesizedDistribution.Generate(samples: NumberOfSamples); Vector.Sort <double>(s); samples[i] = KolmogorovSmirnovTest.GetStatistic((double[])s, (IDistribution <double>)hypothesizedDistribution, alternate); }); } return(new EmpiricalDistribution(samples, smoothing: 0)); }
/// <summary> /// Creates a new One-Sample Lilliefors' Kolmogorov-Smirnov test. /// </summary> /// /// <param name="sample">The sample we would like to test as belonging to the <paramref name="hypothesizedDistribution"/>.</param> /// <param name="hypothesizedDistribution">A fully specified distribution (which could have been estimated from the data).</param> /// <param name="alternate">The alternative hypothesis (research hypothesis) to test.</param> /// <param name="iterations">The number of Monte-Carlo iterations to perform. Default is 10,000.</param> /// <param name="reestimate">Whether the target distribution should be re-estimated from the sampled data /// at each Monte-Carlo iteration. Pass true in case <paramref name="hypothesizedDistribution"/> has been /// estimated from the data.</param> /// public LillieforsTest(double[] sample, ISampleableDistribution <double> hypothesizedDistribution, KolmogorovSmirnovTestHypothesis alternate = KolmogorovSmirnovTestHypothesis.SampleIsDifferent, int iterations = 10000, bool reestimate = true) : this() { if (reestimate) { if (!(hypothesizedDistribution is IFittableDistribution <double>)) { throw new InvalidOperationException("The estimate option can only be used with distributions that implement IFittableDistribution<double>."); } } this.Hypothesis = alternate; // Create a copy of the samples to prevent altering the // constructor's original arguments in the sorting step double[] orderedSamples = sample.Sorted(); // Create the theoretical and empirical distributions this.TheoreticalDistribution = hypothesizedDistribution; this.EmpiricalDistribution = new EmpiricalDistribution(orderedSamples, smoothing: 0); this.NumberOfSamples = sample.Length; StatisticDistribution = GetSimulatedDistribution(hypothesizedDistribution, reestimate, iterations, alternate); // Finally, compute the test statistic and perform actual testing. base.Statistic = KolmogorovSmirnovTest.GetStatistic(orderedSamples, TheoreticalDistribution, alternate); this.Tail = (DistributionTail)alternate; base.PValue = StatisticToPValue(Statistic); }