public static double TestImpl(double[][] data, out double statistic, double s0, out double pvalS0, out double[] gmeans) { List <int> v = new List <int>(); for (int i = 0; i < data.Length; i++) { if (data[i].Length > 1) { v.Add(i); } } data = ArrayUtils.SubArray(data, v.ToArray()); int g = data.Length; if (g < 2) { statistic = 0; pvalS0 = 1; gmeans = null; return(1); } gmeans = new double[g]; double totMean = 0; int n = 0; for (int i = 0; i < g; i++) { gmeans[i] = ArrayUtils.Mean(data[i]); totMean += gmeans[i] * data[i].Length; n += data[i].Length; } totMean /= n; double ssw = 0; double ssb = 0; for (int i = 0; i < g; i++) { ssb += data[i].Length * (gmeans[i] - totMean) * (gmeans[i] - totMean); for (int j = 0; j < data[i].Length; j++) { ssw += (data[i][j] - gmeans[i]) * (data[i][j] - gmeans[i]); } } if (ssw <= 0.0) { statistic = 0; pvalS0 = 1; return(1); } double dw = n - g; double db = g - 1; statistic = ssb * dw / db / ssw; double gms = GetGeomMeanSquared(data); double denom = n * db * ssw / dw / gms; double statisticS0 = n * ssb / gms / (Math.Sqrt(denom) + s0) / (Math.Sqrt(denom) + s0); pvalS0 = IncompleteBeta.Value(dw * 0.5, db * 0.5, dw / (dw + db * statisticS0)); return(IncompleteBeta.Value(dw * 0.5, db * 0.5, dw / (dw + db * statistic))); }
public static double StudentDistributionInversed(int k, double p) { double z; double rk = k; if (p is > .25 and < .75) { if (Math.Abs(p - .5) < Eps) { return(0); } z = IncompleteBeta.IncompleteBetaInversed(.5, .5 * rk, Math.Abs(1 - 2 * p)); var t = Math.Sqrt(rk * z / (1 - z)); return(p < 0 ? -t : t); } var r_flg = -1; if (p >= .5) { p = 1 - p; r_flg = 1; } z = IncompleteBeta.IncompleteBetaInversed(.5 * rk, .5, 2 * p); return(__MaxRealNumber * z < rk ? r_flg * __MaxRealNumber : r_flg *Math.Sqrt(rk / z - rk)); }
public static double StudentDistribution(int k, double t) { if (Math.Abs(t - 0) < Eps) { return(.5); } if (t < -2) { return(.5 * IncompleteBeta.IncompleteBetaValue(.5 * k, .5, k / (k + t * t))); } var x = t < 0 ? -t : t; double rk = k; var z = 1 + x * x / rk; double tz; double f; double p; int j; if (k % 2 != 0) { var x_sqk = x / Math.Sqrt(rk); p = Math.Atan(x_sqk); if (k > 1) { f = 1; tz = 1; j = 3; while (j <= k - 2 & tz / f > Eps) { tz *= (j - 1) / (z * j); f += tz; j += 2; } p += f * x_sqk / z; } p *= 2 / Consts.pi; } else { f = tz = 1; j = 2; while (j <= k - 2 & tz / f > Eps) { tz *= (j - 1) / (z * j); f += tz; j += 2; } p = f * x / Math.Sqrt(z * rk); } return(.5 + .5 * (t < 0 ? -p : p)); }
/************************************************************************* * Student's t distribution * * Computes the integral from minus infinity to t of the Student * t distribution with integer k > 0 degrees of freedom: * * t * - | | | - | 2 -(k+1)/2 | ( (k+1)/2 ) | ( x ) | ---------------------- | ( 1 + --- ) dx | - | ( k ) | sqrt( k pi ) | ( k/2 ) | | | | - | -inf. | | Relation to incomplete beta integral: | | 1 - stdtr(k,t) = 0.5 * incbet( k/2, 1/2, z ) | where | z = k/(k + t**2). | | For t < -2, this is the method of computation. For higher t, | a direct method is derived from integration by parts. | Since the function is symmetric about t=0, the area under the | right tail of the density is found by calling the function | with -t instead of t. | | ACCURACY: | | Tested at random 1 <= k <= 25. The "domain" refers to t. | Relative error: | arithmetic domain # trials peak rms | IEEE -100,-2 50000 5.9e-15 1.4e-15 | IEEE -2,100 500000 2.7e-15 4.9e-17 | | Cephes Math Library Release 2.8: June, 2000 | Copyright 1984, 1987, 1995, 2000 by Stephen L. Moshier *************************************************************************/ public static double Cumulative(int k, double t) { if (k <= 0) { throw new Exception("Negative value for k in Student's distribution"); } if (t == 0) { return(0.5); } double rk; double z; if (t < -2.0) { rk = k; z = rk / (rk + t * t); return(0.5 * IncompleteBeta.Value(0.5 * rk, 0.5, z)); } double x; if (t < 0) { x = -t; } else { x = t; } rk = k; z = 1.0 + x * x / rk; double p; if (k % 2 != 0) { double xsqk = x / Math.Sqrt(rk); p = Math.Atan(xsqk); if (k > 1) { double f = 1.0; double tz = 1.0; int j = 3; while (j <= k - 2 & tz / f > epsilon) { tz = tz * ((j - 1) / (z * j)); f = f + tz; j = j + 2; } p = p + f * xsqk / z; } p = p * 2.0 / Math.PI; } else { double f = 1.0; double tz = 1.0; int j = 2; while (j <= k - 2 & tz / f > epsilon) { tz = tz * ((j - 1) / (z * j)); f = f + tz; j = j + 2; } p = f * x / Math.Sqrt(z * rk); } if (t < 0) { p = -p; } return(0.5 + 0.5 * p); }