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 public abstract class LineSampler implements SharedStateObjectSampler<double[]> {
35
36 private static final int ONE_D = 1;
37
38 private static final int TWO_D = 2;
39
40 private static final int THREE_D = 3;
41
42 private final UniformRandomProvider rng;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 private static class LineSampler1D extends LineSampler {
59
60 private final double ax;
61
62 private final double bx;
63
64
65
66
67
68
69 LineSampler1D(UniformRandomProvider rng, double[] a, double[] b) {
70 super(rng);
71 ax = a[0];
72 bx = b[0];
73 }
74
75
76
77
78
79 LineSampler1D(UniformRandomProvider rng, LineSampler1D source) {
80 super(rng);
81 ax = source.ax;
82 bx = source.bx;
83 }
84
85 @Override
86 public double[] createSample(double p1mu, double u) {
87 return new double[] {p1mu * ax + u * bx};
88 }
89
90 @Override
91 public LineSampler withUniformRandomProvider(UniformRandomProvider rng) {
92 return new LineSampler1D(rng, this);
93 }
94 }
95
96
97
98
99
100 private static class LineSampler2D extends LineSampler {
101
102 private final double ax;
103
104 private final double ay;
105
106 private final double bx;
107
108 private final double by;
109
110
111
112
113
114
115 LineSampler2D(UniformRandomProvider rng, double[] a, double[] b) {
116 super(rng);
117 ax = a[0];
118 ay = a[1];
119 bx = b[0];
120 by = b[1];
121 }
122
123
124
125
126
127 LineSampler2D(UniformRandomProvider rng, LineSampler2D source) {
128 super(rng);
129 ax = source.ax;
130 ay = source.ay;
131 bx = source.bx;
132 by = source.by;
133 }
134
135 @Override
136 public double[] createSample(double p1mu, double u) {
137 return new double[] {p1mu * ax + u * bx,
138 p1mu * ay + u * by};
139 }
140
141 @Override
142 public LineSampler withUniformRandomProvider(UniformRandomProvider rng) {
143 return new LineSampler2D(rng, this);
144 }
145 }
146
147
148
149
150
151 private static class LineSampler3D extends LineSampler {
152
153 private final double ax;
154
155 private final double ay;
156
157 private final double az;
158
159 private final double bx;
160
161 private final double by;
162
163 private final double bz;
164
165
166
167
168
169
170 LineSampler3D(UniformRandomProvider rng, double[] a, double[] b) {
171 super(rng);
172 ax = a[0];
173 ay = a[1];
174 az = a[2];
175 bx = b[0];
176 by = b[1];
177 bz = b[2];
178 }
179
180
181
182
183
184 LineSampler3D(UniformRandomProvider rng, LineSampler3D source) {
185 super(rng);
186 ax = source.ax;
187 ay = source.ay;
188 az = source.az;
189 bx = source.bx;
190 by = source.by;
191 bz = source.bz;
192 }
193
194 @Override
195 public double[] createSample(double p1mu, double u) {
196 return new double[] {p1mu * ax + u * bx,
197 p1mu * ay + u * by,
198 p1mu * az + u * bz};
199 }
200
201 @Override
202 public LineSampler withUniformRandomProvider(UniformRandomProvider rng) {
203 return new LineSampler3D(rng, this);
204 }
205 }
206
207
208
209
210 private static class LineSamplerND extends LineSampler {
211
212 private final double[] a;
213
214 private final double[] b;
215
216
217
218
219
220
221 LineSamplerND(UniformRandomProvider rng, double[] a, double[] b) {
222 super(rng);
223
224 this.a = a.clone();
225 this.b = b.clone();
226 }
227
228
229
230
231
232 LineSamplerND(UniformRandomProvider rng, LineSamplerND source) {
233 super(rng);
234
235 a = source.a;
236 b = source.b;
237 }
238
239 @Override
240 public double[] createSample(double p1mu, double u) {
241 final double[] x = new double[a.length];
242 for (int i = 0; i < x.length; i++) {
243 x[i] = p1mu * a[i] + u * b[i];
244 }
245 return x;
246 }
247
248 @Override
249 public LineSampler withUniformRandomProvider(UniformRandomProvider rng) {
250 return new LineSamplerND(rng, this);
251 }
252 }
253
254
255
256
257 LineSampler(UniformRandomProvider rng) {
258 this.rng = rng;
259 }
260
261
262
263
264 @Override
265 public double[] sample() {
266 final double u = rng.nextDouble();
267 return createSample(1.0 - u, u);
268 }
269
270
271
272
273
274
275
276
277
278
279
280
281
282 protected abstract double[] createSample(double p1mu, double u);
283
284
285
286 @Override
287 public abstract LineSampler withUniformRandomProvider(UniformRandomProvider rng);
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302 public static LineSampler of(UniformRandomProvider rng,
303 double[] a,
304 double[] b) {
305 final int dimension = a.length;
306 if (dimension != b.length) {
307 throw new IllegalArgumentException(
308 new StringBuilder("Mismatch of vertex dimensions: ").append(dimension).append(',')
309 .append(b.length).toString());
310 }
311
312 Coordinates.requireFinite(a, "Vertex a");
313 Coordinates.requireFinite(b, "Vertex b");
314
315 if (dimension == TWO_D) {
316 return new LineSampler2D(rng, a, b);
317 } else if (dimension == THREE_D) {
318 return new LineSampler3D(rng, a, b);
319 } else if (dimension > THREE_D) {
320 return new LineSamplerND(rng, a, b);
321 } else if (dimension == ONE_D) {
322
323
324 return new LineSampler1D(rng, a, b);
325 }
326
327 throw new IllegalArgumentException("Unsupported dimension: " + dimension);
328 }
329 }