StdGaussian.java



/*************************************************************************
 *  Author:       Kevin Wayne
 *  Date:         8/20/04
 *  Compilation:  javac StdGaussian.java
 *  Execution:    java StdGaussian
 *  
 *  Computes a standard Gaussian random deviate using the cartesian
 *  form of the Box-Muller transform. The method is to compute a 
 *  random point (x, y) inside the circle centered at (0, 0) with
 *  radius 1. Then
 *
 *     x * Math.sqrt(-2.0 * Math.log(r) / r)
 *
 *  and
 *
 *     y * Math.sqrt(-2.0 * Math.log(r) / r)
 *
 *  are each Gaussian random variables with mean 0 and standard deviation 1.
 *  This formula appears in 
 *
 *     Knuth, The Art of Computer Programming, Volume 2, p. 122.
 *
 *
 *  Sample executions
 *  ---------------------
 *  % java StdGaussian
 *  -1.2927277357189828
 *
 *  % java StdGaussian
 *  0.32433796089430544
 *
 *  % java StdGaussian
 *  -0.1174251833833895
 *
 *  % java StdGaussian
 *  0.053192581194524566
 *
 *************************************************************************/



public class StdGaussian {

   public static void main(String[] args) { 
      double r, x, y;
      
      // find a uniform random point (x, y) inside unit circle
      do {
         x = 2.0 * Math.random() - 1.0;
         y = 2.0 * Math.random() - 1.0;
         r = x*x + y*y;
      } while (r > 1 || r == 0);    // loop executed 4 / pi = 1.273.. times on average
                                    // http://en.wikipedia.org/wiki/Box-Muller_transform

  
      // apply the Box-Muller formula to get standard Gaussian z    
      double z = x * Math.sqrt(-2.0 * Math.log(r) / r);

      // print it to standard output
      System.out.println(z);
   }

}