A game about forced loneliness, made by TACStudios
1using System; 2using static System.Math; 3 4namespace Unity.PerformanceTesting.Statistics 5{ 6 static class StudentDistributionHelper 7 { 8 public static double InverseTwoTailedStudent(double p, double n) 9 { 10 var lower = 0.0; 11 var upper = 1000.0; 12 while (upper - lower > 1e-9) 13 { 14 var t = (lower + upper) / 2; 15 var p2 = TwoTailedStudent(t, n); 16 if (p2 < p) 17 upper = t; 18 else 19 lower = t; 20 } 21 22 return (lower + upper) / 2; 23 } 24 25 /// <summary> 26 /// ACM Algorithm 395: Student's t-distribution 27 /// 28 /// Evaluates the two-tail probability P(t|n) that t is exceeded 29 /// in magnitude for Student's t-distribution with n degrees of freedom. 30 /// 31 /// http://dl.acm.org/citation.cfm?id=355599 32 /// </summary> 33 /// <param name="t">t-value, t > 0</param> 34 /// <param name="n">Degree of freedom, n >= 1</param> 35 /// <returns>2-tail p-value</returns> 36 static double TwoTailedStudent(double t, double n) 37 { 38 if (t < 0) 39 throw new ArgumentOutOfRangeException(nameof(t), "t should be >= 0"); 40 if (n < 1) 41 throw new ArgumentOutOfRangeException(nameof(n), "n should be >= 1"); 42 43 t = t * t; 44 var y = t / n; 45 var b = y + 1.0; 46 var nn = (int)Round(n); 47 if (Abs(n - nn) > 1e-9 || n >= 20 || t < n && n > 200) 48 { 49 if (y > 1.0e-6) 50 y = Log(b); 51 var a = n - 0.5; 52 b = 48.0 * (a * a); 53 y = a * y; 54 y = (((((-0.4 * y - 3.3) * y - 24.0) * y - 85.5) / (0.8 * (y * y) + 100.0 + b) + y + 3.0) / b + 1.0) * Sqrt(y); 55 return 2 * NormalDistributionHelper.Gauss(-y); 56 } 57 58 { 59 double z = 1; 60 61 double a; 62 if (n < 20 && t < 4.0) 63 { 64 y = Sqrt(y); 65 a = y; 66 if (nn == 1) 67 a = 0; 68 } 69 else 70 { 71 a = Sqrt(b); 72 y = a * nn; 73 var j = 0; 74 while (Abs(a - z) > 0) 75 { 76 j += 2; 77 z = a; 78 y *= (j - 1) / (b * j); 79 a += y / (nn + j); 80 } 81 82 nn += 2; 83 z = 0; 84 y = 0; 85 a = -a; 86 } 87 88 while (true) 89 { 90 nn -= 2; 91 if (nn > 1) 92 a = (nn - 1) / (b * nn) * a + y; 93 else 94 break; 95 } 96 97 a = nn == 0 ? a / Sqrt(b) : (Atan(y) + a / b) * 2 / PI; 98 return z - a; 99 } 100 } 101 } 102}