1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.sampling.distribution;
18
19 import org.apache.commons.rng.UniformRandomProvider;
20 import org.apache.commons.rng.core.source64.SplitMix64;
21 import org.apache.commons.rng.sampling.RandomAssert;
22 import org.junit.jupiter.api.Assertions;
23 import org.junit.jupiter.api.Test;
24
25
26
27
28 class ContinuousUniformSamplerTest {
29
30
31
32 @Test
33 void testNoRestrictionOnOrderOfLowAndHighParameters() {
34 final double low = 3.18;
35 final double high = 5.23;
36 final UniformRandomProvider rng = RandomAssert.createRNG();
37 testSampleInRange(rng, low, high);
38 testSampleInRange(rng, high, low);
39 }
40
41 private static void testSampleInRange(UniformRandomProvider rng,
42 double low, double high) {
43 final SharedStateContinuousSampler sampler = ContinuousUniformSampler.of(rng, low, high);
44 final double min = Math.min(low, high);
45 final double max = Math.max(low, high);
46 for (int i = 0; i < 10; i++) {
47 final double value = sampler.sample();
48 Assertions.assertTrue(value >= min && value <= max, () -> "Value not in range: " + value);
49 }
50 }
51
52
53
54
55
56 @Test
57 void testExcludeBounds() {
58
59
60 final UniformRandomProvider rng = new SplitMix64(0L) {
61 private long l1;
62 private long l2;
63 @Override
64 public long nextLong() {
65 long x;
66 if (l1 > l2) {
67 l2++;
68
69 x = -l2;
70 } else {
71
72 x = l1++;
73 }
74
75
76 return x << 11;
77 }
78 };
79 final double low = 3.18;
80 final double high = 5.23;
81 final SharedStateContinuousSampler sampler =
82 ContinuousUniformSampler.of(rng, low, high, true);
83
84 for (int i = 0; i < 10; i++) {
85 final double value = sampler.sample();
86 Assertions.assertTrue(value > low && value < high, () -> "Value not in range: " + value);
87 }
88 }
89
90
91
92
93
94 @Test
95 void testInvalidOpenIntervalThrows() {
96 final UniformRandomProvider rng = RandomAssert.seededRNG();
97 for (final double[] interval : new double[][] {
98
99 {-0.0, 0.0},
100 {-0.0, Double.MIN_VALUE},
101 {-0.0, Double.MIN_VALUE * 2},
102 {-Double.MIN_VALUE, 0.0},
103 {-Double.MIN_VALUE * 2, 0.0},
104 {-Double.MIN_VALUE, Double.MIN_VALUE},
105
106
107 {1.23, Math.nextUp(1.23)},
108 {1.23, Math.nextUp(1.23)},
109
110 {2.0, Math.nextDown(2.0)},
111 }) {
112 final double low = interval[0];
113 final double high = interval[1];
114 Assertions.assertThrows(IllegalArgumentException.class,
115 () -> ContinuousUniformSampler.of(rng, low, high, true),
116 () -> "(" + low + "," + high + ")");
117 Assertions.assertThrows(IllegalArgumentException.class,
118 () -> ContinuousUniformSampler.of(rng, high, low, true),
119 () -> "(" + high + "," + low + ")");
120 }
121
122
123
124 ContinuousUniformSampler.of(rng, Double.MAX_VALUE, -Double.MAX_VALUE, true);
125 }
126
127
128
129
130
131 @Test
132 void testTinyOpenIntervalSample() {
133 final UniformRandomProvider rng = RandomAssert.seededRNG();
134
135
136 final double x = Double.MIN_VALUE;
137
138 for (final double expected : new double[] {
139 1.23, 2, 56787.7893, 3 * x, 2 * x, x
140 }) {
141 final double low = Math.nextUp(expected);
142 final double high = Math.nextDown(expected);
143 Assertions.assertEquals(expected, ContinuousUniformSampler.of(rng, low, high, true).sample());
144 Assertions.assertEquals(expected, ContinuousUniformSampler.of(rng, high, low, true).sample());
145 Assertions.assertEquals(-expected, ContinuousUniformSampler.of(rng, -low, -high, true).sample());
146 Assertions.assertEquals(-expected, ContinuousUniformSampler.of(rng, -high, -low, true).sample());
147 }
148
149
150
151 final double y = ContinuousUniformSampler.of(rng, -x, 2 * x, true).sample();
152 Assertions.assertTrue(-x < y && y < 2 * x);
153 final double z = ContinuousUniformSampler.of(rng, -2 * x, x, true).sample();
154 Assertions.assertTrue(-2 * x < z && z < x);
155 }
156
157
158
159
160 @Test
161 void testSharedStateSampler() {
162 testSharedStateSampler(false);
163 testSharedStateSampler(true);
164 }
165
166
167
168
169
170
171 private static void testSharedStateSampler(boolean excludedBounds) {
172
173
174
175 final UniformRandomProvider rng1 = new SplitMix64(0L) {
176 private double x;
177 @Override
178 public double nextDouble() {
179 final double y = x;
180 x = super.nextDouble();
181 return y;
182 }
183 };
184 final UniformRandomProvider rng2 = new SplitMix64(0L) {
185 private double x;
186 @Override
187 public double nextDouble() {
188 final double y = x;
189 x = super.nextDouble();
190 return y;
191 }
192 };
193 final double low = 1.23;
194 final double high = 4.56;
195 final SharedStateContinuousSampler sampler1 =
196 ContinuousUniformSampler.of(rng1, low, high, excludedBounds);
197 final SharedStateContinuousSampler sampler2 = sampler1.withUniformRandomProvider(rng2);
198 RandomAssert.assertProduceSameSequence(sampler1, sampler2);
199 }
200
201
202
203
204
205 @Test
206 void testSamplerWithBoundsExcluded() {
207
208
209 final UniformRandomProvider rng1 = RandomAssert.seededRNG();
210 final UniformRandomProvider rng2 = RandomAssert.seededRNG();
211 final double low = 1.23;
212 final double high = 4.56;
213 final SharedStateContinuousSampler sampler1 =
214 ContinuousUniformSampler.of(rng1, low, high, false);
215 final SharedStateContinuousSampler sampler2 =
216 ContinuousUniformSampler.of(rng2, low, high, true);
217 RandomAssert.assertProduceSameSequence(sampler1, sampler2);
218 }
219 }