1 package org.djunits.value.vfloat.vector;
2
3 import java.util.Arrays;
4 import java.util.List;
5 import java.util.SortedMap;
6 import java.util.stream.IntStream;
7
8 import org.djunits.unit.scale.Scale;
9 import org.djunits.value.StorageType;
10 import org.djunits.value.ValueException;
11 import org.djunits.value.vfloat.scalar.FloatScalarInterface;
12
13
14
15
16
17
18
19
20
21
22
23
24 abstract class FloatVectorData
25 {
26
27 @SuppressWarnings("checkstyle:visibilitymodifier")
28 protected float[] vectorSI;
29
30
31 private final StorageType storageType;
32
33
34
35
36 FloatVectorData(final StorageType storageType)
37 {
38 super();
39 this.storageType = storageType;
40 }
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public static FloatVectorData instantiate(final float[] values, final Scale scale, final StorageType storageType)
55 throws ValueException
56 {
57 if (values == null)
58 {
59 throw new ValueException("FloatVectorData.instantiate: float[] values is null");
60 }
61
62 float[] valuesSI = new float[values.length];
63 IntStream.range(0, values.length).parallel().forEach(i -> valuesSI[i] = (float) scale.toStandardUnit(values[i]));
64
65 switch (storageType)
66 {
67 case DENSE:
68 return new FloatVectorDataDense(valuesSI);
69
70 case SPARSE:
71 return FloatVectorDataSparse.instantiate(valuesSI);
72
73 default:
74 throw new ValueException("Unknown data type in FloatVectorData.instantiate: " + storageType);
75 }
76 }
77
78
79
80
81
82
83
84
85
86 public static FloatVectorData instantiate(final List<Float> values, final Scale scale, final StorageType storageType)
87 throws ValueException
88 {
89 if (values == null)
90 {
91 throw new ValueException("FloatVectorData.instantiate: List<Float> values is null");
92 }
93
94 float[] valuesSI = new float[values.size()];
95 IntStream.range(0, values.size()).parallel().forEach(i -> valuesSI[i] = (float) scale.toStandardUnit(values.get(i)));
96
97 switch (storageType)
98 {
99 case DENSE:
100 return new FloatVectorDataDense(valuesSI);
101
102 case SPARSE:
103 return FloatVectorDataSparse.instantiate(valuesSI);
104
105 default:
106 throw new ValueException("Unknown data type in FloatVectorData.instantiate: " + storageType);
107 }
108 }
109
110
111
112
113
114
115
116
117 public static FloatVectorData instantiate(final FloatScalarInterface[] values, final StorageType storageType)
118 throws ValueException
119 {
120 if (values == null)
121 {
122 throw new ValueException("FloatVectorData.instantiate: FloatScalar[] values is null");
123 }
124
125 float[] valuesSI = new float[values.length];
126 IntStream.range(0, values.length).parallel().forEach(i -> valuesSI[i] = values[i].getSI());
127
128 switch (storageType)
129 {
130 case DENSE:
131 return new FloatVectorDataDense(valuesSI);
132
133 case SPARSE:
134 return FloatVectorDataSparse.instantiate(valuesSI);
135
136 default:
137 throw new ValueException("Unknown data type in FloatVectorData.instantiate: " + storageType);
138 }
139 }
140
141
142
143
144
145
146
147
148 public static FloatVectorData instantiateLD(final List<? extends FloatScalarInterface> values,
149 final StorageType storageType) throws ValueException
150 {
151 if (values == null)
152 {
153 throw new ValueException("FloatVectorData.instantiate: values list is null");
154 }
155
156 float[] valuesSI = new float[values.size()];
157 IntStream.range(0, values.size()).parallel().forEach(i -> valuesSI[i] = values.get(i).getSI());
158
159 switch (storageType)
160 {
161 case DENSE:
162 return new FloatVectorDataDense(valuesSI);
163
164 case SPARSE:
165 return FloatVectorDataSparse.instantiate(valuesSI);
166
167 default:
168 throw new ValueException("Unknown data type in FloatVectorData.instantiate: " + storageType);
169 }
170 }
171
172
173
174
175
176
177
178
179
180
181 public static <S extends FloatScalarInterface> FloatVectorData instantiateMD(final SortedMap<Integer, S> values,
182 final int length, final StorageType storageType) throws ValueException
183 {
184 if (values == null)
185 {
186 throw new ValueException("FloatVectorData.instantiate: values map is null");
187 }
188
189 switch (storageType)
190 {
191 case DENSE:
192 {
193 float[] valuesSI = new float[length];
194 values.keySet().parallelStream().forEach(index -> valuesSI[index] = values.get(index).getSI());
195 return new FloatVectorDataDense(valuesSI);
196 }
197
198 case SPARSE:
199 {
200 int[] indices = values.keySet().parallelStream().mapToInt(i -> i).toArray();
201 float[] valuesSI = new float[values.size()];
202 IntStream.range(0, values.size()).parallel()
203 .forEach(index -> valuesSI[index] = values.get(indices[index]).getSI());
204 return new FloatVectorDataSparse(valuesSI, indices, length);
205 }
206
207 default:
208 throw new ValueException("Unknown data type in FloatVectorData.instantiate: " + storageType);
209 }
210 }
211
212
213
214
215
216
217
218
219
220
221 public static FloatVectorData instantiate(final SortedMap<Integer, Float> values, final int length, final Scale scale,
222 final StorageType storageType) throws ValueException
223 {
224 if (values == null)
225 {
226 throw new ValueException("FloatVectorData.instantiate: values map is null");
227 }
228
229 switch (storageType)
230 {
231 case DENSE:
232 {
233 float[] valuesSI = new float[length];
234 values.keySet().parallelStream()
235 .forEach(index -> valuesSI[index] = (float) scale.toStandardUnit(values.get(index)));
236 return new FloatVectorDataDense(valuesSI);
237 }
238
239 case SPARSE:
240 {
241 int[] indices = values.keySet().parallelStream().mapToInt(i -> i).toArray();
242 float[] valuesSI = new float[values.size()];
243 IntStream.range(0, values.size()).parallel()
244 .forEach(index -> valuesSI[index] = (float) scale.toStandardUnit(values.get(indices[index])));
245 return new FloatVectorDataSparse(valuesSI, indices, length);
246 }
247
248 default:
249 throw new ValueException("Unknown data type in FloatVectorData.instantiate: " + storageType);
250 }
251 }
252
253
254
255
256
257
258
259
260
261 public final StorageType getStorageType()
262 {
263 return this.storageType;
264 }
265
266
267
268
269 public abstract int size();
270
271
272
273
274 public boolean isSparse()
275 {
276 return this.storageType.equals(StorageType.SPARSE);
277 }
278
279
280
281
282 public FloatVectorDataSparse toSparse()
283 {
284 return isSparse() ? (FloatVectorDataSparse) this : ((FloatVectorDataDense) this).toSparse();
285 }
286
287
288
289
290 public boolean isDense()
291 {
292 return this.storageType.equals(StorageType.DENSE);
293 }
294
295
296
297
298 public FloatVectorDataDense toDense()
299 {
300 return isDense() ? (FloatVectorDataDense) this : ((FloatVectorDataSparse) this).toDense();
301 }
302
303
304
305
306
307 public abstract float getSI(int index);
308
309
310
311
312
313
314 public abstract void setSI(int index, float valueSI);
315
316
317
318
319 public final int cardinality()
320 {
321
322 return (int) IntStream.range(0, this.vectorSI.length).parallel().mapToDouble(i -> this.vectorSI[i])
323 .filter(d -> d != 0.0).count();
324 }
325
326
327
328
329 public final float zSum()
330 {
331
332 return (float) IntStream.range(0, this.vectorSI.length).parallel().mapToDouble(i -> this.vectorSI[i]).sum();
333 }
334
335
336
337
338 public abstract FloatVectorData copy();
339
340
341
342
343 public abstract float[] getDenseVectorSI();
344
345
346
347
348
349
350 private void checkSizes(final FloatVectorData other) throws ValueException
351 {
352 if (this.size() != other.size())
353 {
354 throw new ValueException("Two data objects used in a FloatVector operation do not have the same size");
355 }
356 }
357
358
359
360
361
362
363
364
365
366
367
368
369 public FloatVectorData plus(final FloatVectorData right) throws ValueException
370 {
371 checkSizes(right);
372 float[] dv = new float[size()];
373 IntStream.range(0, size()).parallel().forEach(i -> dv[i] = getSI(i) + right.getSI(i));
374 if (this instanceof FloatVectorDataSparse && right instanceof FloatVectorDataSparse)
375 {
376 return new FloatVectorDataDense(dv).toSparse();
377 }
378 return new FloatVectorDataDense(dv);
379 }
380
381
382
383
384
385
386 public abstract void incrementBy(FloatVectorData right) throws ValueException;
387
388
389
390
391
392 public void incrementBy(final float valueSI)
393 {
394 IntStream.range(0, this.vectorSI.length).parallel().forEach(i -> this.vectorSI[i] += valueSI);
395 }
396
397
398
399
400
401
402
403
404 public FloatVectorData minus(final FloatVectorData right) throws ValueException
405 {
406 checkSizes(right);
407 float[] dv = new float[size()];
408 IntStream.range(0, size()).parallel().forEach(i -> dv[i] = getSI(i) - right.getSI(i));
409 if (this instanceof FloatVectorDataSparse && right instanceof FloatVectorDataSparse)
410 {
411 return new FloatVectorDataDense(dv).toSparse();
412 }
413 return new FloatVectorDataDense(dv);
414 }
415
416
417
418
419
420
421 public abstract void decrementBy(FloatVectorData right) throws ValueException;
422
423
424
425
426
427 public void decrementBy(final float valueSI)
428 {
429 IntStream.range(0, this.vectorSI.length).parallel().forEach(i -> this.vectorSI[i] -= valueSI);
430 }
431
432
433
434
435
436
437
438
439 public FloatVectorData times(final FloatVectorData right) throws ValueException
440 {
441 checkSizes(right);
442 float[] dv = new float[size()];
443 IntStream.range(0, size()).parallel().forEach(i -> dv[i] = getSI(i) * right.getSI(i));
444 if (this instanceof FloatVectorDataDense && right instanceof FloatVectorDataDense)
445 {
446 return new FloatVectorDataDense(dv);
447 }
448 return new FloatVectorDataDense(dv).toSparse();
449 }
450
451
452
453
454
455
456
457 public abstract void multiplyBy(FloatVectorData right) throws ValueException;
458
459
460
461
462
463 public void multiplyBy(final float valueSI)
464 {
465 IntStream.range(0, this.vectorSI.length).parallel().forEach(i -> this.vectorSI[i] *= valueSI);
466 }
467
468
469
470
471
472
473
474
475 public FloatVectorData divide(final FloatVectorData right) throws ValueException
476 {
477 checkSizes(right);
478 float[] dv = new float[size()];
479 IntStream.range(0, size()).parallel().forEach(i -> dv[i] = getSI(i) / right.getSI(i));
480 if (this instanceof FloatVectorDataDense && right instanceof FloatVectorDataDense)
481 {
482 return new FloatVectorDataDense(dv);
483 }
484 return new FloatVectorDataDense(dv).toSparse();
485 }
486
487
488
489
490
491
492
493 public abstract void divideBy(FloatVectorData right) throws ValueException;
494
495
496
497
498
499 public void divideBy(final float valueSI)
500 {
501 IntStream.range(0, this.vectorSI.length).parallel().forEach(i -> this.vectorSI[i] /= valueSI);
502 }
503
504
505
506
507
508
509 @Override
510 public int hashCode()
511 {
512 final int prime = 31;
513 int result = 1;
514 result = prime * result + Arrays.hashCode(this.vectorSI);
515 return result;
516 }
517
518
519 @Override
520 @SuppressWarnings("checkstyle:needbraces")
521 public boolean equals(final Object obj)
522 {
523 if (this == obj)
524 return true;
525 if (obj == null)
526 return false;
527 if (getClass() != obj.getClass())
528 return false;
529 FloatVectorData other = (FloatVectorData) obj;
530 if (!Arrays.equals(this.vectorSI, other.vectorSI))
531 return false;
532 return true;
533 }
534
535
536 @Override
537 public String toString()
538 {
539 return "FloatVectorData [storageType=" + this.storageType + ", vectorSI=" + Arrays.toString(this.vectorSI) + "]";
540 }
541 }