Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standard C or Python libraries to compute standard deviation of normal distribution

Say we have normal distribution n(x): mean=0 and \int_{-a}^{a} n(x) = P.

What is the easiest way to compute standard deviation of such distribution? May be there are standard libraries for python or C, that are suitable for that task?

like image 264
elephantum Avatar asked Dec 06 '22 07:12

elephantum


2 Answers

If X is normal with mean 0 and standard deviation sigma, it must hold

P = Prob[ -a <= X <= a ] = Prob[ -a/sigma <= N <= a/sigma ]
  = 2 Prob[ 0 <= N <= a/sigma ]
  = 2 ( Prob[ N <= a/sigma ] - 1/2 )

where N is normal with mean 0 and standard deviation 1. Hence

P/2 + 1/2 = Prob[ N <= a/sigma ] = Phi(a/sigma)

Where Phi is the cumulative distribution function (cdf) of a normal variable with mean 0 and stddev 1. Now we need the inverse normal cdf (or the "percent point function"), which in Python is scipy.stats.norm.ppf(). Sample code:

from scipy.stats import norm
P = 0.3456
a = 3.0

a_sigma = float(norm.ppf(P/2 + 0.5))   # a/sigma
sigma = a/a_sigma   # Here is the standard deviation

For example, we know that the probability of a N(0,1) variable falling int the interval [-1.1] is ~ 0.682 (the dark blue area in this figure). If you set P = 0.682 and a = 1.0 you obtain sigma ~ 1.0, which is indeed the standard deviation.

like image 166
Federico A. Ramponi Avatar answered Dec 10 '22 09:12

Federico A. Ramponi


The standard deviation of a mean-zero gaussian distribution with Pr(-a < X < a) = P is

a/(sqrt(2)*inverseErf(P))

which is the expression you're looking for, where inverseErf is the inverse of the error function (commonly known as erf).

For C, the Gnu Scientific Library (GSL) is a good resource. However it only has erf, not inverseErf, so you'd have to invert it yourself (a simple binary search would do the trick). Alternatively, here's a nice way to approximate erf and inverseErf:

http://homepages.physik.uni-muenchen.de/~Winitzki/erf-approx.pdf

For Python, inverseErf is available as erfinv in the SciPy library, so the following gives the standard deviation:

a/(math.sqrt(2)*erfinv(P))

PS: There's some kind of bug in Stackoverflow's URL rendering and it wouldn't let me link to GSL above: http://www.gnu.org/software/gsl. It also renders wrong when I make the URL above with a pdf a proper link.

like image 42
Paul Grime Avatar answered Dec 10 '22 10:12

Paul Grime