Tunny Icon
TunnyDocs

The next-gen Grasshopper optimization tool.

Box-Muller Transform

Overview

The Box-Muller transform converts a pair of independent uniform random numbers into a pair of independent standard normal samples. It is the sampler behind every Gaussian draw in this app — most prominently the input-noise perturbations of the Robustness widget — chosen because it is exact (not an approximation), branch-free, and easy to make reproducible on top of the app's deterministic ChaCha8-based RNG.


Formula

Given two independent uniform variates U1,U2U(0,1)U_1, U_2 \sim \mathcal{U}(0, 1):

Z0=2lnU1cos(2πU2),Z1=2lnU1sin(2πU2)Z_0 = \sqrt{-2 \ln U_1} , \cos(2\pi U_2), \qquad Z_1 = \sqrt{-2 \ln U_1} , \sin(2\pi U_2)

Then Z0,Z1N(0,1)Z_0, Z_1 \sim \mathcal{N}(0, 1) and they are independent.

The construction is a change of variables to polar coordinates: R2=2lnU1R^2 = -2\ln U_1 gives the squared radius the chi-squared distribution with 2 degrees of freedom (the distribution of Z02+Z12Z_0^2 + Z_1^2 for a standard bivariate normal), while Θ=2πU2\Theta = 2\pi U_2 picks the angle uniformly. Mapping the pair (R,Θ)(R, \Theta) back to Cartesian coordinates yields two independent standard normals.

A general Gaussian sample is obtained by scaling and shifting: X=μ+σZX = \mu + \sigma Z.


Characteristics

  • Exact: the output follows the normal distribution exactly (up to floating-point error), unlike approximations such as summing twelve uniforms.
  • Domain care: lnU1\ln U_1 requires U1>0U_1 > 0. Since the underlying generator returns values in [0,1)[0, 1), Tunny Dashboard feeds 1U1 - U (which lies in (0,1](0, 1]) to the logarithm, so a raw draw of exactly 00 cannot produce ln0=\ln 0 = -\infty.
  • This app uses only the cosine branch ( Z0Z_0) and discards Z1Z_1, trading a factor-of-two efficiency for a simpler, stateless call. The cost is irrelevant at the sample counts involved (thousands per analysis).
  • Reproducibility: driven by the seeded ChaCha8 RNG, the same seed always yields the same Gaussian sequence — which is what makes robustness-analysis results deterministic for fixed settings.
  • Tail behavior is limited by the resolution of U1U_1 near 11: with 53-bit doubles the largest attainable Z|Z| is about 8.5σ8.5\sigma, far beyond anything relevant at the sample sizes used here.

Where It Is Used in the App

  • Robustness widget: generates the Gaussian input-noise perturbations around the candidate design, and (when "Model uncertainty" is enabled) the draws from the GP posterior.

References