View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  package org.hipparchus.random;
23  
24  import org.hipparchus.util.FastMath;
25  import org.junit.Assert;
26  import org.junit.Test;
27  
28  public class UnitSphereRandomVectorGeneratorTest {
29      /**
30       * Test the distribution of points from {@link UnitSphereRandomVectorGenerator#nextVector()}
31       * in two dimensions.
32       */
33      @Test
34      public void test2DDistribution() {
35  
36          RandomGenerator rg = new JDKRandomGenerator();
37          rg.setSeed(17399225432l);
38          UnitSphereRandomVectorGenerator generator = new UnitSphereRandomVectorGenerator(2, rg);
39  
40          // In 2D, angles with a given vector should be uniformly distributed
41          int[] angleBuckets = new int[100];
42          int steps = 1000000;
43          for (int i = 0; i < steps; ++i) {
44              final double[] v = generator.nextVector();
45              Assert.assertEquals(2, v.length);
46              Assert.assertEquals(1, length(v), 1e-10);
47              // Compute angle formed with vector (1,0)
48              // Cosine of angle is their dot product, because both are unit length
49              // Dot product here is just the first element of the vector by construction
50              final double angle = FastMath.acos(v[0]);
51              final int bucket = (int) (angleBuckets.length * (angle / FastMath.PI));
52              ++angleBuckets[bucket];
53          }
54  
55          // Simplistic test for roughly even distribution
56          final int expectedBucketSize = steps / angleBuckets.length;
57          for (int bucket : angleBuckets) {
58              Assert.assertTrue("Bucket count " + bucket + " vs expected " + expectedBucketSize,
59                                FastMath.abs(expectedBucketSize - bucket) < 350);
60          }
61      }
62  
63      /**
64       * @return length (L2 norm) of given vector
65       */
66      private static double length(double[] vector) {
67          double total = 0;
68          for (double d : vector) {
69              total += d * d;
70          }
71          return FastMath.sqrt(total);
72      }
73  }