View Javadoc
1   package org.djunits.value.vdouble.scalar;
2   
3   import org.djunits.unit.AbsoluteLinearUnit;
4   import org.djunits.unit.SICoefficients;
5   import org.djunits.unit.SIUnit;
6   import org.djunits.unit.Unit;
7   
8   /**
9    * Immutable DoubleScalar, with Abs and Rel static subclasses.
10   * <p>
11   * Copyright (c) 2015-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
12   * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>.
13   * <p>
14   * $LastChangedDate: 2019-01-18 00:35:01 +0100 (Fri, 18 Jan 2019) $, @version $Revision: 324 $, by $Author: averbraeck $,
15   * initial version 26 jun, 2015 <br>
16   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
17   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
18   */
19  public abstract class DoubleScalar
20  {
21      /**
22       * Absolute Immutable DoubleScalar.
23       * @param <AU> Absolute unit
24       * @param <RU> Relative unit
25       */
26      public static class Abs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>>
27              extends AbstractDoubleScalarAbs<AU, DoubleScalar.Abs<AU, RU>, RU, DoubleScalar.Rel<RU>>
28      {
29          /**  */
30          private static final long serialVersionUID = 20150626L;
31  
32          /**
33           * Construct a new Absolute Immutable DoubleScalar.
34           * @param value double; the value of the new Absolute Immutable DoubleScalar
35           * @param unit AU; the unit of the new Absolute Immutable DoubleScalar
36           */
37          public Abs(final double value, final AU unit)
38          {
39              super(value, unit);
40          }
41  
42          /**
43           * Construct a new Absolute Immutable DoubleScalar from an existing Absolute Immutable DoubleScalar.
44           * @param value DoubleScalar.Abs&lt;AU, RU&gt;; the reference
45           */
46          public Abs(final DoubleScalar.Abs<AU, RU> value)
47          {
48              super(value);
49          }
50  
51          /** {@inheritDoc} */
52          @Override
53          public final DoubleScalar.Abs<AU, RU> instantiateAbs(final double value, final AU unit)
54          {
55              return new DoubleScalar.Abs<>(value, unit);
56          }
57  
58          /** {@inheritDoc} */
59          @Override
60          public final DoubleScalar.Rel<RU> instantiateRel(final double value, final RU unit)
61          {
62              return new DoubleScalar.Rel<>(value, unit);
63          }
64  
65      }
66  
67      /**
68       * Relative Immutable DoubleScalar.
69       * @param <U> Unit
70       */
71      public static class Rel<U extends Unit<U>> extends AbstractDoubleScalarRel<U, DoubleScalar.Rel<U>>
72      {
73          /**  */
74          private static final long serialVersionUID = 20150626L;
75  
76          /**
77           * Construct a new Relative Immutable DoubleScalar.
78           * @param value double; the value of the new Relative Immutable DoubleScalar
79           * @param unit U; the unit of the new Relative Immutable DoubleScalar
80           */
81          public Rel(final double value, final U unit)
82          {
83              super(value, unit);
84          }
85  
86          /**
87           * Construct a new Relative Immutable DoubleScalar from an existing Relative Immutable DoubleScalar.
88           * @param value DoubleScalar.Rel&lt;U&gt;; the reference
89           */
90          public Rel(final DoubleScalar.Rel<U> value)
91          {
92              super(value);
93          }
94  
95          /** {@inheritDoc} */
96          @Override
97          public final DoubleScalar.Rel<U> instantiateRel(final double value, final U unit)
98          {
99              return new DoubleScalar.Rel<>(value, unit);
100         }
101 
102     }
103 
104     /**********************************************************************************/
105     /********************************* STATIC METHODS *********************************/
106     /**********************************************************************************/
107 
108     /**
109      * Add a Relative value to an Absolute value. Return a new instance of the value. The unit of the return value will be the
110      * unit of the left argument.
111      * @param left A, an absolute typed DoubleScalar; the left argument
112      * @param right R, a relative typed DoubleScalar; the right argument
113      * @param <AU> Unit; the absolute unit of the parameters and the result
114      * @param <RU> Unit; the relative unit of the parameters and the result
115      * @param <R> the relative type
116      * @param <A> the corresponding absolute type
117      * @return A, an absolute typed DoubleScalar; the sum of the values as an Absolute value
118      */
119     public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, R extends AbstractDoubleScalarRel<RU, R>,
120             A extends AbstractDoubleScalarAbs<AU, A, RU, R>> A plus(final A left, final R right)
121     {
122         return left.plus(right);
123     }
124 
125     /**
126      * Add an Absolute value to a Relative value. Return a new instance of the value. The unit of the return value will be the
127      * unit of the left argument.
128      * @param left A, an absolute typed DoubleScalar; the left argument
129      * @param right R, a relative typed DoubleScalar; the right argument
130      * @param <AU> Unit; the absolute unit of the parameters and the result
131      * @param <RU> Unit; the relative unit of the parameters and the result
132      * @param <R> the relative type
133      * @param <A> the corresponding absolute type
134      * @return A, an absolute typed DoubleScalar; the sum of the values as an Absolute value
135      */
136     public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, R extends AbstractDoubleScalarRel<RU, R>,
137             A extends AbstractDoubleScalarAbs<AU, A, RU, R>> A plus(final R left, final A right)
138     {
139         return right.plus(left);
140     }
141 
142     /**
143      * Add a Relative value to a Relative value. Return a new instance of the value. The unit of the return value will be the
144      * unit of the left argument.
145      * @param left R, a relative typed DoubleScalar; the left argument
146      * @param right R, a relative typed DoubleScalar; the right argument
147      * @param <U> Unit; the unit of the parameters and the result
148      * @param <R> the relative type
149      * @return R, a relative typed DoubleScalar; the sum of the values as a Relative value
150      */
151     public static <U extends Unit<U>, R extends AbstractDoubleScalarRel<U, R>> R plus(final R left, final R right)
152     {
153         return left.plus(right);
154     }
155 
156     /**
157      * Subtract a Relative value from an absolute value. Return a new instance of the value. The unit of the return value will
158      * be the unit of the left argument.
159      * @param left A, an absolute typed DoubleScalar; the left value
160      * @param right R, a relative typed DoubleScalar; the right value
161      * @param <AU> Unit; the absolute unit of the parameters and the result
162      * @param <RU> Unit; the relative unit of the parameters and the result
163      * @param <R> the relative type
164      * @param <A> the corresponding absolute type
165      * @return A, an absolute typed DoubleScalar; the resulting value as an absolute value
166      */
167     public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, R extends AbstractDoubleScalarRel<RU, R>,
168             A extends AbstractDoubleScalarAbs<AU, A, RU, R>> A minus(final A left, final R right)
169     {
170         return left.minus(right);
171     }
172 
173     /**
174      * Subtract a relative value from a relative value. Return a new instance of the value. The unit of the value will be the
175      * unit of the first argument.
176      * @param left R, a relative typed DoubleScalar; the left value
177      * @param right R, a relative typed DoubleScalar; the right value
178      * @param <U> Unit; the unit of the parameters and the result
179      * @param <R> the relative type
180      * @return R, a relative typed DoubleScalar; the resulting value as a relative value
181      */
182     public static <U extends Unit<U>, R extends AbstractDoubleScalarRel<U, R>> R minus(final R left, final R right)
183     {
184         return left.minus(right);
185     }
186 
187     /**
188      * Subtract two absolute values. Return a new instance of a relative value of the difference. The unit of the value will be
189      * the unit of the first argument.
190      * @param left A, an absolute typed DoubleScalar; value 1
191      * @param right A, an absolute typed DoubleScalar; value 2
192      * @param <AU> Unit; the absolute unit of the parameters and the result
193      * @param <RU> Unit; the relative unit of the parameters and the result
194      * @param <R> the relative type
195      * @param <A> the corresponding absolute type
196      * @return R, a relative typed DoubleScalar; the difference of the two absolute values as a relative value
197      */
198     public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, R extends AbstractDoubleScalarRel<RU, R>,
199             A extends AbstractDoubleScalarAbs<AU, A, RU, R>> R minus(final A left, final A right)
200     {
201         return left.minus(right);
202     }
203 
204     /**
205      * Multiply two values; the result is a new instance with a different (existing or generated) SI unit.
206      * @param left AbstractDoubleScalarRel&lt;?, ?&gt;; the left operand
207      * @param right AbstractDoubleScalarRel&lt;?, ?&gt;; the right operand
208      * @return DoubleScalar.Rel&lt;SIUnit&gt;; the product of the two values
209      */
210     public static DoubleScalar.Rel<SIUnit> multiply(final AbstractDoubleScalarRel<?, ?> left,
211             final AbstractDoubleScalarRel<?, ?> right)
212     {
213         SIUnit targetUnit = Unit.lookupOrCreateSIUnitWithSICoefficients(
214                 SICoefficients.multiply(left.getUnit().getSICoefficients(), right.getUnit().getSICoefficients()).toString());
215         return new DoubleScalar.Rel<SIUnit>(left.getSI() * right.getSI(), targetUnit);
216     }
217 
218     /**
219      * Divide two values; the result is a new instance with a different (existing or generated) SI unit.
220      * @param left AbstractDoubleScalarRel&lt;?, ?&gt;; the left operand
221      * @param right AbstractDoubleScalarRel&lt;?, ?&gt;; the right operand
222      * @return DoubleScalar.Rel&lt;SIUnit&gt;; the ratio of the two values
223      */
224     public static DoubleScalar.Rel<SIUnit> divide(final AbstractDoubleScalarRel<?, ?> left,
225             final AbstractDoubleScalarRel<?, ?> right)
226     {
227         SIUnit targetUnit = Unit.lookupOrCreateSIUnitWithSICoefficients(
228                 SICoefficients.divide(left.getUnit().getSICoefficients(), right.getUnit().getSICoefficients()).toString());
229         return new DoubleScalar.Rel<SIUnit>(left.getSI() / right.getSI(), targetUnit);
230     }
231 
232     /**
233      * Interpolate between two values. Made to be able to call e.g., Area a = DoubleScalar.interpolate(a1, a2, 0.4);
234      * @param zero R; the low value
235      * @param one R; the high value
236      * @param ratio double; the ratio between 0 and 1, inclusive
237      * @param <U> Unit; the unit of the parameters and the result
238      * @param <R> the relative type
239      * @return a Scalar at the ratio between
240      */
241     public static <U extends Unit<U>, R extends AbstractDoubleScalarRel<U, R>> R interpolate(final R zero, final R one,
242             final double ratio)
243     {
244         return zero.instantiateRel(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getUnit()) * ratio, zero.getUnit());
245     }
246 
247     /**
248      * Interpolate between two values. Made to be able to call e.g., Time t = DoubleScalar.interpolate(t1, t2, 0.4);
249      * @param zero A; the low value
250      * @param one A; the high value
251      * @param ratio double; the ratio between 0 and 1, inclusive
252      * @param <AU> Unit; the absolute unit of the parameters and the result
253      * @param <RU> Unit; the relative unit of the parameters and the result
254      * @param <R> the relative type
255      * @param <A> the corresponding absolute type
256      * @return a Scalar at the ratio between
257      */
258     public static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, R extends AbstractDoubleScalarRel<RU, R>,
259             A extends AbstractDoubleScalarAbs<AU, A, RU, R>> A interpolate(final A zero, final A one, final double ratio)
260     {
261         return zero.instantiateAbs(zero.getInUnit() * (1 - ratio) + one.getInUnit(zero.getUnit()) * ratio, zero.getUnit());
262     }
263 
264     /**
265      * Return the maximum value of two relative scalars.
266      * @param r1 T; the first scalar
267      * @param r2 T; the second scalar
268      * @param <U> Unit; the unit of the parameters and the result
269      * @param <T> the argument and result type
270      * @return the maximum value of two relative scalars
271      */
272     public static <U extends Unit<U>, T extends AbstractDoubleScalar<U, T>> T max(final T r1, final T r2)
273     {
274         return (r1.gt(r2)) ? r1 : r2;
275     }
276 
277     /**
278      * Return the maximum value of more than two relative scalars.
279      * @param r1 T; the first scalar
280      * @param r2 T; the second scalar
281      * @param rn T...; the other scalars
282      * @param <U> Unit; the unit of the parameters and the result
283      * @param <T> the argument and result type
284      * @return the maximum value of more than two relative scalars
285      */
286     @SafeVarargs
287     public static <U extends Unit<U>, T extends AbstractDoubleScalar<U, T>> T max(final T r1, final T r2, final T... rn)
288     {
289         T maxr = (r1.gt(r2)) ? r1 : r2;
290         for (T r : rn)
291         {
292             if (r.gt(maxr))
293             {
294                 maxr = r;
295             }
296         }
297         return maxr;
298     }
299 
300     /**
301      * Return the minimum value of two relative scalars.
302      * @param r1 T; the first scalar
303      * @param r2 T; the second scalar
304      * @param <U> Unit; the unit of the parameters and the result
305      * @param <T> the argument and result type
306      * @return the minimum value of two relative scalars
307      */
308     public static <U extends Unit<U>, T extends AbstractDoubleScalar<U, T>> T min(final T r1, final T r2)
309     {
310         return (r1.lt(r2)) ? r1 : r2;
311     }
312 
313     /**
314      * Return the minimum value of more than two relative scalars.
315      * @param r1 T; the first scalar
316      * @param r2 T; the second scalar
317      * @param rn T...; the other scalars
318      * @param <U> Unit; the unit of the parameters and the result
319      * @param <T> the argument and result type
320      * @return the minimum value of more than two relative scalars
321      */
322     @SafeVarargs
323     public static <U extends Unit<U>, T extends AbstractDoubleScalar<U, T>> T min(final T r1, final T r2, final T... rn)
324     {
325         T minr = (r1.lt(r2)) ? r1 : r2;
326         for (T r : rn)
327         {
328             if (r.lt(minr))
329             {
330                 minr = r;
331             }
332         }
333         return minr;
334     }
335 
336 }