1 package org.djunits.value.vfloat.vector.base;
2
3 import java.io.Serializable;
4 import java.lang.reflect.Array;
5 import java.util.Iterator;
6 import java.util.NoSuchElementException;
7
8 import org.djunits.unit.Unit;
9 import org.djunits.value.Absolute;
10 import org.djunits.value.ValueRuntimeException;
11 import org.djunits.value.base.Vector;
12 import org.djunits.value.formatter.Format;
13 import org.djunits.value.storage.StorageType;
14 import org.djunits.value.util.ValueUtil;
15 import org.djunits.value.vfloat.function.FloatFunction;
16 import org.djunits.value.vfloat.function.FloatMathFunctions;
17 import org.djunits.value.vfloat.scalar.base.FloatScalar;
18 import org.djunits.value.vfloat.vector.data.FloatVectorData;
19 import org.djutils.exceptions.Throw;
20
21
22
23
24
25
26
27
28
29
30
31
32
33 public abstract class FloatVector<U extends Unit<U>, S extends FloatScalar<U, S>, V extends FloatVector<U, S, V>>
34 extends Vector<U, S, V, FloatVectorData>
35 {
36
37 private static final long serialVersionUID = 20161015L;
38
39
40 @SuppressWarnings("checkstyle:visibilitymodifier")
41 protected FloatVectorData data;
42
43
44
45
46
47
48 FloatVector(final FloatVectorData data, final U unit)
49 {
50 super(unit);
51 Throw.whenNull(data, "data cannot be null");
52 this.data = data;
53 }
54
55
56
57
58
59
60
61
62
63 public abstract V instantiateVector(FloatVectorData fvd, U displayUnit);
64
65
66
67
68
69
70
71
72
73 public abstract S instantiateScalarSI(float valueSI, U displayUnit);
74
75 @Override
76 protected final FloatVectorData getData()
77 {
78 return this.data;
79 }
80
81 @Override
82 protected void setData(final FloatVectorData data)
83 {
84 this.data = data;
85 }
86
87
88
89
90
91 public final float[] getValuesSI()
92 {
93 return getData().getDenseVectorSI();
94 }
95
96
97
98
99
100 public final float[] getValuesInUnit()
101 {
102 return getValuesInUnit(getDisplayUnit());
103 }
104
105
106
107
108
109
110 public final float[] getValuesInUnit(final U targetUnit)
111 {
112 float[] values = getValuesSI();
113 for (int i = values.length; --i >= 0;)
114 {
115 values[i] = (float) ValueUtil.expressAsUnit(values[i], targetUnit);
116 }
117 return values;
118 }
119
120 @Override
121 public final int size()
122 {
123 return getData().size();
124 }
125
126
127
128
129
130
131 protected final void checkIndex(final int index) throws IndexOutOfBoundsException
132 {
133 if (index < 0 || index >= size())
134 {
135 throw new IndexOutOfBoundsException(
136 "index out of range (valid range is 0.." + (size() - 1) + ", got " + index + ")");
137 }
138 }
139
140
141
142
143
144
145
146 public final float getSI(final int index) throws IndexOutOfBoundsException
147 {
148 checkIndex(index);
149 return getData().getSI(index);
150 }
151
152 @Override
153 public S get(final int index) throws IndexOutOfBoundsException
154 {
155 return FloatScalar.instantiateSI(getSI(index), getDisplayUnit());
156 }
157
158
159
160
161
162
163
164 public final float getInUnit(final int index) throws IndexOutOfBoundsException
165 {
166 return (float) ValueUtil.expressAsUnit(getSI(index), getDisplayUnit());
167 }
168
169
170
171
172
173
174
175
176 public final float getInUnit(final int index, final U targetUnit) throws IndexOutOfBoundsException
177 {
178 return (float) ValueUtil.expressAsUnit(getSI(index), targetUnit);
179 }
180
181
182
183
184
185
186
187 public final void setSI(final int index, final float valueSI) throws IndexOutOfBoundsException
188 {
189 checkIndex(index);
190 checkCopyOnWrite();
191 getData().setSI(index, valueSI);
192 }
193
194
195
196
197
198
199
200 public void setInUnit(final int index, final float valueInUnit) throws IndexOutOfBoundsException
201 {
202 setSI(index, (float) ValueUtil.expressAsSIUnit(valueInUnit, getDisplayUnit()));
203 }
204
205
206
207
208
209
210
211
212 public void setInUnit(final int index, final float valueInUnit, final U valueUnit) throws IndexOutOfBoundsException
213 {
214 setSI(index, (float) ValueUtil.expressAsSIUnit(valueInUnit, valueUnit));
215 }
216
217
218
219
220
221
222
223 public void set(final int index, final S value) throws IndexOutOfBoundsException
224 {
225 setSI(index, value.si);
226 }
227
228 @SuppressWarnings("unchecked")
229 @Override
230 public S[] getScalars()
231 {
232 S[] array = (S[]) Array.newInstance(getScalarClass(), size());
233 for (int i = 0; i < size(); i++)
234 {
235 array[i] = get(i);
236 }
237 return array;
238 }
239
240 @SuppressWarnings("unchecked")
241 @Override
242 public V toSparse()
243 {
244 V result;
245 if (getStorageType().equals(StorageType.SPARSE))
246 {
247 result = (V) this;
248 result.setDisplayUnit(getDisplayUnit());
249 }
250 else
251 {
252 result = instantiateVector(getData().toSparse(), getDisplayUnit());
253 }
254 result.setDisplayUnit(getDisplayUnit());
255 return result;
256 }
257
258 @SuppressWarnings("unchecked")
259 @Override
260 public V toDense()
261 {
262 V result;
263 if (getStorageType().equals(StorageType.DENSE))
264 {
265 result = (V) this;
266 result.setDisplayUnit(getDisplayUnit());
267 }
268 else
269 {
270 result = instantiateVector(getData().toDense(), getDisplayUnit());
271 }
272 return result;
273 }
274
275
276
277
278
279
280 @SuppressWarnings("unchecked")
281 public final V assign(final FloatFunction floatFunction)
282 {
283 checkCopyOnWrite();
284 this.data.assign(floatFunction);
285 return (V) this;
286 }
287
288 @Override
289 public final V abs()
290 {
291 return assign(FloatMathFunctions.ABS);
292 }
293
294 @Override
295 public final V ceil()
296 {
297 return assign(FloatMathFunctions.CEIL);
298 }
299
300 @Override
301 public final V floor()
302 {
303 return assign(FloatMathFunctions.FLOOR);
304 }
305
306 @Override
307 public final V neg()
308 {
309 return assign(FloatMathFunctions.NEG);
310 }
311
312 @Override
313 public final V rint()
314 {
315 return assign(FloatMathFunctions.RINT);
316 }
317
318 @Override
319 public String toString()
320 {
321 return toString(getDisplayUnit(), false, true);
322 }
323
324 @Override
325 public String toString(final U displayUnit)
326 {
327 return toString(displayUnit, false, true);
328 }
329
330 @Override
331 public String toString(final boolean verbose, final boolean withUnit)
332 {
333 return toString(getDisplayUnit(), verbose, withUnit);
334 }
335
336 @Override
337 public String toString(final U displayUnit, final boolean verbose, final boolean withUnit)
338 {
339 StringBuffer buf = new StringBuffer();
340 if (verbose)
341 {
342 String ar = this instanceof Absolute ? "Abs " : "Rel ";
343 String ds = getData().isDense() ? "Dense " : getData().isSparse() ? "Sparse " : "?????? ";
344 if (isMutable())
345 {
346 buf.append("Mutable " + ar + ds);
347 }
348 else
349 {
350 buf.append("Immutable " + ar + ds);
351 }
352 }
353 buf.append("[");
354 for (int i = 0; i < size(); i++)
355 {
356 try
357 {
358 float f = (float) ValueUtil.expressAsUnit(getSI(i), displayUnit);
359 buf.append(" " + Format.format(f));
360 }
361 catch (IndexOutOfBoundsException ve)
362 {
363 buf.append(" " + "********************".substring(0, Format.DEFAULTSIZE));
364 }
365 }
366 buf.append("]");
367 if (withUnit)
368 {
369 buf.append(" " + displayUnit.getLocalizedDisplayAbbreviation());
370 }
371 return buf.toString();
372 }
373
374
375
376
377
378
379
380 protected final void checkSize(final FloatVector<?, ?, ?> other) throws ValueRuntimeException
381 {
382 Throw.whenNull(other, "Other vector is null");
383 Throw.when(size() != other.size(), ValueRuntimeException.class, "The vectors have different sizes: %d != %d", size(),
384 other.size());
385 }
386
387 @Override
388 @SuppressWarnings("checkstyle:designforextension")
389 public int hashCode()
390 {
391 final int prime = 31;
392 int result = getDisplayUnit().getStandardUnit().hashCode();
393 result = prime * result + ((this.data == null) ? 0 : this.data.hashCode());
394 return result;
395 }
396
397 @Override
398 @SuppressWarnings({"checkstyle:designforextension", "checkstyle:needbraces"})
399 public boolean equals(final Object obj)
400 {
401 if (this == obj)
402 return true;
403 if (obj == null)
404 return false;
405 if (getClass() != obj.getClass())
406 return false;
407 FloatVector<?, ?, ?> other = (FloatVector<?, ?, ?>) obj;
408 if (!getDisplayUnit().getStandardUnit().equals(other.getDisplayUnit().getStandardUnit()))
409 return false;
410 if (this.data == null)
411 {
412 if (other.data != null)
413 return false;
414 }
415 else if (!this.data.equals(other.data))
416 return false;
417 return true;
418 }
419
420
421
422
423
424 @Override
425 public Iterator<S> iterator()
426 {
427 return new Itr();
428 }
429
430
431
432
433
434
435 protected class Itr implements Iterator<S>, Serializable
436 {
437
438 private static final long serialVersionUID = 20191018L;
439
440
441 private int cursor = 0;
442
443 @Override
444 public boolean hasNext()
445 {
446 return this.cursor != size();
447 }
448
449 @Override
450 public S next()
451 {
452 if (this.cursor >= size())
453 {
454 throw new NoSuchElementException();
455 }
456 try
457 {
458 int i = this.cursor;
459 S next = get(i);
460 this.cursor = i + 1;
461 return next;
462 }
463 catch (IndexOutOfBoundsException exception)
464 {
465 throw new RuntimeException(exception);
466 }
467 }
468
469 @Override
470 public void remove()
471 {
472 throw new RuntimeException("Remove function cannot be applied on fixed-size DJUNITS Vector");
473 }
474
475 @Override
476 public String toString()
477 {
478 return "Itr [cursor=" + this.cursor + "]";
479 }
480
481 }
482
483 }