UnitSphereRandomVectorGenerator implements RandomVectorGenerator { public double[] nextVector() { final double[] v = new double[dimension]; double normSq = 0; for (int i = 0; i < dimension; i++) { final double comp = rand.nextGaussian(); v[i] = comp; normSq += comp * comp; } final double f = 1 / FastMath.sqrt(normSq); for (int i = 0; i < dimension; i++) { v[i] *= f; } return v; } UnitSphereRandomVectorGenerator(final int dimension,
                                           final RandomGenerator rand);  UnitSphereRandomVectorGenerator(final int dimension); double[] nextVector();  }
@Test public void test2DDistribution() { RandomGenerator rg = new JDKRandomGenerator(); rg.setSeed(17399225432l); UnitSphereRandomVectorGenerator generator = new UnitSphereRandomVectorGenerator(2, rg); int[] angleBuckets = new int[100]; int steps = 1000000; for (int i = 0; i < steps; ++i) { final double[] v = generator.nextVector(); Assert.assertEquals(2, v.length); Assert.assertEquals(1, length(v), 1e-10); final double angle = FastMath.acos(v[0]); final int bucket = (int) (angleBuckets.length * (angle / FastMath.PI)); ++angleBuckets[bucket]; } final int expectedBucketSize = steps / angleBuckets.length; for (int bucket : angleBuckets) { Assert.assertTrue("Bucket count " + bucket + " vs expected " + expectedBucketSize, FastMath.abs(expectedBucketSize - bucket) < 350); } }