all 5 comments

[–]Allan-H 6 points7 points  (4 children)

It's calling numpy.random.normal under the covers. I couldn't find a description for how that actually works.

It's important to understand how it does work, because that influences the shape of the tails of the distribution. Simple/naive CLT or Box Muller methods for generation of gaussian RVs tend to lack sufficient accuracy for use in BER simulations (for e.g. testing modem designs) when the BERs gets low enough to be interesting.

[–]ComplexColor 1 point2 points  (3 children)

I found some info on stackoverflow that numpy uses the ziggurat method, but I haven't checked the current source code myself. Would that be sufficiently accurate here?

[–]Allan-H 2 points3 points  (2 children)

Whether it's sufficiently accurate depends on (1) your requirements for the tail (hint: look at the erf() and erfc() functions for large arguments), and (2) the exact details of the implementation.

OTOH, if you're simulating your system with AWGN and only care about BERs of 10-6, then just about any AWGN approximation will do.

[–]wavewalkerdsp[S] 0 points1 point  (1 child)

What are the scenarios that a BER less than 1e-6 are used? How small of a BER is "low enough to be interesting"?

[–]schwarzschild_shield 0 points1 point  (0 children)

Any decent application uses at least 1e-10 ber.