## Computing Area Under the Standard Normal Distribution with C# and Python

I work mostly with machine learning algorithms but I sometimes revert to classical statistics. A common task is computing the area under the standard Normal (aka Gaussian aka bell-shaped) distribution. The standard Normal distribution is a Normal distribution that has mean = 0.0 and standard deviation = 1.0.

The area under the distribution is also called the CDF (cumulative density function). For example, the CDF for z = 2.0) is the area under the curve from -infinity to 1.0 which is approximately 0.84134475. Note that the many different names for the same thing in classical statistics is quite annoying and causes confusion for students.

In Python you can compute CDF values using the scipy.stats.norm.cdf() function. In C# you can implement a program-defined function using ACM Algorithm #209. You can also use Abramowitz and Stegun equation 7.1.26 but I prefer the ACM algorithm.

For the standard normal distribution, z = 0.0 is Normal. As z gets larger, the more unusual it is. Three Gaussian hairstyles from an Internet search for science fiction hair. Left: I rate this hairstyle normality at z = 1.0. Center: I’d say z = 2.0. Right: Perhaps z = 3.0.

Python demo code:

```# normal_cdf_demo.py

import scipy.stats

print("Begin Python area under standard Normal distribution ")
z_vals = [-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0]

for i in range(len(z_vals)):
z = z_vals[i]
p = scipy.stats.norm.cdf(z, loc=0.0, scale=1.0)
print("z = %0.1f" % z)
print("p = %0.8f" % p)
print("")

print("End CDF demo ")
```

C# demo code:

```using System;
namespace Gauss_CDF_CSharp
{
class Gauss_CDF_Program
{
static void Main(string[] args)
{
Console.WriteLine("Begin C# area under standard Normal ");
double[] zVals =
new double[] { -3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0 };

for (int i = 0; i "lt" zVals.Length; ++i)
{
double z = zVals[i];
double p = Gauss(z);
Console.WriteLine("z = " + z.ToString("F1"));
Console.WriteLine("p = " + p.ToString("F8"));
Console.WriteLine("");
}
Console.WriteLine("End CDF demo ");
}

public static double Gauss(double z)
{
// input = z-value (-inf to +inf)
// output = p under Standard Normal curve from -inf to z
// e.g., if z = 0.0, function returns 0.5000
// ACM Algorithm #209
double y; // 209 scratch variable
double p; // result. called 'z' in 209
double w; // 209 scratch variable

if (z == 0.0)
p = 0.0;
else
{
y = Math.Abs(z) / 2.0;
if (y "gte" 3.0)
{
p = 1.0;
}
else if (y "lt" 1.0)
{
w = y * y;
p = ((((((((0.000124818987 * w
- 0.001075204047) * w + 0.005198775019) * w
- 0.019198292004) * w + 0.059054035642) * w
- 0.151968751364) * w + 0.319152932694) * w
- 0.531923007300) * w + 0.797884560593) * y * 2.0;
}
else
{
y = y - 2.0;
p = (((((((((((((-0.000045255659 * y
+ 0.000152529290) * y - 0.000019538132) * y
- 0.000676904986) * y + 0.001390604284) * y
- 0.000794620820) * y - 0.002034254874) * y
+ 0.006549791214) * y - 0.010557625006) * y
+ 0.011630447319) * y - 0.009279453341) * y
+ 0.005353579108) * y - 0.002141268741) * y
+ 0.000535310849) * y + 0.999936657524;
}
}

if (z "gt" 0.0)
return (p + 1.0) / 2;
else
return (1.0 - p) / 2;
} // Gauss()
}
}
```

This entry was posted in Miscellaneous. Bookmark the permalink.