public void rtest() { // pweibull((0:20)/10, 1.52, 0.6) var n = new WeibullDistribution(1.52, 0.6); Assert.AreEqual(0.00000000, n.DistributionFunction(0.0), 1e-6); Assert.AreEqual(0.06353795, n.DistributionFunction(0.1), 1e-6); Assert.AreEqual(0.17160704, n.DistributionFunction(0.2), 1e-6); Assert.AreEqual(0.29438528, n.DistributionFunction(0.3), 1e-6); Assert.AreEqual(0.41721373, n.DistributionFunction(0.4), 1e-6); Assert.AreEqual(0.53137710, n.DistributionFunction(0.5), 1e-6); Assert.AreEqual(0.63212056, n.DistributionFunction(0.6), 1e-6); Assert.AreEqual(0.71748823, n.DistributionFunction(0.7), 1e-6); Assert.AreEqual(0.78743013, n.DistributionFunction(0.8), 1e-6); Assert.AreEqual(0.84308886, n.DistributionFunction(0.9), 1e-6); Assert.AreEqual(0.88625003, n.DistributionFunction(1.0), 1e-6); Assert.AreEqual(0.9999903, n.DistributionFunction(3.0), 1e-6); Assert.AreEqual(0.00000000, n.ProbabilityDensityFunction(0.0), 1e-6); Assert.AreEqual(0.934423757, n.ProbabilityDensityFunction(0.1), 1e-6); Assert.AreEqual(1.185292906, n.ProbabilityDensityFunction(0.2), 1e-6); Assert.AreEqual(1.246592100, n.ProbabilityDensityFunction(0.3), 1e-6); Assert.AreEqual(1.195732949, n.ProbabilityDensityFunction(0.4), 1e-6); Assert.AreEqual(1.079795701, n.ProbabilityDensityFunction(0.5), 1e-6); Assert.AreEqual(0.931961251, n.ProbabilityDensityFunction(0.6), 1e-6); Assert.AreEqual(0.775427531, n.ProbabilityDensityFunction(0.7), 1e-6); Assert.AreEqual(0.625406197, n.ProbabilityDensityFunction(0.8), 1e-6); Assert.AreEqual(0.490810192, n.ProbabilityDensityFunction(0.9), 1e-6); Assert.AreEqual(0.375841697, n.ProbabilityDensityFunction(1.0), 1e-6); }
static void Main(string[] args) { // // Prueba de Kolmogorov-Smirnov // Console.WriteLine("\nPrueba de Kolmogorov-Smirnov"); // Muestra de 25 numeros aleatorios LognormalDistribution logNormal = new LognormalDistribution(0, 1); WeibullDistribution weibull = new WeibullDistribution(2, 1); // Generamos las muestras var logNormalSample = logNormal.Sample(25); // Construimos la prueba de Kolmogorov smirnov: var ksTest = new OneSampleKolmogorovSmirnovTest(logNormalSample, weibull); Console.WriteLine(logNormalSample); Console.WriteLine("\n"); Console.WriteLine(ksTest + "\n"); // Podemos obtener el valor del estadístico de prueba a través de la propiedad Statistic // el valor P correspondiente a través de la propiedad Probability: Console.WriteLine("Test statistic: {0:F4}", ksTest.Statistic); Console.WriteLine("P-value: {0:F4}", ksTest.PValue); // Ahora podemos imprimir los resultados de la prueba: Console.WriteLine("Rechazar la Hipotesis nula? {0}", ksTest.Reject() ? "si" : "no"); Console.ReadLine(); }
protected override void EndProcessing() { var dist = new WeibullDistribution(Shape, Scale); var obj = DistributionHelper.AddConvinienceMethods(dist); WriteObject(obj); }
public void ProbabilityDistributionTest() { WeibullDistribution n = new WeibullDistribution(0.80, 12.5); double[] expected = { Double.PositiveInfinity, // checked against R 0.09289322, 0.07330050, 0.06186956, 0.05377820, 0.04754570, 0.04251180, 0.03832077, 0.03475727, 0.03168016, 0.02899143 }; double[] actual = new double[expected.Length]; for (int i = 0; i < actual.Length; i++) { actual[i] = n.ProbabilityDensityFunction(i); } for (int i = 0; i < actual.Length; i++) { Assert.AreEqual(expected[i], actual[i], 1e-5); } }
public void Bug7213() { Sample s = new Sample(); s.Add(0.00590056, 0.00654598, 0.0066506, 0.00679065, 0.008826); WeibullFitResult r = WeibullDistribution.FitToSample(s); }
//End of ui.cs file Contents //------------------------------------------------------------------------- //Begin of Random.cs file contents /// <summary> /// Initializes the random-number generator with a specific seed. /// </summary> public void Initialize(uint seed) { RandomNumberGenerator = new MT19937Generator(seed); betaDist = new BetaDistribution(RandomNumberGenerator); betaPrimeDist = new BetaPrimeDistribution(RandomNumberGenerator); cauchyDist = new CauchyDistribution(RandomNumberGenerator); chiDist = new ChiDistribution(RandomNumberGenerator); chiSquareDist = new ChiSquareDistribution(RandomNumberGenerator); continuousUniformDist = new ContinuousUniformDistribution(RandomNumberGenerator); erlangDist = new ErlangDistribution(RandomNumberGenerator); exponentialDist = new ExponentialDistribution(RandomNumberGenerator); fisherSnedecorDist = new FisherSnedecorDistribution(RandomNumberGenerator); fisherTippettDist = new FisherTippettDistribution(RandomNumberGenerator); gammaDist = new GammaDistribution(RandomNumberGenerator); laplaceDist = new LaplaceDistribution(RandomNumberGenerator); lognormalDist = new LognormalDistribution(RandomNumberGenerator); normalDist = new NormalDistribution(RandomNumberGenerator); paretoDist = new ParetoDistribution(RandomNumberGenerator); powerDist = new PowerDistribution(RandomNumberGenerator); rayleighDist = new RayleighDistribution(RandomNumberGenerator); studentsTDist = new StudentsTDistribution(RandomNumberGenerator); triangularDist = new TriangularDistribution(RandomNumberGenerator); weibullDist = new WeibullDistribution(RandomNumberGenerator); poissonDist = new PoissonDistribution(RandomNumberGenerator); // generator.randomGenerator = new MT19937Generator(seed); }
public void CumulativeDistributionTest() { WeibullDistribution n = new WeibullDistribution(0.80, 12.5); double[] expected = { 0.0, 0.1241655, 0.2061272, 0.2733265, 0.3309536, 0.3814949, }; double[] actual = new double[expected.Length]; for (int i = 0; i < actual.Length; i++) { actual[i] = n.DistributionFunction(i); } for (int i = 0; i < actual.Length; i++) { Assert.AreEqual(expected[i], actual[i], 1e-6); Assert.IsFalse(double.IsNaN(actual[i])); } }
public void ProbabilityDistributionTest() { WeibullDistribution n = new WeibullDistribution(0.80, 12.5); double[] expected = { 0.0, 0.09289322, 0.0733005, 0.06186956, 0.0537782, 0.0475457 }; double[] actual = new double[expected.Length]; for (int i = 0; i < actual.Length; i++) { actual[i] = n.ProbabilityDensityFunction(i); } for (int i = 0; i < actual.Length; i++) { Assert.AreEqual(expected[i], actual[i], 1e-5); Assert.IsFalse(double.IsNaN(actual[i])); } }
public void WeibullDistributionTest1() { var weibull = new WeibullDistribution(1); AssertEqual("Shape", 1, weibull.Shape); AssertEqual("Scale", 1, weibull.Scale); AssertEqual("Mean", 1, weibull.Mean); AssertEqual("Median", 0.6931471805599453, weibull.Median); AssertEqual("Variance", 1, weibull.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.90483741803596, 0.818730753077982, 0.740818220681718, 0.670320046035639, 0.606530659712633, 0.548811636094026, 0.496585303791409, 0.449328964117222, 0.406569659740599 }; var expectedCdf = new[] { 0.0951625819640404, 0.181269246922018, 0.259181779318282, 0.329679953964361, 0.393469340287367, 0.451188363905974, 0.503414696208591, 0.550671035882778, 0.593430340259401 }; var expectedQuantile = new[] { 0.105360515657826, 0.22314355131421, 0.356674943938732, 0.510825623765991, 0.693147180559945, 0.916290731874155, 1.20397280432594, 1.6094379124341, 2.30258509299405 }; Check(weibull, x, expectedPdf, expectedCdf, expectedQuantile); }
public void WeibullDistributionTest2() { var weibull = new WeibullDistribution(2, 1.5); AssertEqual("Shape", 2, weibull.Shape); AssertEqual("Scale", 1.5, weibull.Scale); AssertEqual("Mean", 1.3293403902848553, weibull.Mean); AssertEqual("Median", 1.2488319167365465, weibull.Median); AssertEqual("Variance", 0.482854144940259, weibull.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.0884947037762749, 0.174645211487676, 0.256210517107286, 0.331149654084036, 0.397706363028609, 0.454476687448646, 0.500455919329689, 0.535062866552393, 0.558141060856825 }; var expectedCdf = new[] { 0.00443458251690719, 0.0176206853818224, 0.0392105608476768, 0.068641597888648, 0.10516068318563, 0.147856211033789, 0.195695843934428, 0.247567843910697, 0.302323673928969 }; var expectedQuantile = new[] { 0.486889268961752, 0.708571090616158, 0.895834038124333, 1.07208099203068, 1.24883191673655, 1.43584614312149, 1.64588541816657, 1.90295436176928, 2.27614069407772 }; Check(weibull, x, expectedPdf, expectedCdf, expectedQuantile); }
public static void FitToDistribution() { Random rng = new Random(7); WeibullDistribution distribution = new WeibullDistribution(3.0, 1.5); List <double> sample = distribution.GetRandomValues(rng, 500).ToList(); WeibullFitResult weibull = sample.FitToWeibull(); Console.WriteLine($"Best fit scale: {weibull.Scale}"); Console.WriteLine($"Best fit shape: {weibull.Shape}"); Console.WriteLine($"Probability of fit: {weibull.GoodnessOfFit.Probability}"); LognormalFitResult lognormal = sample.FitToLognormal(); Console.WriteLine($"Best fit mu: {lognormal.Mu}"); Console.WriteLine($"Best fit sigma: {lognormal.Sigma}"); Console.WriteLine($"Probability of fit: {lognormal.GoodnessOfFit.Probability}"); var result = sample.MaximumLikelihoodFit(parameters => { return(new WeibullDistribution(parameters["Scale"], parameters["Shape"])); }, new Dictionary <string, double>() { { "Scale", 1.0 }, { "Shape", 1.0 } } ); foreach (Parameter parameter in result.Parameters) { Console.WriteLine($"{parameter.Name} = {parameter.Estimate}"); } }
public void WeibullDistributionChiSquareTest(double k, double lambda) { var weibullDistribution = new WeibullDistribution(k, lambda); var test = ChiSquareTest.Test(weibullDistribution); Assert.IsTrue(test); }
public void ConstructorTest() { WeibullDistribution n = new WeibullDistribution(0.807602, 12.5); Assert.AreEqual(14.067993598321863, n.Mean); Assert.AreEqual(17.552908226174811, n.StandardDeviation); Assert.IsFalse(Double.IsNaN(n.Mean)); Assert.IsFalse(Double.IsNaN(n.Variance)); }
public void ConstructorTest() { WeibullDistribution n = new WeibullDistribution(0.807602, 12.5); Assert.AreEqual(14.067993598321863, n.Mean); Assert.AreEqual(17.552908226174811, n.StandardDeviation); Assert.AreEqual(12.5, n.Scale); Assert.AreEqual(0.807602, n.Shape); }
public FuncionWeibull3(double[] eventos) : base(eventos) { try { DistribucionContinua = new WeibullDistribution(shape, scale); Resultado = new ResultadoAjuste(StringFDP, StringInversa, DistribucionContinua.StandardDeviation, DistribucionContinua.Mean, DistribucionContinua.Variance, this); } catch (Exception) { Resultado = null; } }
public void ConstructorTest2() { var weilbull = new WeibullDistribution(scale: 0.42, shape: 1.2); double mean = weilbull.Mean; // 0.39507546046784414 double median = weilbull.Median; // 0.30945951550913292 double var = weilbull.Variance; // 0.10932249666369542 double mode = weilbull.Mode; // 0.094360430821809421 double cdf = weilbull.DistributionFunction(x: 1.4); // 0.98560487188700052 double pdf = weilbull.ProbabilityDensityFunction(x: 1.4); // 0.052326687031379278 double lpdf = weilbull.LogProbabilityDensityFunction(x: 1.4); // -2.9502487697674415 double ccdf = weilbull.ComplementaryDistributionFunction(x: 1.4); // 0.22369885565908001 double icdf = weilbull.InverseDistributionFunction(p: cdf); // 1.400000001051205 double hf = weilbull.HazardFunction(x: 1.4); // 1.1093328057258516 double chf = weilbull.CumulativeHazardFunction(x: 1.4); // 1.4974545260150962 string str = weilbull.ToString(CultureInfo.InvariantCulture); // Weibull(x; λ = 0.42, k = 1.2) double imedian = weilbull.InverseDistributionFunction(p: 0.5); Assert.AreEqual(0.39507546046784414, mean); Assert.AreEqual(0.30945951550913292, median); Assert.AreEqual(0.094360430821809421, mode, 1e-10); Assert.AreEqual(0.3094595, imedian, 1e-5); Assert.AreEqual(0.10932249666369542, var); Assert.AreEqual(1.4974545260150962, chf); Assert.AreEqual(0.98560487188700052, cdf); Assert.AreEqual(0.052326687031379278, pdf); Assert.AreEqual(-2.9502487697674415, lpdf); Assert.AreEqual(1.1093328057258516, hf); Assert.AreEqual(0.22369885565908001, ccdf); Assert.AreEqual(1.40, icdf, 1e-6); Assert.AreEqual("Weibull(x; λ = 0.42, k = 1.2)", str); var range1 = weilbull.GetRange(0.95); var range2 = weilbull.GetRange(0.99); var range3 = weilbull.GetRange(0.01); Assert.AreEqual(0.035342687605397792, range1.Min); Assert.AreEqual(1.0479366931850318, range1.Max); Assert.AreEqual(0.0090865355213001313, range2.Min); Assert.AreEqual(1.4995260942223139, range2.Max); Assert.AreEqual(0.0090865355213001677, range3.Min); Assert.AreEqual(1.4995260942223139, range3.Max); }
public void Bug7953() { // Fitting this sample to a Weibull caused a NonconvergenceException in the root finder that was used inside the fit method. // The underlying problem was that our equation to solve involved x^k and k ~ 2000 and (~12)^(~2000) overflows double // so all the quantities became Infinity and the root-finder never converged. We changed the algorithm to operate on // w = log x - <log x> which keeps quantities much smaller. Sample sample = new Sample( 12.824, 12.855, 12.861, 12.862, 12.863, 12.864, 12.865, 12.866, 12.866, 12.866, 12.867, 12.867, 12.868, 12.868, 12.870, 12.871, 12.871, 12.871, 12.871, 12.872, 12.876, 12.878, 12.879, 12.879, 12.881 ); WeibullFitResult result = WeibullDistribution.FitToSample(sample); Console.WriteLine("{0} {1}", result.Scale, result.Shape); Console.WriteLine(result.GoodnessOfFit.Probability); }
public void TestDistributionWeibull() { IDoubleDistribution dist = new WeibullDistribution(m_model, "WeibullDistribution", Guid.NewGuid(), 2, 0, 2.0); Assert.IsTrue(dist.GetValueWithCumulativeProbability(0.50) == 1.6651092223153954); dist.SetCDFInterval(0.5, 0.5); Assert.IsTrue(dist.GetNext() == 1.6651092223153954); dist.SetCDFInterval(0.0, 1.0); System.IO.StreamWriter tw = new System.IO.StreamWriter(Environment.GetEnvironmentVariable("TEMP") + "\\DistributionWeibull.csv"); Debug.WriteLine("Generating raw data."); int DATASETSIZE = 1500000; double[] rawData = new double[DATASETSIZE]; for (int x = 0; x < DATASETSIZE; x++) { rawData[x] = dist.GetNext(); //tw.WriteLine(rawData[x]); } Debug.WriteLine("Performing histogram analysis."); Histogram1D_Double hist = new Histogram1D_Double(rawData, 0, 7.5, 100, "distribution"); hist.LabelProvider = new LabelProvider(((Histogram1D_Double)hist).DefaultLabelProvider); hist.Recalculate(); Debug.WriteLine("Writing data dump file."); int[] bins = (int[])hist.Bins; for (int i = 0; i < bins.Length; i++) { //Debug.WriteLine(hist.GetLabel(new int[]{i}) + ", " + bins[i]); tw.WriteLine(hist.GetLabel(new int[] { i }) + ", " + bins[i]); } tw.Flush(); tw.Close(); if (m_visuallyVerify) { System.Diagnostics.Process.Start("excel.exe", Environment.GetEnvironmentVariable("TEMP") + "\\DistributionWeibull.csv"); } }
public void TestWeibullDistribution() { double[][] para = { new double[] { 1.5, 1.75, 0.762628880480291575561159, 0.424377229596168368465272, 3.63669361568547473062272, 0.061781371833876567930871 } }; for (int i = 0; i < para.Length; i++) { var tester = new ContDistTester(para[i], delegate(double a, double b) { var ret = new WeibullDistribution { Alpha = a, Lambda = b }; return(ret); } ); tester.Test(1E-14); } }
/// <summary> /// Sets the distribution for operations using the current genrator /// </summary> /// <param name="distx">Distx.</param> public void setDistribution(distributions distx, Dictionary <string, double> args) { //TODO check arguments to ensure they are making a change to the distribution //otherwise throw an exception see laplace as a example of implementing this switch (distx) { case distributions.Bernoili: BernoulliDistribution x0 = new BernoulliDistribution(gen); if (args.ContainsKey("alpha")) { x0.Alpha = args["alpha"]; } else { throw new System.Exception("for Bernoili distribution you must provide an alpha"); } dist = x0; break; case distributions.Beta: BetaDistribution x1 = new BetaDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x1.Alpha = args["alpha"]; x1.Beta = args["beta"]; } else { throw new System.Exception(" for beta distribution you must provide alpha and beta"); } dist = x1; break; case distributions.BetaPrime: BetaPrimeDistribution x2 = new BetaPrimeDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x2.Alpha = args["alpha"]; x2.Beta = args["beta"]; } else { throw new System.Exception(" for betaPrime distribution you must provide alpha and beta"); } dist = x2; break; case distributions.Cauchy: CauchyDistribution x3 = new CauchyDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("gamma")) { x3.Alpha = args["alpha"]; x3.Gamma = args["gamma"]; } else { throw new System.Exception("for cauchy dist you must provide alpha and gamma"); } dist = x3; break; case distributions.Chi: ChiDistribution x4 = new ChiDistribution(gen); if (args.ContainsKey("alpha")) { x4.Alpha = (int)args["alpha"]; } else { throw new System.Exception("for chi you must provide alpha"); } dist = x4; break; case distributions.ChiSquared: ChiSquareDistribution x5 = new ChiSquareDistribution(gen); if (args.ContainsKey("alpha")) { x5.Alpha = (int)args["alpha"]; } else { throw new System.Exception("for chiSquared you must provide alpha"); } dist = x5; break; case distributions.ContinuousUniform: ContinuousUniformDistribution x6 = new ContinuousUniformDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x6.Alpha = args["alpha"]; x6.Beta = args["beta"]; } else { throw new System.Exception("for ContinuousUniform you must provide alpha and beta"); } dist = x6; break; case distributions.DiscreteUniform: DiscreteUniformDistribution x7 = new DiscreteUniformDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x7.Alpha = (int)args["alpha"]; x7.Beta = (int)args["beta"]; } else { throw new System.Exception("for discrete uniform distribution you must provide alpha and beta"); } dist = x7; break; case distributions.Erlang: ErlangDistribution x8 = new ErlangDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("lambda")) { x8.Alpha = (int)args["alpha"]; x8.Lambda = (int)args["lambda"]; } else { throw new System.Exception("for Erlang dist you must provide alpha and lambda"); } dist = x8; break; case distributions.Exponential: ExponentialDistribution x9 = new ExponentialDistribution(gen); if (args.ContainsKey("lambda")) { x9.Lambda = args["lambda"]; } else { throw new System.Exception("for exponential dist you must provide lambda"); } dist = x9; break; case distributions.FisherSnedecor: FisherSnedecorDistribution x10 = new FisherSnedecorDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x10.Alpha = (int)args["alpha"]; x10.Beta = (int)args["beta"]; } else { throw new System.Exception("for FisherSnedecor you must provide alpha and beta"); } dist = x10; break; case distributions.FisherTippett: FisherTippettDistribution x11 = new FisherTippettDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("mu")) { x11.Alpha = args["alpha"]; x11.Mu = args["mu"]; } else { throw new System.Exception("for FisherTippets you must provide alpha and mu"); } dist = x11; break; case distributions.Gamma: GammaDistribution x12 = new GammaDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("theta")) { x12.Alpha = args["alpha"]; x12.Theta = args["theta"]; } else { throw new System.Exception("for Gamma dist you must provide alpha and theta"); } dist = x12; break; case distributions.Geometric: GeometricDistribution x13 = new GeometricDistribution(gen); if (args.ContainsKey("alpha")) { x13.Alpha = args["alpha"]; } else { throw new System.Exception("Geometric distribution requires alpha value"); } dist = x13; break; case distributions.Binomial: BinomialDistribution x14 = new BinomialDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x14.Alpha = args["alpha"]; x14.Beta = (int)args["beta"]; } else { throw new System.Exception("binomial distribution requires alpha and beta"); } dist = x14; break; case distributions.None: break; case distributions.Laplace: LaplaceDistribution x15 = new LaplaceDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("mu")) { if (x15.IsValidAlpha(args["alpha"]) && x15.IsValidMu(args["mu"])) { x15.Alpha = args["alpha"]; x15.Mu = args["mu"]; } else { throw new ArgumentException("alpha must be greater than zero"); } } else { throw new System.Exception("Laplace dist requires alpha and mu"); } dist = x15; break; case distributions.LogNormal: LognormalDistribution x16 = new LognormalDistribution(gen); if (args.ContainsKey("mu") && args.ContainsKey("sigma")) { x16.Mu = args["mu"]; x16.Sigma = args["sigma"]; } else { throw new System.Exception("lognormal distribution requires mu and sigma"); } dist = x16; break; case distributions.Normal: NormalDistribution x17 = new NormalDistribution(gen); if (args.ContainsKey("mu") && args.ContainsKey("sigma")) { x17.Mu = args["mu"]; x17.Sigma = args["sigma"]; } else { throw new System.Exception("normal distribution requires mu and sigma"); } dist = x17; break; case distributions.Pareto: ParetoDistribution x18 = new ParetoDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x18.Alpha = args["alpha"]; x18.Beta = args["beta"]; } else { throw new System.Exception("pareto distribution requires alpha and beta"); } dist = x18; break; case distributions.Poisson: PoissonDistribution x19 = new PoissonDistribution(gen); if (args.ContainsKey("lambda")) { x19.Lambda = args["lambda"]; } else { throw new System.Exception("Poisson distribution requires lambda"); } dist = x19; break; case distributions.Power: PowerDistribution x20 = new PowerDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta")) { x20.Alpha = args["alpha"]; x20.Beta = args["beta"]; } else { throw new System.Exception("Power dist requires alpha and beta"); } dist = x20; break; case distributions.RayLeigh: RayleighDistribution x21 = new RayleighDistribution(gen); if (args.ContainsKey("sigma")) { x21.Sigma = args["sigma"]; } else { throw new System.Exception("Rayleigh dist requires sigma"); } dist = x21; break; case distributions.StudentsT: StudentsTDistribution x22 = new StudentsTDistribution(gen); if (args.ContainsKey("nu")) { x22.Nu = (int)args["nu"]; } else { throw new System.Exception("StudentsT dist requirres nu"); } dist = x22; break; case distributions.Triangular: TriangularDistribution x23 = new TriangularDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("beta") && args.ContainsKey("gamma")) { x23.Alpha = args["alpha"]; x23.Beta = args["beta"]; x23.Gamma = args["gamma"]; } else { throw new System.Exception("Triangular distribution requires alpha, beta and gamma"); } dist = x23; break; case distributions.WeiBull: WeibullDistribution x24 = new WeibullDistribution(gen); if (args.ContainsKey("alpha") && args.ContainsKey("lambda")) { x24.Alpha = args["alpha"]; x24.Lambda = args["lambda"]; } else { throw new System.Exception("WeiBull dist requires alpha and lambda"); } dist = x24; break; default: throw new NotImplementedException("the distribution you want has not yet been implemented " + "you could help everyone out by going and implementing it"); } }
/// <summary> /// Finds the Weibull distribution that best fits the given sample. /// </summary> /// <param name="sample">The sample to fit.</param> /// <returns>The best fit parameters.</returns> /// <exception cref="ArgumentNullException"><paramref name="sample"/> is null.</exception> /// <exception cref="InvalidOperationException"><paramref name="sample"/> contains non-positive values.</exception> /// <exception cref="InsufficientDataException"><paramref name="sample"/> contains fewer than three values.</exception> public static WeibullFitResult FitToWeibull(this IReadOnlyList <double> sample) { if (sample == null) { throw new ArgumentNullException(nameof(sample)); } if (sample.Count < 3) { throw new InsufficientDataException(); } foreach (double value in sample) { if (value <= 0.0) { throw new InvalidOperationException(); } } // The log likelihood function is // \log L = N \log k + (k-1) \sum_i \log x_i - N K \log \lambda - \sum_i \left(\frac{x_i}{\lambda}\right)^k // Taking derivatives, we get // \frac{\partial \log L}{\partial \lambda} = - \frac{N k}{\lambda} + \sum_i \frac{k}{\lambda} \left(\frac{x_i}{\lambda}\right)^k // \frac{\partial \log L}{\partial k} =\frac{N}{k} + \sum_i \left[ 1 - \left(\frac{x_i}{\lambda}\right)^k \right] \log \left(\frac{x_i}{\lambda}\right) // Setting the first expression to zero and solving for \lambda gives // \lambda = \left( N^{-1} \sum_i x_i^k \right)^{1/k} = ( < x^k > )^{1/k} // which allows us to reduce the problem from 2D to 1D. // By the way, using the expression for the moment < x^k > of the Weibull distribution, you can show there is // no bias to this result even for finite samples. // Setting the second expression to zero gives // \frac{1}{k} = \frac{1}{N} \sum_i \left[ \left( \frac{x_i}{\lambda} \right)^k - 1 \right] \log \left(\frac{x_i}{\lambda}\right) // which, given the equation for \lambda as a function of k derived from the first expression, is an implicit equation for k. // It cannot be solved in closed form, but we have now reduced our problem to finding a root in one-dimension. // We need a starting guess for k. // The method of moments equations are not solvable for the parameters in closed form // but the scale parameter drops out of the ratio of the 1/3 and 2/3 quantile points // and the result is easily solved for the shape parameter // k = \frac{\log 2}{\log\left(\frac{x_{2/3}}{x_{1/3}}\right)} double x1 = sample.InverseLeftProbability(1.0 / 3.0); double x2 = sample.InverseLeftProbability(2.0 / 3.0); double k0 = Global.LogTwo / Math.Log(x2 / x1); // Given the shape paramter, we could invert the expression for the mean to get // the scale parameter, but since we have an expression for \lambda from k, we // don't need it. //double s0 = sample.Mean / AdvancedMath.Gamma(1.0 + 1.0 / k0); // Simply handing our 1D function to a root-finder works fine until we start to encounter large k. For large k, // even just computing \lambda goes wrong because we are taking x_i^k which overflows. Horst Rinne, "The Weibull // Distribution: A Handbook" describes a way out. Basically, we first move to variables z_i = \log(x_i) and // then w_i = z_i - \bar{z}. Then lots of factors of e^{k \bar{z}} cancel out and, even though we still do // have some e^{k w_i}, the w_i are small and centered around 0 instead of large and centered around \lambda. //Sample transformedSample = sample.Copy(); //transformedSample.Transform(x => Math.Log(x)); double[] transformedSample = new double[sample.Count]; for (int j = 0; j < sample.Count; j++) { transformedSample[j] = Math.Log(sample[j]); } double zbar = transformedSample.Mean(); for (int j = 0; j < transformedSample.Length; j++) { transformedSample[j] -= zbar; } // After this change of variable the 1D function to zero becomes // g(k) = \sum_i ( 1 - k w_i ) e^{k w_i} // It's easy to show that g(0) = n and g(\infinity) = -\infinity, so it must cross zero. It's also easy to take // a derivative // g'(k) = - k \sum_i w_i^2 e^{k w_i} // so we can apply Newton's method. int i = 0; double k1 = k0; while (true) { i++; double g = 0.0; double gp = 0.0; foreach (double w in transformedSample) { double e = Math.Exp(k1 * w); g += (1.0 - k1 * w) * e; gp -= k1 * w * w * e; } double dk = -g / gp; k1 += dk; if (Math.Abs(dk) <= Global.Accuracy * Math.Abs(k1)) { break; } if (i >= Global.SeriesMax) { throw new NonconvergenceException(); } } // The corresponding lambda can also be expressed in terms of zbar and w's. double t = 0.0; foreach (double w in transformedSample) { t += Math.Exp(k1 * w); } t /= transformedSample.Length; double lambda1 = Math.Exp(zbar) * Math.Pow(t, 1.0 / k1); // We need the curvature matrix at the minimum of our log likelihood function // to determine the covariance matrix. Taking more derivatives... // \frac{\partial^2 \log L} = \frac{N k}{\lambda^2} - \sum_i \frac{k(k+1) x_i^k}{\lambda^{k+2}} // = - \frac{N k^2}{\lambda^2} // The second expression follows by inserting the first-derivative-equal-zero relation into the first. // For k=1, this agrees with the variance formula for the mean of the best-fit exponential. // Derivatives involving k are less simple. // We end up needing the means < (x/lambda)^k log(x/lambda) > and < (x/lambda)^k log^2(x/lambda) > double mpl = 0.0; double mpl2 = 0.0; foreach (double x in sample) { double r = x / lambda1; double p = Math.Pow(r, k1); double l = Math.Log(r); double pl = p * l; double pl2 = pl * l; mpl += pl; mpl2 += pl2; } mpl = mpl / sample.Count; mpl2 = mpl2 / sample.Count; // See if we can't do any better here. Transforming to zbar and w's looked ugly, but perhaps it // can be simplified? One interesting observation: if we take expectation values (which gives // the Fisher information matrix) the entries become simple: // B_{\lambda \lambda} = \frac{N k^2}{\lambda^2} // B_{\lambda k} = -\Gamma'(2) \frac{N}{\lambda} // B_{k k } = [1 + \Gamma''(2)] \frac{N}{k^2} // Would it be bad to just use these directly? // Construct the curvature matrix and invert it. SymmetricMatrix C = new SymmetricMatrix(2); C[0, 0] = sample.Count * MoreMath.Sqr(k1 / lambda1); C[0, 1] = -sample.Count * k1 / lambda1 * mpl; C[1, 1] = sample.Count * (1.0 / MoreMath.Sqr(k1) + mpl2); CholeskyDecomposition CD = C.CholeskyDecomposition(); if (CD == null) { throw new DivideByZeroException(); } C = C.Inverse(); // Do a KS test to compare sample to best-fit distribution WeibullDistribution distribution = new WeibullDistribution(lambda1, k1); TestResult test = sample.KolmogorovSmirnovTest(distribution); // return the result return(new WeibullFitResult(lambda1, k1, C, distribution, test)); }
/// <summary> /// Returns a new line chart plotting the specified function of the given distribution for 0.0001 <= p <= 0.9999. /// </summary> /// <param name="dist">The distribution.</param> /// <param name="function">The distribution function to plot.</param> /// <param name="numInterpolatedValues">The number of interpolated values.</param> /// <returns>A new chart.</returns> public static ChartControl ToChart( WeibullDistribution dist, DistributionFunction function = DistributionFunction.PDF, int numInterpolatedValues = 100 ) { ChartControl chart = GetDefaultChart(); Update( ref chart, dist, function, numInterpolatedValues ); return chart; }
public void MedianTest() { WeibullDistribution target = new WeibullDistribution(1.52, 0.6); Assert.AreEqual(target.Median, target.InverseDistributionFunction(0.5), 1e-8); }
/// <summary> /// Updates the given chart with the specified distribution. /// </summary> /// <param name="chart">A chart.</param> /// <param name="dist">The distribution.</param> /// <param name="function">The distribution function to plot.</param> /// <param name="numInterpolatedValues">The number of interpolated values.</param> /// <returns>A new chart.</returns> /// <remarks> /// Plots the specified function of the given distribution for 0.0001 <= p <= 0.9999. /// <br/> /// Titles are added only if chart does not currently contain any titles. /// <br/> /// chart.Series[0] is replaced, or added if necessary. /// </remarks> public static void Update( ref ChartControl chart, WeibullDistribution dist, DistributionFunction function = DistributionFunction.PDF, int numInterpolatedValues = 100 ) { List<string> titles = new List<string>() { "WeibullDistribution", String.Format("scale={0}, shape={1}", dist.Scale, dist.Shape) }; UpdateContinuousDistribution( ref chart, dist, titles, function, numInterpolatedValues ); }
/// <summary> /// Shows a new chart in a default form. /// </summary> /// <param name="dist">The distribution.</param> /// <param name="function">The distribution function to plot.</param> /// <param name="numInterpolatedValues">The number of interpolated values.</param> /// <remarks> /// Equivalent to: /// <code> /// NMathStatsChart.Show( ToChart( dist, function, numInterpolatedValues ) ); /// </code> /// </remarks> public static void Show( WeibullDistribution dist, DistributionFunction function = DistributionFunction.PDF, int numInterpolatedValues = 100 ) { Show( ToChart( dist, function, numInterpolatedValues ) ); }
//--------------------------------------------------------------------- private static double GenerateRandomNum(Distribution dist, double parameter1, double parameter2) { double randomNum = 0.0; if(dist == Distribution.normal) { NormalDistribution randVar = new NormalDistribution(RandomNumberGenerator.Singleton); randVar.Mu = parameter1; // mean randVar.Sigma = parameter2; // std dev randomNum = randVar.NextDouble(); } if(dist == Distribution.lognormal) { LognormalDistribution randVar = new LognormalDistribution(RandomNumberGenerator.Singleton); randVar.Mu = parameter1; // mean randVar.Sigma = parameter2; // std dev randomNum = randVar.NextDouble(); } if(dist == Distribution.gamma) { GammaDistribution randVar = new GammaDistribution(RandomNumberGenerator.Singleton); randVar.Alpha = parameter1; // mean randVar.Theta = parameter2; // std dev randomNum = randVar.NextDouble(); } if(dist == Distribution.Weibull) { WeibullDistribution randVar = new WeibullDistribution(RandomNumberGenerator.Singleton); randVar.Alpha = parameter1; // mean randVar.Lambda = parameter2; // std dev randomNum = randVar.NextDouble(); } return randomNum; }
/* public Distribution( DistributionType name, double value1, double value2 ) { this.name = name; this.value1 = value1; this.value2 = value2; }*/ //--------------------------------------------------------------------- public static double GenerateRandomNum(DistributionType dist, double parameter1, double parameter2) { double randomNum = 0.0; /*if(dist == DistributionType.Normal) { NormalDistribution randVar = new NormalDistribution(RandomNumberGenerator.Singleton); randVar.Mu = parameter1; // mean randVar.Sigma = parameter2; // std dev randomNum = randVar.NextDouble(); } if(dist == DistributionType.Lognormal) { LognormalDistribution randVar = new LognormalDistribution(RandomNumberGenerator.Singleton); randVar.Mu = parameter1; // mean randVar.Sigma = parameter2; // std dev randomNum = randVar.NextDouble(); }*/ if(dist == DistributionType.Weibull) { WeibullDistribution randVar = new WeibullDistribution(RandomNumberGenerator.Singleton); randVar.Alpha = parameter1; // mean randVar.Lambda = parameter2; // std dev randomNum = randVar.NextDouble(); } if(dist == DistributionType.Gamma) { GammaDistribution randVar = new GammaDistribution(RandomNumberGenerator.Singleton); randVar.Alpha = parameter1; // mean randVar.Theta = parameter2; // std dev randomNum = randVar.NextDouble(); } if(dist == DistributionType.Beta) { BetaDistribution randVar = new BetaDistribution(RandomNumberGenerator.Singleton); randVar.Alpha = parameter1; // mean randVar.Beta = parameter2; // std dev randomNum = randVar.NextDouble(); } return randomNum; }