Standard Normal Distribution z-value function in C#

normal distribution c#
z-score table
normal distribution library c#
normal distribution table
c# cumulative normal distribution function
cdf function in c#
normal distribution curve
z distribution

I been looking at the recent blog post by Jeff Atwood on Alternate Sorting Orders. I tried to convert the code in the post to C# but I ran into an issue. There is no function in .NET that I know of that will return the z-value, given the percentage of area under the standard normal curve. The recommended values to use for the algorithm are 95% and 97.5% which you can look up on the z-value table in any statistics book.

Does anyone know how to implement such a function for all values of z or at least to 6 standard deviations from the mean. One way would be to hard code the values into a dictionary and use a look up but there has to be a way of calculating the exact value. My attempt at solving this was to take a definite integral of the standard normal curve function.

y = (1 / (sqrt(2 * PI))) * e^(-(1/2) * x^2)

This gives me the area under the curve between two x values but then I am stuck… Maybe I am way of base and this is not how you would do it?

Thanks.

Here's some code for the normal distribution written in Python, but it could easily be translated to C# by adding some punctuation. It's just about 15 lines of code.

StatisticFormula.NormalDistribution(Double) Method (System.Web , Returns the probability for the standard normal cumulative distribution function. public: double NormalDistribution(double zValue);. C# Copy. There is no function in .NET that I know of that will return the z-value, given the percentage of area under the standard normal curve. The recommended values to use for the algorithm are 95% and 97.5% which you can look up on the z-value table in any statistics book.

Here's a C# translation of the normal quantile C code used in the stats program R.

/// <summary>
/// Quantile function (Inverse CDF) for the normal distribution.
/// </summary>
/// <param name="p">Probability.</param>
/// <param name="mu">Mean of normal distribution.</param>
/// <param name="sigma">Standard deviation of normal distribution.</param>
/// <param name="lower_tail">If true, probability is P[X <= x], otherwise P[X > x].</param>
/// <param name="log_p">If true, probabilities are given as log(p).</param>
/// <returns>P[X <= x] where x ~ N(mu,sigma^2)</returns>
/// <remarks>See https://svn.r-project.org/R/trunk/src/nmath/qnorm.c</remarks>
public static double QNorm(double p, double mu, double sigma, bool lower_tail, bool log_p)
{
  if (double.IsNaN(p) || double.IsNaN(mu) || double.IsNaN(sigma)) return (p + mu + sigma);
  double ans;
  bool isBoundaryCase = R_Q_P01_boundaries(p, double.NegativeInfinity, double.PositiveInfinity, lower_tail, log_p, out ans);
  if (isBoundaryCase) return (ans);
  if (sigma < 0) return (double.NaN);
  if (sigma == 0) return (mu);

  double p_ = R_DT_qIv(p, lower_tail, log_p);
  double q = p_ - 0.5;
  double r, val;

  if (Math.Abs(q) <= 0.425)  // 0.075 <= p <= 0.925
  {
    r = .180625 - q * q;
    val = q * (((((((r * 2509.0809287301226727 +
               33430.575583588128105) * r + 67265.770927008700853) * r +
             45921.953931549871457) * r + 13731.693765509461125) * r +
           1971.5909503065514427) * r + 133.14166789178437745) * r +
         3.387132872796366608)
    / (((((((r * 5226.495278852854561 +
             28729.085735721942674) * r + 39307.89580009271061) * r +
           21213.794301586595867) * r + 5394.1960214247511077) * r +
         687.1870074920579083) * r + 42.313330701600911252) * r + 1.0);
  }
  else
  {
    r = q > 0 ? R_DT_CIv(p, lower_tail, log_p) : p_;
    r = Math.Sqrt(-((log_p && ((lower_tail && q <= 0) || (!lower_tail && q > 0))) ? p : Math.Log(r)));

    if (r <= 5)              // <==> min(p,1-p) >= exp(-25) ~= 1.3888e-11
    {
      r -= 1.6;
      val = (((((((r * 7.7454501427834140764e-4 +
              .0227238449892691845833) * r + .24178072517745061177) *
            r + 1.27045825245236838258) * r +
           3.64784832476320460504) * r + 5.7694972214606914055) *
         r + 4.6303378461565452959) * r +
        1.42343711074968357734)
       / (((((((r *
                1.05075007164441684324e-9 + 5.475938084995344946e-4) *
               r + .0151986665636164571966) * r +
              .14810397642748007459) * r + .68976733498510000455) *
            r + 1.6763848301838038494) * r +
           2.05319162663775882187) * r + 1.0);
    }
    else                     // very close to  0 or 1 
    {
      r -= 5.0;
      val = (((((((r * 2.01033439929228813265e-7 +
              2.71155556874348757815e-5) * r +
             .0012426609473880784386) * r + .026532189526576123093) *
           r + .29656057182850489123) * r +
          1.7848265399172913358) * r + 5.4637849111641143699) *
        r + 6.6579046435011037772)
       / (((((((r *
                2.04426310338993978564e-15 + 1.4215117583164458887e-7) *
               r + 1.8463183175100546818e-5) * r +
              7.868691311456132591e-4) * r + .0148753612908506148525)
            * r + .13692988092273580531) * r +
           .59983220655588793769) * r + 1.0);
    }
    if (q < 0.0) val = -val;
  }

  return (mu + sigma * val);
}

Some helper methods:

private static bool R_Q_P01_boundaries(double p, double _LEFT_, double _RIGHT_, bool lower_tail, bool log_p, out double ans)
{
  if (log_p)
  {
    if (p > 0.0)
    {
      ans = double.NaN;
      return (true);
    }
    if (p == 0.0)
    {
      ans = lower_tail ? _RIGHT_ : _LEFT_;
      return (true);
    }
    if (p == double.NegativeInfinity)
    {
      ans = lower_tail ? _LEFT_ : _RIGHT_;
      return (true);
    }
  }
  else
  {
    if (p < 0.0 || p > 1.0)
    {
      ans = double.NaN;
      return (true);
    }
    if (p == 0.0)
    {
      ans = lower_tail ? _LEFT_ : _RIGHT_;
      return (true);
    }
    if (p == 1.0)
    {
      ans = lower_tail ? _RIGHT_ : _LEFT_;
      return (true);
    }
  }
  ans = double.NaN;
  return (false);
}

private static double R_DT_qIv(double p, bool lower_tail, bool log_p)
{
  return (log_p ? (lower_tail ? Math.Exp(p) : -ExpM1(p)) : R_D_Lval(p, lower_tail));
}

private static double R_DT_CIv(double p, bool lower_tail, bool log_p)
{
  return (log_p ? (lower_tail ? -ExpM1(p) : Math.Exp(p)) : R_D_Cval(p, lower_tail));
}

private static double R_D_Lval(double p, bool lower_tail) 
{
  return lower_tail ? p : 0.5 - p + 0.5; 
} 

private static double R_D_Cval(double p, bool lower_tail) 
{ 
  return lower_tail ? 0.5 - p + 0.5 : p;
}
private static double ExpM1(double x) 
{
  if (Math.Abs(x) < 1e-5)
     return x + 0.5 * x * x;
  else
     return Math.Exp(x) - 1.0;
 }

In your case, you want mu=0.0, sigma=1.0, lower_tail=true, log_p=false.

StatisticFormula.NormalDistribution(Double) Method (System , The values in the table are calculated using the cumulative distribution function of a standard normal distribution with a mean of zero and a� The distribution has a mean of 0 and a standard deviation of 1. public: double NormalDistribution (double zValue); C#. public double NormalDistribution (double zValue); member this.NormalDistribution : double -> double. Public Function NormalDistribution (zValue As Double) As Double.

Look up implementations of the error function. There was one in all the classic Numerical Recipes in ... books.

How to Use and Create a Z-Table (Standard Normal Table), ZScore Method (Methods, NormalDistribution Class, Extreme. C#. VB. C++. F#. Copy. public double ZScore( double x ). Public Function ZScore The z-score is the value of the sample relative to a standard normal distribution. A z-score measures the deviation of a sample from the mean in units of the standard deviation. The standard normal distribution is a special case of the normal distribution. It is the distribution that occurs when a normal random variable has a mean of zero and a standard deviation of one. The normal random variable of a standard normal distribution is called a standard score or a z score.

For a newer version of MathNet

    //standard normal cumulative distribution function
    static double F(double x)
    {
        MathNet.Numerics.Distributions.Normal result = new MathNet.Numerics.Distributions.Normal();
        return result.CumulativeDistribution(x);
    }

ZScore Method - Methods - NormalDistribution Class, I been looking at the recent blog post by Jeff Atwood on Alternate Sorting Orders. I tried to convert the code in the post to C# but I ran into an issue. There is no� normal_distribution Class. 11/04/2016; 4 minutes to read +3; In this article. Generates a normal distribution. Syntax template<class RealType = double> class normal_distribution { public: // types typedef RealType result_type; struct param_type; // constructors and reset functions explicit normal_distribution(result_type mean = 0.0, result_type stddev = 1.0); explicit normal_distribution(const

if you are using Math.Net then you can just use the InverseCumulativeDistribution function.

So if you want the Z-value, where 80% of the Standard Normal curve is covered the code would look something like this

var curve = new MathNet.Numerics.Distributions.Normal();
var z_value = curve.InverseCumulativeDistribution(0.8);
Console.WriteLine(z_value);

Ensure that you have installed the MathNet.Numerics NuGet package.

Standard Normal Distribution z-value function in C#, C#. VB. Copy. [SerializableAttribute] public class NormalDistribution Gets the Mean value μ (mu) for this Normal distribution. Gets the Standard Gaussian Distribution, with zero mean and unit variance. Gets the cumulative distribution function (cdf) for this distribution evaluated at Gets the Z-Score for a given value. A standard normal table is also called the unit normal table or Z table, is a mathematical table for the values of F, which are the values of the cumulative distribution function of the normal distribution. Standard Normal Distribution. The standard normal distribution is a normal distribution with a mean of 0 and a standard deviation of 1

NormalDistribution Class, NORMSDIST(z) returns the probability that the observed value of a standard normal If X is a normal random variable with mean μ and standard deviation σ, then we write X~N(μ, σ) where σ > 0. However it is interesting to see that this Normal distribution function is Tagged as. C# � Windows � C#4.0� The normal distribution density function f (z) is called the Bell Curve because it has the shape that resembles a bell. Standard normal distribution table is used to find the area under the f (z) function in order to find the probability of a specified range of distribution.

Excel Function: NORMSDIST(z), A z-score can be placed on a normal distribution curve. Z-scores range from -3 standard deviations (which would fall to the far left of the normal distribution� History of Standard Normal Distribution Table. The credit for the discovery, origin and penning down the Standard Normal Distribution can be attributed to the 16th century French mathematician Abraham de Moivre ( 26th May 1667 – 27th November 1754) who is well known for his ‘de Moivre’s formula’ which links complex numbers and trigonometry.

Z-Score: Definition, Formula and Calculation, Z = (X - u) / s where: Z = value on the standard normal distribution X = value Generating a Random Standard Normal Function – Using nextGaussian() in Java : I tried to look in this chart solutions - but none can get an AVG and StdDEV and generate a graph. I'll need to generate normal distribution points and then send them to the graph. I hoped it could be made simpler. – Roman Jan 14 '10 at 17:42

Comments
  • I really like your blog, Thank You!
  • +1 for "# A&S formula 7.1.26". Abramowitz and Stegun is terrific - everyone who does numerical work should know about it.
  • ... and instead of translating it to C# youself, you could just click on the "C#" link.
  • I found this implementation, it is very similar but in c#: codeproject.com/script/Articles/ViewDownloads.aspx?aid=408214
  • You're missing definitions for R_D_Lval and R_D_Cval as defined in svn.r-project.org/R/trunk/src/nmath/dpq.h. In C# they are as follows: private static double R_D_Lval(double p, bool lower_tail) { return lower_tail ? p : 0.5 - p + 0.5; } and private static double R_D_Cval(double p, bool lower_tail) { return lower_tail ? 0.5 - p + 0.5 : p; }
  • Thanks; I've added these to the answer.
  • What is -Base.ExpM1() referring to?
  • The R version of expm1 is defined here: svn.r-project.org/R/trunk/src/nmath/expm1.c. It relies on log1p (svn.r-project.org/R/trunk/src/nmath/log1p.c) and chebyshev_init and chebyshev_eval (svn.r-project.org/R/trunk/src/nmath/chebyshev.c). We could easily end up writing an entire numerics library in C# here!
  • Edgar Sánchez's implementation is as precise and twice as fast stackoverflow.com/a/3367467/76859