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