Skip to content

Instantly share code, notes, and snippets.

@otac0n
Created May 11, 2018 00:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save otac0n/71a7c33ef7311fcd32fce9098c4b678a to your computer and use it in GitHub Desktop.
Save otac0n/71a7c33ef7311fcd32fce9098c4b678a to your computer and use it in GitHub Desktop.
void Main()
{
GetPassFailRateWithConfidence(10, 2, 0.95).ToString().Dump();
GetPassFailRateWithConfidence(100, 20, 0.95).ToString().Dump();
GetPassFailRateWithConfidence(1000, 200, 0.95).ToString().Dump();
GetPassFailRateWithConfidence(10000, 2000, 0.95).ToString().Dump();
}
public ErrorRate GetPassFailRateWithConfidence(long passes, long fails, double confidence)
{
double fact(long n) => Math.Round(Math.Sqrt(Math.PI * (2 * n + 1.0 / 3)) * Math.Pow(n / Math.E, n));
double nCr(long n, long r) =>
fact(n).Dump() / (fact(r) * fact(n - r));
long gcd(long a, long b) => b > 0
? gcd(b, a % b)
: a;
double nCr2(long n, long r, double factor)
{
if (r > n / 2) r = n - r;
double ans = factor;
for (long i = 1; i <= r; i++)
{
var num = (n - r + i);
var divisor = gcd(num, i);
ans *= (num / divisor);
ans /= (i / divisor);
}
return ans;
}
var total = passes + fails;
var θ = (passes + 0.5) / (total + 1);
double P(long p) =>
nCr2(total, p, Math.Pow(θ, p) * Math.Pow(1 - θ, total - p));
var minThreshold = (1 - confidence) / 2;
var maxThreshold = 1 - minThreshold;
var sum = 0.0;
double? min = default;
double? max = default;
for (var i = 0; i <= total; i++)
{
if (sum >= maxThreshold && max == null)
{
max = (double)i / total;
break;
}
sum += P(i);
//sum.Dump();
if (sum >= minThreshold && min == null)
{
min = (double)i / total;
}
}
if (max == null)
{
max = 1;
}
return new ErrorRate(mean: (double)passes / total, min: min.Value, max: max.Value, confidence: confidence);
}
public class ErrorRate
{
public ErrorRate(double mean, double min, double max, double confidence)
{
this.Mean = mean;
this.Min = min;
this.Max = max;
this.Confidence = confidence;
}
public double Mean { get; }
public double Min { get; }
public double Max { get; }
public double Confidence { get; }
public override string ToString()
{
return $"{this.Mean:P} ({this.Min:P}-{this.Max:P} @{this.Confidence:P})";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment