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