1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.sampling;
18
19 import org.junit.Assert;
20 import org.junit.Test;
21 import org.apache.commons.rng.simple.RandomSource;
22 import org.apache.commons.rng.UniformRandomProvider;
23
24
25
26
27 public class UnitSphereSamplerTest {
28 @Test(expected = IllegalArgumentException.class)
29 public void testPrecondition() {
30 new UnitSphereSampler(0, null);
31 }
32
33
34
35
36 @Test
37 public void testDistribution2D() {
38 UniformRandomProvider rng = RandomSource.create(RandomSource.XOR_SHIFT_1024_S, 17399225432L);
39 UnitSphereSampler generator = new UnitSphereSampler(2, rng);
40
41
42 final int[] angleBuckets = new int[100];
43 final int steps = 1000000;
44 for (int i = 0; i < steps; ++i) {
45 final double[] v = generator.nextVector();
46 Assert.assertEquals(2, v.length);
47 Assert.assertEquals(1, length(v), 1e-10);
48
49
50
51 final double angle = Math.acos(v[0]);
52 final int bucket = (int) (angle / Math.PI * angleBuckets.length);
53 ++angleBuckets[bucket];
54 }
55
56
57 final int expectedBucketSize = steps / angleBuckets.length;
58 for (int bucket : angleBuckets) {
59 Assert.assertTrue("Bucket count " + bucket + " vs expected " + expectedBucketSize,
60 Math.abs(expectedBucketSize - bucket) < 350);
61 }
62 }
63
64
65 @Test(expected = StackOverflowError.class)
66 public void testBadProvider1() {
67 final UniformRandomProvider bad = new UniformRandomProvider() {
68 public long nextLong(long n) { return 0; }
69 public long nextLong() { return 0; }
70 public int nextInt(int n) { return 0; }
71 public int nextInt() { return 0; }
72 public float nextFloat() { return 0; }
73 public double nextDouble() { return 0;}
74 public void nextBytes(byte[] bytes, int start, int len) {}
75 public void nextBytes(byte[] bytes) {}
76 public boolean nextBoolean() { return false; }
77 };
78
79 new UnitSphereSampler(1, bad).nextVector();
80 }
81
82
83
84
85 private static double length(double[] vector) {
86 double total = 0;
87 for (double d : vector) {
88 total += d * d;
89 }
90 return Math.sqrt(total);
91 }
92 }