1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.rng.sampling.shape;
19
20 import org.apache.commons.rng.UniformRandomProvider;
21 import org.apache.commons.rng.sampling.SharedStateObjectSampler;
22
23
24
25
26
27
28
29
30
31
32
33
34
35 public abstract class BoxSampler implements SharedStateObjectSampler<double[]> {
36
37 private static final int TWO_D = 2;
38
39 private static final int THREE_D = 3;
40
41 private final UniformRandomProvider rng;
42
43
44
45
46
47
48
49
50
51
52
53 private static class BoxSampler2D extends BoxSampler {
54
55 private final double ax;
56
57 private final double ay;
58
59 private final double bx;
60
61 private final double by;
62
63
64
65
66
67
68 BoxSampler2D(UniformRandomProvider rng, double[] a, double[] b) {
69 super(rng);
70 ax = a[0];
71 ay = a[1];
72 bx = b[0];
73 by = b[1];
74 }
75
76
77
78
79
80 BoxSampler2D(UniformRandomProvider rng, BoxSampler2D source) {
81 super(rng);
82 ax = source.ax;
83 ay = source.ay;
84 bx = source.bx;
85 by = source.by;
86 }
87
88 @Override
89 public double[] sample() {
90 return new double[] {createSample(ax, bx),
91 createSample(ay, by)};
92 }
93
94 @Override
95 public BoxSampler withUniformRandomProvider(UniformRandomProvider rng) {
96 return new BoxSampler2D(rng, this);
97 }
98 }
99
100
101
102
103
104 private static class BoxSampler3D extends BoxSampler {
105
106 private final double ax;
107
108 private final double ay;
109
110 private final double az;
111
112 private final double bx;
113
114 private final double by;
115
116 private final double bz;
117
118
119
120
121
122
123 BoxSampler3D(UniformRandomProvider rng, double[] a, double[] b) {
124 super(rng);
125 ax = a[0];
126 ay = a[1];
127 az = a[2];
128 bx = b[0];
129 by = b[1];
130 bz = b[2];
131 }
132
133
134
135
136
137 BoxSampler3D(UniformRandomProvider rng, BoxSampler3D source) {
138 super(rng);
139 ax = source.ax;
140 ay = source.ay;
141 az = source.az;
142 bx = source.bx;
143 by = source.by;
144 bz = source.bz;
145 }
146
147 @Override
148 public double[] sample() {
149 return new double[] {createSample(ax, bx),
150 createSample(ay, by),
151 createSample(az, bz)};
152 }
153
154 @Override
155 public BoxSampler withUniformRandomProvider(UniformRandomProvider rng) {
156 return new BoxSampler3D(rng, this);
157 }
158 }
159
160
161
162
163 private static class BoxSamplerND extends BoxSampler {
164
165 private final double[] a;
166
167 private final double[] b;
168
169
170
171
172
173
174 BoxSamplerND(UniformRandomProvider rng, double[] a, double[] b) {
175 super(rng);
176
177 this.a = a.clone();
178 this.b = b.clone();
179 }
180
181
182
183
184
185 BoxSamplerND(UniformRandomProvider rng, BoxSamplerND source) {
186 super(rng);
187
188 a = source.a;
189 b = source.b;
190 }
191
192 @Override
193 public double[] sample() {
194 final double[] x = new double[a.length];
195 for (int i = 0; i < x.length; i++) {
196 x[i] = createSample(a[i], b[i]);
197 }
198 return x;
199 }
200
201 @Override
202 public BoxSampler withUniformRandomProvider(UniformRandomProvider rng) {
203 return new BoxSamplerND(rng, this);
204 }
205 }
206
207
208
209
210 BoxSampler(UniformRandomProvider rng) {
211 this.rng = rng;
212 }
213
214
215
216
217 @Override
218 public abstract double[] sample();
219
220
221
222
223
224
225
226
227 double createSample(double a, double b) {
228 final double u = rng.nextDouble();
229 return (1.0 - u) * a + u * b;
230 }
231
232
233
234 @Override
235 public abstract BoxSampler withUniformRandomProvider(UniformRandomProvider rng);
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254 public static BoxSampler of(UniformRandomProvider rng,
255 double[] a,
256 double[] b) {
257 final int dimension = a.length;
258 if (dimension != b.length) {
259 throw new IllegalArgumentException(
260 new StringBuilder("Mismatch of box dimensions: ").append(dimension).append(',')
261 .append(b.length).toString());
262 }
263
264 Coordinates.requireFinite(a, "Bound a");
265 Coordinates.requireFinite(b, "Bound b");
266
267 if (dimension == TWO_D) {
268 return new BoxSampler2D(rng, a, b);
269 } else if (dimension == THREE_D) {
270 return new BoxSampler3D(rng, a, b);
271 } else if (dimension > THREE_D) {
272 return new BoxSamplerND(rng, a, b);
273 }
274
275 throw new IllegalArgumentException("Unsupported dimension: " + dimension);
276 }
277 }