public void WeightedSampleTest() { var random = new Random(42); var values = new GumbelDistribution().Random(random).Next(30).Concat( new GumbelDistribution(10).Random(random).Next(30)).ToList(); double[] weights = ExponentialDecaySequence.CreateFromHalfLife(10).GenerateReverseArray(values.Count); var sample = new Sample(values, weights); var simpleModalityData = detector.DetectModes(values); output.WriteLine("SimpleModalityData.Modes:"); output.WriteLine(Present(simpleModalityData)); output.WriteLine(); output.WriteLine(simpleModalityData.DensityHistogram.Present()); output.WriteLine("------------------------------"); var weightedModalityData = detector.DetectModes(sample); output.WriteLine("WeightedModalityData.Modes:"); output.WriteLine(Present(weightedModalityData)); output.WriteLine(); output.WriteLine(weightedModalityData.DensityHistogram.Present()); Assert.Equal(2, simpleModalityData.Modality); Assert.Equal(1, weightedModalityData.Modality); }
public void GumbelFit() { GumbelDistribution d = new GumbelDistribution(-1.0, 2.0); MultivariateSample parameters = new MultivariateSample(2); MultivariateSample variances = new MultivariateSample(3); // Do a bunch of fits, record reported parameters and variances for (int i = 0; i < 32; i++) { Sample s = SampleTest.CreateSample(d, 64, i); GumbelFitResult r = GumbelDistribution.FitToSample(s); parameters.Add(r.Location.Value, r.Scale.Value); variances.Add(r.Parameters.CovarianceMatrix[0, 0], r.Parameters.CovarianceMatrix[1, 1], r.Parameters.CovarianceMatrix[0, 1]); Assert.IsTrue(r.GoodnessOfFit.Probability > 0.01); } // The reported parameters should agree with the underlying parameters Assert.IsTrue(parameters.Column(0).PopulationMean.ConfidenceInterval(0.99).ClosedContains(d.Location)); Assert.IsTrue(parameters.Column(1).PopulationMean.ConfidenceInterval(0.99).ClosedContains(d.Scale)); // The reported covariances should agree with the observed covariances Assert.IsTrue(parameters.Column(0).PopulationVariance.ConfidenceInterval(0.99).ClosedContains(variances.Column(0).Mean)); Assert.IsTrue(parameters.Column(1).PopulationVariance.ConfidenceInterval(0.99).ClosedContains(variances.Column(1).Mean)); Assert.IsTrue(parameters.TwoColumns(0, 1).PopulationCovariance.ConfidenceInterval(0.99).ClosedContains(variances.Column(2).Mean)); }
public void GumbelDistributionTest2() { var gumbel = new GumbelDistribution(1, 2); AssertEqual("Location", 1, gumbel.Location); AssertEqual("Scale", 2, gumbel.Scale); AssertEqual("Mean", 2.1544313298030655, gumbel.Mean); AssertEqual("Median", 1.7330258411633288, gumbel.Median); AssertEqual("Variance", 6.579736267392906, gumbel.Variance); var x = new[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 }; var expectedPdf = new[] { 0.163415479697888, 0.167801779821723, 0.171664252678358, 0.174993580579211, 0.177786373690972, 0.180044733644614, 0.181775762939958, 0.182991038252879, 0.183706064004954 }; var expectedCdf = new[] { 0.2083966205323, 0.224961793549918, 0.241939508585805, 0.259276865990828, 0.276920334099909, 0.294816320729158, 0.312911698166345, 0.331154277152909, 0.349493227081447 }; var expectedQuantile = new[] { -0.668064890495911, 0.0482300093457789, 0.628746482275269, 1.17484314358151, 1.73302584116333, 2.34345398418424, 3.06186086631745, 3.99987997351903, 5.50073465462489 }; Check(gumbel, x, expectedPdf, expectedCdf, expectedQuantile); }
public void GumbelDistributionTest1() { var gumbel = new GumbelDistribution(); AssertEqual("Location", 0, gumbel.Location); AssertEqual("Scale", 1, gumbel.Scale); AssertEqual("Mean", 0.5772156649015329, gumbel.Mean); AssertEqual("Median", 0.36651292058166435, gumbel.Median); AssertEqual("Variance", 1.6449340668482264, gumbel.Variance); var x = new[] { 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 }; var expectedPdf = new[] { 0.36610415189774, 0.36105291477093, 0.353165596312007, 0.342898756467732, 0.330704298890418, 0.31701327275429, 0.302224456630968, 0.286697116378904, 0.270747220321608 }; var expectedCdf = new[] { 0.404607661664132, 0.440991025942983, 0.476723690714594, 0.511544833689042, 0.545239211892605, 0.577635844258916, 0.608605317804406, 0.638056166582019, 0.665930705440122 }; var expectedQuantile = new[] { -0.834032445247956, -0.475884995327111, -0.185626758862366, 0.0874215717907552, 0.366512920581664, 0.671726992092122, 1.03093043315872, 1.49993998675952, 2.25036732731245 }; Check(gumbel, x, expectedPdf, expectedCdf, expectedQuantile); }
public void ConstructorTest1() { var gumbel = new GumbelDistribution(location: 4.795, scale: 1 / 0.392); double mean = gumbel.Mean; // 6.2674889410753387 double median = gumbel.Median; // 5.7299819402593481 double mode = gumbel.Mode; // 4.7949999999999999 double var = gumbel.Variance; // 10.704745853604138 double cdf = gumbel.DistributionFunction(x: 3.4); // 0.17767760424788051 double pdf = gumbel.ProbabilityDensityFunction(x: 3.4); // 0.12033954114322486 double lpdf = gumbel.LogProbabilityDensityFunction(x: 3.4); // -2.1174380222001519 double ccdf = gumbel.ComplementaryDistributionFunction(x: 3.4); // 0.82232239575211952 double icdf = gumbel.InverseDistributionFunction(p: cdf); // 3.3999999904866245 double hf = gumbel.HazardFunction(x: 1.4); // 0.03449691276402958 double chf = gumbel.CumulativeHazardFunction(x: 1.4); // 0.022988793482259906 string str = gumbel.ToString(CultureInfo.InvariantCulture); // Gumbel(x; μ = 4.795, β = 2.55) Assert.AreEqual(6.2674889410753387, mean); Assert.AreEqual(5.7299819402593481, median); Assert.AreEqual(10.704745853604138, var); Assert.AreEqual(0.022988793482259906, chf); Assert.AreEqual(0.17767760424788051, cdf); Assert.AreEqual(0.12033954114322486, pdf); Assert.AreEqual(-2.1174380222001519, lpdf); Assert.AreEqual(0.03449691276402958, hf); Assert.AreEqual(0.82232239575211952, ccdf); Assert.AreEqual(3.3999999904866245, icdf); Assert.AreEqual("Gumbel(x; μ = 4.795, β = 2.55102040816327)", str); }
public void ConstructorTest1() { var gumbel = new GumbelDistribution(location: 4.795, scale: 1 / 0.392); double mean = gumbel.Mean; // 6.2674889410753387 double median = gumbel.Median; // 5.7299819402593481 double mode = gumbel.Mode; // 4.7949999999999999 double var = gumbel.Variance; // 10.704745853604138 double cdf = gumbel.DistributionFunction(x: 3.4); // 0.17767760424788051 double pdf = gumbel.ProbabilityDensityFunction(x: 3.4); // 0.12033954114322486 double lpdf = gumbel.LogProbabilityDensityFunction(x: 3.4); // -2.1174380222001519 double ccdf = gumbel.ComplementaryDistributionFunction(x: 3.4); // 0.82232239575211952 double icdf = gumbel.InverseDistributionFunction(p: cdf); // 3.3999999904866245 double hf = gumbel.HazardFunction(x: 1.4); // 0.03449691276402958 double chf = gumbel.CumulativeHazardFunction(x: 1.4); // 0.022988793482259906 string str = gumbel.ToString(CultureInfo.InvariantCulture); // Gumbel(x; μ = 4.795, β = 2.55) Assert.AreEqual(6.2674889410753387, mean); Assert.AreEqual(5.7299819402593481, median); Assert.AreEqual(4.7949999999999999, mode); Assert.AreEqual(10.704745853604138, var); Assert.AreEqual(0.022988793482259906, chf); Assert.AreEqual(0.17767760424788051, cdf); Assert.AreEqual(0.12033954114322486, pdf); Assert.AreEqual(-2.1174380222001519, lpdf); Assert.AreEqual(0.034496912764029573, hf); Assert.AreEqual(0.82232239575211952, ccdf); Assert.AreEqual(3.3999999999999999, icdf); Assert.AreEqual("Gumbel(x; μ = 4.795, β = 2.55102040816327)", str); var range1 = gumbel.GetRange(0.95); var range2 = gumbel.GetRange(0.99); var range3 = gumbel.GetRange(0.01); Assert.AreEqual(1.9960492163695556, range1.Min, 1e-6); Assert.AreEqual(12.37202869894511, range1.Max, 1e-6); Assert.AreEqual(0.89913343799046785, range2.Min, 1e-6); Assert.AreEqual(16.530074551002095, range2.Max, 1e-6); Assert.AreEqual(0.8991334379904673, range3.Min, 1e-6); Assert.AreEqual(16.530074551002095, range3.Max, 1e-6); /* Tested against R's package QRM: * * > pGumbel(3.4, 4.795, 1 / 0.392) * [1] 0.1776776 * * > dGumbel(3.4, 4.795, 1 / 0.392) * [1] 0.1203395 * */ }
private void SetDistributionFunctionFromString() { if (DistributionfunctionString.StartsWith("N")) { DistributionFunction = new NormalDistribution(Mean, StDeviation); } else if (DistributionfunctionString.StartsWith("Poisson")) { DistributionfunctionString = EnsureOnlyOneComma(DistributionfunctionString, 1); var lambda = double.Parse((DistributionfunctionString.Split('=')[1]).Replace(")", "").Trim(), CultureInfo.InvariantCulture); DistributionFunction = new PoissonDistribution(lambda); } else if (DistributionfunctionString.StartsWith("U")) { DistributionfunctionString = EnsureOnlyOneComma(DistributionfunctionString, 2); var a = double.Parse((DistributionfunctionString.Split('=')[1]).Split(',')[0].Trim(), CultureInfo.InvariantCulture); var b = double.Parse((DistributionfunctionString.Split('=')[2]).Split(')')[0].Trim(), CultureInfo.InvariantCulture); DistributionFunction = new UniformContinuousDistribution(a, b); } else if (DistributionfunctionString.Contains("x; k =")) { DistributionfunctionString = EnsureOnlyOneComma(DistributionfunctionString, 2); var k = double.Parse((DistributionfunctionString.Split('=')[1]).Split(',')[0].Trim(), CultureInfo.InvariantCulture); var teta = double.Parse((DistributionfunctionString.Split('=')[2]).Split(')')[0].Trim(), CultureInfo.InvariantCulture); DistributionFunction = new GammaDistribution(teta, k); } else if (DistributionfunctionString.Contains("Gumbel")) { DistributionfunctionString = EnsureOnlyOneComma(DistributionfunctionString, 2); var u = double.Parse((DistributionfunctionString.Split('=')[1]).Split(',')[0].Trim(), CultureInfo.InvariantCulture); var b = double.Parse((DistributionfunctionString.Split('=')[2]).Split(')')[0].Trim(), CultureInfo.InvariantCulture); DistributionFunction = new GumbelDistribution(u, b); } else { throw new Exception("Unregnoized disitrubtionfunction " + DistributionfunctionString); } }
public static void DistributionFunctions() { ContinuousDistribution gumbel = new GumbelDistribution(); // Use PDF to compute absolute deviation IntegrationResult r = FunctionMath.Integrate( z => gumbel.ProbabilityDensity(z) * Math.Abs(z - gumbel.Mean), gumbel.Support ); Console.WriteLine($"mean absolute deviation = {r.Value}"); // Shorter form double gumbelMad = gumbel.ExpectationValue(z => Math.Abs(z - gumbel.Mean)); Console.WriteLine($"mean absolute deviation = {gumbelMad}"); double x = 1.5; // PDF Console.WriteLine($"p({x}) = {gumbel.ProbabilityDensity(x)}"); // CDF, aka percentile double P = gumbel.LeftProbability(x); Console.WriteLine($"P({x}) = {P}"); // Right CDF double Q = gumbel.RightProbability(x); Console.WriteLine($"Q({x}) = {Q}"); Console.WriteLine($"P + Q = {P + Q}"); // Far tail double xt = 100.0; double qt = gumbel.RightProbability(xt); Console.WriteLine($"Q({xt}) = {qt}"); // Inverse CDF, aka quantile Console.WriteLine($"PI({P}) = {gumbel.InverseLeftProbability(P)}"); Console.WriteLine($"QI({qt} = {gumbel.InverseRightProbability(qt)}"); DiscreteDistribution binomial = new BinomialDistribution(0.4, 8); Console.WriteLine($"support {binomial.Support}"); int k = 4; Console.WriteLine($"P({k}) = {binomial.ProbabilityMass(k)}"); double binomialMad = binomial.ExpectationValue(i => Math.Abs(i - binomial.Mean)); Console.WriteLine($"mean absolute deviation = {binomialMad}"); Console.WriteLine($"P(k < {k}) = {binomial.LeftExclusiveProbability(k)}"); Console.WriteLine($"P(k <= {k}) = {binomial.LeftInclusiveProbability(k)}"); Console.WriteLine($"P(k > {k}) = {binomial.RightExclusiveProbability(k)}"); int k0 = binomial.InverseLeftProbability(0.5); Console.WriteLine($"min k0 to achieve P(k <= k0) > 0.5: {k0}"); Console.WriteLine($"P(k < {k0}) = {binomial.LeftExclusiveProbability(k0)}"); Console.WriteLine($"P(k <= {k0}) = {binomial.LeftInclusiveProbability(k0)}"); }
/// <summary> /// Find the Gumbel distribution that best fit the given sample. /// </summary> /// <param name="sample">The sample to fit.</param> /// <returns>The fit result.</returns> /// <exception cref="ArgumentNullException"><paramref name="sample"/> is <see langword="null"/>.</exception> /// <exception cref="InsufficientDataException"><paramref name="sample"/> contains fewer than three values.</exception> public static GumbelFitResult FitToGumbel(this IReadOnlyList <double> sample) { if (sample == null) { throw new ArgumentNullException(nameof(sample)); } if (sample.Count < 3) { throw new InsufficientDataException(); } // To do a maximum likelihood fit, start from the log probability of each data point and aggregate to // obtain the log likelihood of the sample // z_i = \frac{x_i - m}{s} // -\ln p_i = \ln s + ( z_i + e^{-z_i}) // \ln L = \sum_i \ln p_i // Take derivatives wrt m and s. // \frac{\partial \ln L}{\partial m} = \frac{1}{s} \sum_i ( 1 - e^{-z_i} ) // \frac{\partial \ln L}{\partial s} = \frac{1}{s} \sum_i ( -1 + z_i - z_i e^{-z_i} ) // Set derivatives to zero to get a system of equations for the maximum. // n = \sum_i e^{-z_i} // n = \sum_i ( z_i - z_i e^{-z_i} ) // that is, <e^z> = 1 and <z> - <z e^z> = 1. // To solve this system, pull e^{m/s} out of the sum in the first equation and solve for m // n = e^{m / s} \sum_i e^{-x_i / s} // m = -s \ln \left( \frac{1}{n} \sum_i e^{-x_i / s} \right) = -s \ln <e^{-x/s}> // Substituting this result into the second equation gets us to // s = \bar{x} - \frac{ <x e^{-x/s}> }{ <e^{x/s}> } // which involves only s. We can use a one-dimensional root-finder to determine s, then determine m // from the first equation. // To avoid exponentiating potentially large x_i, it's better to write the problem in terms // of d_i, where x_i = \bar{x} + d_i. // m = \bar{x} - s \ln <e^{-d/s}> // s = -\frac{ <d e^{-d/s}> }{ <e^{-d/s}> } // To get the covariance matrix, we need the curvature matrix at the minimum, so take more derivatives // \frac{\partial^2 \ln L}{\partial m^2} = - \frac{1}{s} \sum_i e^{-z_i} = - \frac{n}{s^2} // \frac{\partial^2 \ln L}{\partial m \partial s} = - \frac{n}{s^2} <z e^{-z}> // \frac{\partial^2 \ln L}{\partial s^2} = - \frac{n}{s^2} ( <z^2 e^{-z}> + 1 ) // Several crucial pieces of this analysis are taken from Mahdi and Cenac, "Estimating Parameters of Gumbel Distribution // "using the method of moments, probability weighted moments, and maximum likelihood", Revista de Mathematica: // Teoria y Aplicaciones 12 (2005) 151-156 (http://revistas.ucr.ac.cr/index.php/matematica/article/viewFile/259/239) // We will be needed the sample mean and standard deviation int n; double mean, stdDev; Univariate.ComputeMomentsUpToSecond(sample, out n, out mean, out stdDev); stdDev = Math.Sqrt(stdDev / n); // Use the method of moments to get an initial estimate of s. double s0 = Math.Sqrt(6.0) / Math.PI * stdDev; // Define the function to zero Func <double, double> fnc = (double s) => { double u, v; MaximumLikelihoodHelper(sample, n, mean, s, out u, out v); return(s + v / u); }; // Zero it to compute the best-fit s double s1 = FunctionMath.FindZero(fnc, s0); // Compute the corresponding best-fit m double u1, v1; MaximumLikelihoodHelper(sample, n, mean, s1, out u1, out v1); double m1 = mean - s1 * Math.Log(u1); // Compute the curvature matrix double w1 = 0.0; double w2 = 0.0; foreach (double x in sample) { double z = (x - m1) / s1; double e = Math.Exp(-z); w1 += z * e; w2 += z * z * e; } w1 /= sample.Count; w2 /= sample.Count; SymmetricMatrix C = new SymmetricMatrix(2); C[0, 0] = (n - 2) / (s1 * s1); C[0, 1] = (n - 2) / (s1 * s1) * w1; C[1, 1] = (n - 2) / (s1 * s1) * (w2 + 1.0); SymmetricMatrix CI = C.CholeskyDecomposition().Inverse(); // The use of (n-2) here in place of n is a very ad hoc attempt to increase accuracy. // Compute goodness-of-fit GumbelDistribution dist = new GumbelDistribution(m1, s1); TestResult test = sample.KolmogorovSmirnovTest(dist); return(new GumbelFitResult(m1, s1, CI[0, 0], CI[1, 1], CI[0, 1], test)); }