public void WScore() { int[] signs = { -1, -1, +1, -1, +1, +1, +1, +1, +1, +1, +1, +1 }; double[] ranks = { 1, 2, 3, 4, 5.5, 5.5, 7, 8, 9, 10, 11, 12 }; double[] diffs = { 0.1, 0.2, 0.3, 0.6, 1.5, 1.5, 1.8, 2.0, 2.1, 2.3, 2.6, 12.4 }; double wm, wp, u; { double expected = 7; wm = WilcoxonDistribution.WNegative(signs, ranks); Assert.AreEqual(expected, wm); } { double expected = 71; wp = WilcoxonDistribution.WPositive(signs, ranks); Assert.AreEqual(expected, wp); } { double expected = 7; u = WilcoxonDistribution.WMinimum(signs, ranks); Assert.AreEqual(expected, u); } { double n = signs.Length; double total = wm + wp; double expected = (n * (n + 1)) / 2; Assert.AreEqual(expected, total); } }
public void CumulativeExactTest() { // example from https://onlinecourses.science.psu.edu/stat414/node/319 double[] ranks = { 22, 2, 13, 24, 16, 15, 25, 10, 9, 11, 5, 17, 12, 20, 14, 30, 8, 6, 26, 19, 29, 27,3, 28, 7, 21, 23, 1, 18, 4 }; WilcoxonDistribution target = new WilcoxonDistribution(ranks); Assert.AreEqual(232.5, target.Mean); Assert.AreEqual(2363.75, target.Variance); Assert.AreEqual(Math.Sqrt(2363.75), target.StandardDeviation); double actual = target.DistributionFunction(200); double expected = 0.2546; Assert.AreEqual(expected, actual, 1e-2); double inv = target.InverseDistributionFunction(actual); Assert.AreEqual(200, inv); }
public void ConstructorTest2() { double[] ranks = { 1, 2, 3, 4, 5.5, 5.5, 7, 8, 9, 10, 11, 12 }; var W = new WilcoxonDistribution(ranks, forceExact: true); double mean = W.Mean; // 39 double median = W.Median; // 39 double var = W.Variance; // 162.5 double cdf = W.DistributionFunction(w: 42); // 0.582763671875 double pdf = W.ProbabilityDensityFunction(w: 42); // 0.014404296875 double lpdf = W.LogProbabilityDensityFunction(w: 42); // -4.2402287228136233 double ccdf = W.ComplementaryDistributionFunction(x: 42); // 0.417236328125 double icdf = W.InverseDistributionFunction(p: cdf); // 41.965447500067114 double icdf2 = W.InverseDistributionFunction(p: 0.5); // 39.000000487005138 double hf = W.HazardFunction(x: 42); // 0.03452311293153891 double chf = W.CumulativeHazardFunction(x: 42); // 0.87410248360375287 string str = W.ToString(); // "W+(x; R)" Assert.AreEqual(39.0, mean); Assert.AreEqual(39.0, median, 1e-6); Assert.AreEqual(162.5, var); Assert.AreEqual(0.87410248360375287, chf); Assert.AreEqual(0.582763671875, cdf); Assert.AreEqual(0.014404296875, pdf); Assert.AreEqual(-4.2402287228136233, lpdf); Assert.AreEqual(0.03452311293153891, hf); Assert.AreEqual(0.417236328125, ccdf); Assert.AreEqual(42, icdf, 0.05); Assert.AreEqual("W+(x; R)", str); }
public void ConstructorTest() { double[] ranks = { 1, 2, 3, 4, 5.5, 5.5, 7, 8, 9, 10, 11, 12 }; var W = new WilcoxonDistribution(ranks); double mean = W.Mean; // 39.0 double median = W.Median; // 38.5 double var = W.Variance; // 162.5 double cdf = W.DistributionFunction(w: 42); // 0.60817384423279575 double pdf = W.ProbabilityDensityFunction(w: 42); // 0.38418508862319295 double lpdf = W.LogProbabilityDensityFunction(w: 42); // 0.38418508862319295 double ccdf = W.ComplementaryDistributionFunction(x: 42); // 0.39182615576720425 double icdf = W.InverseDistributionFunction(p: cdf); // 42 double icdf2 = W.InverseDistributionFunction(p: 0.5); // 42 double hf = W.HazardFunction(x: 42); // 0.98049883339449373 double chf = W.CumulativeHazardFunction(x: 42); // 0.936937017743799 string str = W.ToString(); // "W+(x; R)" Assert.AreEqual(39.0, mean); Assert.AreEqual(38.5, median, 1e-6); Assert.AreEqual(162.5, var); Assert.AreEqual(0.936937017743799, chf); Assert.AreEqual(0.60817384423279575, cdf); Assert.AreEqual(0.38418508862319295, pdf); Assert.AreEqual(-0.95663084089698047, lpdf); Assert.AreEqual(0.98049883339449373, hf); Assert.AreEqual(0.39182615576720425, ccdf); Assert.AreEqual(42, icdf, 1e-6); Assert.AreEqual("W+(x; R)", str); }
public void MedianTest() { double[] ranks = { 1, 2, 3, 7 }; WilcoxonDistribution target = new WilcoxonDistribution(ranks); Assert.AreEqual(target.Median, target.InverseDistributionFunction(0.5)); }
public void MedianTest_approximation() { double[] ranks = { 1, 2, 3, 7 }; WilcoxonDistribution target = new WilcoxonDistribution(ranks, exact: false); Assert.IsFalse(target.Exact); Assert.AreEqual(target.Median, target.InverseDistributionFunction(0.5)); }
/// <summary> /// Performs a Wilcoxon signed rank test. /// </summary> /// <param name="x">The values of the first variable.</param> /// <param name="y">The values of the second variable.</param> /// <returns>The result of the test.</returns> /// <remarks> /// <para>The Wilcoxon signed rank test is a non-parametric alternative to the /// paired t-test (<see cref="PairedStudentTTest"/>). Given two measurements on /// the same subjects, this method tests for changes in the distribution between /// the two measurements. It is sensitive primarily to shifts in the median. /// Note that the distributions of the individual measurements /// may be far from normal, and may be different for each subject.</para> /// </remarks> /// <exception cref="ArgumentNullException"><paramref name="x"/> or <paramref name="y"/> is <see langword="null"/>.</exception> /// <exception cref="DimensionMismatchException"><paramref name="x"/> and <paramref name="y"/> do not contain the same number of entries.</exception> /// <exception cref="InsufficientDataException">There are fewer than two data points.</exception> /// <seealso href="https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test"/> public static TestResult WilcoxonSignedRankTest(IReadOnlyList <double> x, IReadOnlyList <double> y) { if (x == null) { throw new ArgumentNullException(nameof(x)); } if (y == null) { throw new ArgumentNullException(nameof(y)); } if (x.Count != y.Count) { throw new DimensionMismatchException(); } int n = x.Count; if (n < 2) { throw new InsufficientDataException(); } double[] z = new double[n]; for (int i = 0; i < z.Length; i++) { z[i] = x[i] - y[i]; } Array.Sort(z, (xValue, yValue) => Math.Abs(xValue).CompareTo(Math.Abs(yValue))); int W = 0; for (int i = 0; i < z.Length; i++) { if (z[i] > 0.0) { W += (i + 1); } } if (n < 32) { DiscreteDistribution wDistribution = new WilcoxonDistribution(n); return(new TestResult("W", W, wDistribution, TestType.TwoTailed)); } else { double mu = n * (n + 1.0) / 4.0; double sigma = Math.Sqrt(mu * (2.0 * n + 1.0) / 6.0); ContinuousDistribution wDistribution = new NormalDistribution(mu, sigma); return(new TestResult("W", W, wDistribution, TestType.TwoTailed)); } }
public void ConstructorTest2() { double[] ranks = { 1, 2, 3, 4, 5.5, 5.5, 7, 8, 9, 10, 11, 12 }; var W = new WilcoxonDistribution(ranks, exact: true); double mean = W.Mean; // 39 double median = W.Median; // 39 double var = W.Variance; // 162.5 double cdf = W.DistributionFunction(x: 42); // 0.582763671875 double pdf = W.ProbabilityDensityFunction(x: 42); // 0.014404296875 double lpdf = W.LogProbabilityDensityFunction(x: 42); // -4.2402287228136233 double ccdf = W.ComplementaryDistributionFunction(x: 42); // 0.417236328125 double icdf = W.InverseDistributionFunction(p: cdf); // 41.965447500067114 double icdf2 = W.InverseDistributionFunction(p: 0.5); // 39.000000487005138 double hf = W.HazardFunction(x: 42); // 0.03452311293153891 double chf = W.CumulativeHazardFunction(x: 42); // 0.87410248360375287 string str = W.ToString(); // "W+(x; R)" Assert.AreEqual(39.0, mean); Assert.AreEqual(39.0, median, 1e-6); Assert.AreEqual(162.5, var); Assert.AreEqual(0.87410248360375287, chf); Assert.AreEqual(0.59716796875, cdf, 1e-5); Assert.AreEqual(0.014404296875, pdf, 1e-8); Assert.AreEqual(-4.2402287228136233, lpdf); Assert.AreEqual(0.03452311293153891, hf); Assert.AreEqual(0.417236328125, ccdf); Assert.AreEqual(42.5, icdf, 0.05); Assert.AreEqual("W+(x; R)", str); var range1 = W.GetRange(0.95); var range2 = W.GetRange(0.99); var range3 = W.GetRange(0.01); Assert.AreEqual(17.999999736111114, range1.Min, 1e-6); Assert.AreEqual(60.000000315408002, range1.Max, 1e-6); Assert.AreEqual(10.000000351098127, range2.Min, 1e-6); Assert.AreEqual(67.99999981945885, range2.Max, 1e-6); Assert.AreEqual(10.000000351098119, range3.Min, 1e-6); Assert.AreEqual(67.99999981945885, range3.Max, 1e-6); }
public void ProbabilityTest() { // Example from https://onlinecourses.science.psu.edu/stat414/node/319 double[] ranks = { 1, 2, 3 }; WilcoxonDistribution target = new WilcoxonDistribution(ranks); double[] expected = { 1 / 8.0, 1 / 8.0, 1 / 8.0, 2 / 8.0, 1 / 8.0, 1 / 8.0, 1 / 8.0 }; for (int i = 0; i < expected.Length; i++) { // P(W=i) double actual = target.ProbabilityDensityFunction(i); Assert.AreEqual(expected[i], actual); } }
public void CumulativeTest() { // Example from https://onlinecourses.science.psu.edu/stat414/node/319 double[] ranks = { 1, 2, 3 }; WilcoxonDistribution target = new WilcoxonDistribution(ranks); double[] probabilities = { 1 / 8.0, 1 / 8.0, 1 / 8.0, 2 / 8.0, 1 / 8.0, 1 / 8.0, 1 / 8.0 }; double[] expected = Accord.Math.Matrix.CumulativeSum(probabilities); for (int i = 0; i < expected.Length; i++) { // P(W<=i) double actual = target.DistributionFunction(i); Assert.AreEqual(expected[i], actual); } }
public void icdf() { var dist = new WilcoxonDistribution(1); double[] percentiles = Vector.Range(0.0, 1.0, stepSize: 0.1); for (int i = 0; i < percentiles.Length; i++) { double x = percentiles[i]; double icdf = dist.InverseDistributionFunction(x); double cdf = dist.DistributionFunction(icdf); double iicdf = dist.InverseDistributionFunction(cdf); double iiicdf = dist.DistributionFunction(iicdf); Assert.AreEqual(iicdf, icdf, 1e-5); Assert.AreEqual(x, cdf, 1e-5); Assert.AreEqual(iiicdf, cdf, 1e-5); } }
public void ApproximationTest() { double[] m = Matrix.Magic(5).Reshape().Get(0, 20); double[] samples = m.Rank(); var exact = new WilcoxonDistribution(samples, exact: true); var approx = new WilcoxonDistribution(samples, exact: false); var nd = NormalDistribution.Estimate(exact.Table); Assert.AreEqual(nd.Mean, exact.Mean, 1e-10); Assert.AreEqual(nd.Variance, exact.Variance, 1e-3); foreach (double x in Vector.Range(0, 100)) { double e = approx.DistributionFunction(x); double a = exact.DistributionFunction(x); if (e > 0.25) { Assert.AreEqual(e, a, 0.1); } else { Assert.AreEqual(e, a, 0.01); } } foreach (double x in Vector.Range(0, 100)) { double e = approx.ComplementaryDistributionFunction(x); double a = exact.ComplementaryDistributionFunction(x); if (e > 0.25) { Assert.AreEqual(e, a, 0.1); } else { Assert.AreEqual(e, a, 0.01); } } }
public void ConstructorTest() { double[] ranks = { 1, 2, 3, 4, 5.5, 5.5, 7, 8, 9, 10, 11, 12 }; var W = new WilcoxonDistribution(ranks); double mean = W.Mean; // 39.0 double median = W.Median; // 38.5 double var = W.Variance; // 162.5 double mode = W.Mode; // 39.0 double cdf = W.DistributionFunction(x: 42); // 0.60817384423279575 double pdf = W.ProbabilityDensityFunction(x: 42); // 0.38418508862319295 double lpdf = W.LogProbabilityDensityFunction(x: 42); // 0.38418508862319295 double ccdf = W.ComplementaryDistributionFunction(x: 42); // 0.39182615576720425 double icdf = W.InverseDistributionFunction(p: cdf); // 42 double icdf2 = W.InverseDistributionFunction(p: 0.5); // 42 double hf = W.HazardFunction(x: 42); // 0.98049883339449373 double chf = W.CumulativeHazardFunction(x: 42); // 0.936937017743799 string str = W.ToString(); // "W+(x; R)" Assert.AreEqual(39.0, mean); Assert.AreEqual(39, median, 1e-6); Assert.AreEqual(39.0, mode, 1e-8); Assert.AreEqual(162.5, var); Assert.AreEqual(0.87410248360375287, chf, 1e-8); Assert.AreEqual(0.59716796875, cdf, 1e-8); Assert.AreEqual(0.014404296875, pdf, 1e-8); Assert.AreEqual(-4.2402287228136233, lpdf, 1e-8); Assert.AreEqual(0.03452311293153891, hf, 1e-8); Assert.AreEqual(0.417236328125, ccdf, 1e-8); Assert.AreEqual(42.5, icdf, 0.05); Assert.AreEqual("W+(x; R)", str); Assert.AreEqual(0, W.Support.Min); Assert.AreEqual(double.PositiveInfinity, W.Support.Max); Assert.AreEqual(W.InverseDistributionFunction(0), W.Support.Min); Assert.AreEqual(W.InverseDistributionFunction(1), W.Support.Max); }
/// <summary> /// Performs a Wilcoxon signed rank test. /// </summary> /// <returns>The result of the test.</returns> /// <remarks> /// <para>The Wilcoxon signed rank test is a non-parametric alternative to the /// paired t-test (<see cref="PairedStudentTTest"/>). Given two measurements on /// the same subjects, this method tests for changes in the distribution between /// the two measurements. It is sensitive primarily to shifts in the median. /// Note that the distributions of the individual measurements /// may be far from normal, and may be different for each subject.</para> /// </remarks> /// <seealso href="https://en.wikipedia.org/wiki/Wilcoxon_signed-rank_test"/> public TestResult WilcoxonSignedRankTest() { int n = this.Count; if (n < 2) { throw new InsufficientDataException(); } double[] z = new double[n]; for (int i = 0; i < z.Length; i++) { z[i] = xData[i] - yData[i]; } Array.Sort(z, (x, y) => Math.Abs(x).CompareTo(Math.Abs(y))); int W = 0; for (int i = 0; i < z.Length; i++) { if (z[i] > 0.0) { W += (i + 1); } } ContinuousDistribution nullDistribution; if (Count < 32) { DiscreteDistribution wilcoxon = new WilcoxonDistribution(n); nullDistribution = new DiscreteAsContinuousDistribution(wilcoxon); } else { double mu = n * (n + 1.0) / 4.0; double sigma = Math.Sqrt(mu * (2.0 * n + 1.0) / 6.0); nullDistribution = new NormalDistribution(mu, sigma); } return(new TestResult("W", W, TestType.TwoTailed, nullDistribution)); }