1 package org.opentrafficsim.core.value.vdouble.scalar;
2
3 import org.opentrafficsim.core.unit.SICoefficients;
4 import org.opentrafficsim.core.unit.SIUnit;
5 import org.opentrafficsim.core.unit.Unit;
6 import org.opentrafficsim.core.value.Absolute;
7 import org.opentrafficsim.core.value.Format;
8 import org.opentrafficsim.core.value.Relative;
9 import org.opentrafficsim.core.value.Scalar;
10 import org.opentrafficsim.core.value.ValueUtil;
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 public abstract class DoubleScalar<U extends Unit<U>> extends Scalar<U>
26 {
27
28 private static final long serialVersionUID = 20150309L;
29
30
31 private double valueSI;
32
33
34
35
36
37 protected DoubleScalar(final U unit)
38 {
39 super(unit);
40
41 }
42
43
44
45
46 public static class Abs<U extends Unit<U>> extends DoubleScalar<U> implements Absolute, Comparable<Abs<U>>
47 {
48
49 private static final long serialVersionUID = 20150309L;
50
51
52
53
54
55
56 public Abs(final double value, final U unit)
57 {
58 super(unit);
59
60 initialize(value);
61 }
62
63
64
65
66
67 public Abs(final DoubleScalar.Abs<U> value)
68 {
69 super(value.getUnit());
70
71 initialize(value);
72 }
73
74
75
76
77
78 public Abs(final MutableDoubleScalar.Abs<U> value)
79 {
80 super(value.getUnit());
81
82 initialize(value);
83 }
84
85
86 @Override
87 public final MutableDoubleScalar.Abs<U> mutable()
88 {
89 return new MutableDoubleScalar.Abs<U>(this);
90 }
91
92
93 @Override
94 public final int compareTo(final Abs<U> o)
95 {
96 return new Double(getSI()).compareTo(o.getSI());
97 }
98
99
100 @Override
101 public final DoubleScalar.Abs<U> copy()
102 {
103 return this;
104 }
105
106 }
107
108
109
110
111 public static class Rel<U extends Unit<U>> extends DoubleScalar<U> implements Relative, Comparable<Rel<U>>
112 {
113
114 private static final long serialVersionUID = 20150309L;
115
116
117
118
119
120
121 public Rel(final double value, final U unit)
122 {
123 super(unit);
124
125 initialize(value);
126 }
127
128
129
130
131
132 public Rel(final DoubleScalar.Rel<U> value)
133 {
134 super(value.getUnit());
135
136 initialize(value);
137 }
138
139
140
141
142
143 public Rel(final MutableDoubleScalar.Rel<U> value)
144 {
145 super(value.getUnit());
146
147 initialize(value);
148 }
149
150
151 @Override
152 public final MutableDoubleScalar.Rel<U> mutable()
153 {
154 return new MutableDoubleScalar.Rel<U>(this);
155 }
156
157
158 @Override
159 public final int compareTo(final Rel<U> o)
160 {
161 return new Double(getSI()).compareTo(o.getSI());
162 }
163
164
165 @Override
166 public final DoubleScalar.Rel<U> copy()
167 {
168 return this;
169 }
170
171 }
172
173
174
175
176
177
178 public abstract MutableDoubleScalar<U> mutable();
179
180
181
182
183
184 protected final void initialize(final double value)
185 {
186 if (this.getUnit().equals(this.getUnit().getStandardUnit()))
187 {
188 setValueSI(value);
189 }
190 else
191 {
192 setValueSI(expressAsSIUnit(value));
193 }
194 }
195
196
197
198
199
200 protected final void initialize(final DoubleScalar<U> value)
201 {
202 setValueSI(value.getSI());
203 }
204
205
206
207
208
209 public final double getSI()
210 {
211 return this.valueSI;
212 }
213
214
215
216
217
218 protected final void setValueSI(final double value)
219 {
220 this.valueSI = value;
221 }
222
223
224
225
226
227 public final double getInUnit()
228 {
229 return expressAsSpecifiedUnit(getSI());
230 }
231
232
233
234
235
236
237 public final double getInUnit(final U targetUnit)
238 {
239 return ValueUtil.expressAsUnit(getSI(), targetUnit);
240 }
241
242
243
244
245
246
247 @Override
248 public final int intValue()
249 {
250 return (int) Math.round(getSI());
251 }
252
253
254 @Override
255 public final long longValue()
256 {
257 return Math.round(getSI());
258 }
259
260
261 @Override
262 public final float floatValue()
263 {
264 return (float) getSI();
265 }
266
267
268 @Override
269 public final double doubleValue()
270 {
271 return getSI();
272 }
273
274
275 @Override
276 public final String toString()
277 {
278 return toString(getUnit(), false, true);
279 }
280
281
282
283
284
285
286 public final String toString(final U displayUnit)
287 {
288 return toString(displayUnit, false, true);
289 }
290
291
292
293
294
295
296
297 public final String toString(final boolean verbose, final boolean withUnit)
298 {
299 return toString(getUnit(), verbose, withUnit);
300 }
301
302
303
304
305
306
307
308
309 public final String toString(final U displayUnit, final boolean verbose, final boolean withUnit)
310 {
311 StringBuffer buf = new StringBuffer();
312 if (verbose)
313 {
314 if (this instanceof MutableDoubleScalar)
315 {
316 buf.append("Mutable ");
317 if (this instanceof MutableDoubleScalar.Abs)
318 {
319 buf.append("Abs ");
320 }
321 else if (this instanceof MutableDoubleScalar.Rel)
322 {
323 buf.append("Rel ");
324 }
325 else
326 {
327 buf.append("??? ");
328 }
329 }
330 else
331 {
332 buf.append("Immutable ");
333 if (this instanceof DoubleScalar.Abs)
334 {
335 buf.append("Abs ");
336 }
337 else if (this instanceof DoubleScalar.Rel)
338 {
339 buf.append("Rel ");
340 }
341 else
342 {
343 buf.append("??? ");
344 }
345 }
346 }
347 double d = ValueUtil.expressAsUnit(getSI(), displayUnit);
348 buf.append(Format.format(d));
349 if (withUnit)
350 {
351 buf.append(displayUnit.getAbbreviation());
352 }
353 return buf.toString();
354 }
355
356
357 @Override
358 public final int hashCode()
359 {
360 final int prime = 31;
361 int result = 1;
362 long temp;
363 temp = Double.doubleToLongBits(this.valueSI);
364 result = prime * result + (int) (temp ^ (temp >>> 32));
365 return result;
366 }
367
368
369 @Override
370 public final boolean equals(final Object obj)
371 {
372 if (this == obj)
373 {
374 return true;
375 }
376 if (obj == null)
377 {
378 return false;
379 }
380 if (!(obj instanceof DoubleScalar))
381 {
382 return false;
383 }
384 DoubleScalar<?> other = (DoubleScalar<?>) obj;
385
386 if (this.isAbsolute() != other.isAbsolute() || this.isRelative() != other.isRelative())
387 {
388 return false;
389 }
390
391 if (!this.getUnit().getStandardUnit().equals(other.getUnit().getStandardUnit()))
392 {
393 return false;
394 }
395 if (Double.doubleToLongBits(this.valueSI) != Double.doubleToLongBits(other.valueSI))
396 {
397 return false;
398 }
399 return true;
400 }
401
402
403
404
405
406
407
408
409
410
411
412
413
414 public static <U extends Unit<U>> MutableDoubleScalar.Abs<U> plus(final DoubleScalar.Abs<U> left,
415 final DoubleScalar.Rel<U> right)
416 {
417 MutableDoubleScalar.Abs<U> result = new MutableDoubleScalar.Abs<U>(left);
418 result.incrementByImpl(right);
419 return result;
420 }
421
422
423
424
425
426
427
428
429
430 public static <U extends Unit<U>> MutableDoubleScalar.Rel<U> plus(final DoubleScalar.Rel<U> left,
431 final DoubleScalar.Rel<U> right)
432 {
433 MutableDoubleScalar.Rel<U> result = new MutableDoubleScalar.Rel<U>(left);
434 result.incrementByImpl(right);
435 return result;
436 }
437
438
439
440
441
442
443
444
445
446 public static <U extends Unit<U>> MutableDoubleScalar.Abs<U> minus(final DoubleScalar.Abs<U> left,
447 final DoubleScalar.Rel<U> right)
448 {
449 MutableDoubleScalar.Abs<U> result = new MutableDoubleScalar.Abs<U>(left);
450 result.decrementByImpl(right);
451 return result;
452 }
453
454
455
456
457
458
459
460
461
462 public static <U extends Unit<U>> MutableDoubleScalar.Rel<U> minus(final DoubleScalar.Rel<U> left,
463 final DoubleScalar.Rel<U> right)
464 {
465 MutableDoubleScalar.Rel<U> result = new MutableDoubleScalar.Rel<U>(left);
466 result.decrementByImpl(right);
467 return result;
468 }
469
470
471
472
473
474
475
476
477
478 public static <U extends Unit<U>> MutableDoubleScalar.Rel<U> minus(final DoubleScalar.Abs<U> valueAbs1,
479 final DoubleScalar.Abs<U> valueAbs2)
480 {
481 MutableDoubleScalar.Rel<U> result = new MutableDoubleScalar.Rel<U>(valueAbs1.getInUnit(), valueAbs1.getUnit());
482 result.decrementBy(valueAbs2);
483 return result;
484 }
485
486
487
488
489
490
491
492 public static MutableDoubleScalar.Abs<SIUnit> multiply(final DoubleScalar.Abs<?> left,
493 final DoubleScalar.Abs<?> right)
494 {
495 SIUnit targetUnit =
496 Unit.lookupOrCreateSIUnitWithSICoefficients(SICoefficients.multiply(left.getUnit().getSICoefficients(),
497 right.getUnit().getSICoefficients()).toString());
498 return new MutableDoubleScalar.Abs<SIUnit>(left.getSI() * right.getSI(), targetUnit);
499 }
500
501
502
503
504
505
506
507 public static MutableDoubleScalar.Rel<SIUnit> multiply(final DoubleScalar.Rel<?> left,
508 final DoubleScalar.Rel<?> right)
509 {
510 SIUnit targetUnit =
511 Unit.lookupOrCreateSIUnitWithSICoefficients(SICoefficients.multiply(left.getUnit().getSICoefficients(),
512 right.getUnit().getSICoefficients()).toString());
513 return new MutableDoubleScalar.Rel<SIUnit>(left.getSI() * right.getSI(), targetUnit);
514 }
515
516
517
518
519
520
521
522 public static MutableDoubleScalar.Abs<SIUnit> divide(final DoubleScalar.Abs<?> left, final DoubleScalar.Abs<?> right)
523 {
524 SIUnit targetUnit =
525 Unit.lookupOrCreateSIUnitWithSICoefficients(SICoefficients.divide(left.getUnit().getSICoefficients(),
526 right.getUnit().getSICoefficients()).toString());
527 return new MutableDoubleScalar.Abs<SIUnit>(left.getSI() / right.getSI(), targetUnit);
528 }
529
530
531
532
533
534
535
536 public static MutableDoubleScalar.Rel<SIUnit> divide(final DoubleScalar.Rel<?> left, final DoubleScalar.Rel<?> right)
537 {
538 SIUnit targetUnit =
539 Unit.lookupOrCreateSIUnitWithSICoefficients(SICoefficients.divide(left.getUnit().getSICoefficients(),
540 right.getUnit().getSICoefficients()).toString());
541 return new MutableDoubleScalar.Rel<SIUnit>(left.getSI() / right.getSI(), targetUnit);
542 }
543
544
545
546
547
548
549
550
551
552 public static <U extends Unit<U>> MutableDoubleScalar.Abs<U> interpolate(final DoubleScalar.Abs<U> zero,
553 final DoubleScalar.Abs<U> one, final double ratio)
554 {
555 MutableDoubleScalar.Abs<U> result = zero.mutable();
556 result.setSI(result.getSI() * (1 - ratio) + one.getSI() * ratio);
557 return result;
558 }
559
560
561
562
563
564
565
566
567
568 public static <U extends Unit<U>> MutableDoubleScalar.Rel<U> interpolate(final DoubleScalar.Rel<U> zero,
569 final DoubleScalar.Rel<U> one, final double ratio)
570 {
571 MutableDoubleScalar.Rel<U> result = zero.mutable();
572 result.setSI(result.getSI() * (1 - ratio) + one.getSI() * ratio);
573 return result;
574 }
575
576 }