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