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<AU, RU>; 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<U>; 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<?, ?>; the left operand 207 * @param right AbstractDoubleScalarRel<?, ?>; the right operand 208 * @return DoubleScalar.Rel<SIUnit>; 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<?, ?>; the left operand 221 * @param right AbstractDoubleScalarRel<?, ?>; the right operand 222 * @return DoubleScalar.Rel<SIUnit>; 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 }