1 package org.djunits.value.vfloat.vector; 2 3 import java.util.List; 4 import java.util.SortedMap; 5 6 import org.djunits.unit.Unit; 7 import org.djunits.value.MathFunctionsRel; 8 import org.djunits.value.StorageType; 9 import org.djunits.value.ValueException; 10 import org.djunits.value.ValueUtil; 11 import org.djunits.value.vfloat.FloatFunction; 12 import org.djunits.value.vfloat.FloatMathFunctions; 13 import org.djunits.value.vfloat.scalar.AbstractFloatScalarRel; 14 15 /** 16 * Relative Mutable typed Vector. 17 * <p> 18 * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 19 * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>. 20 * <p> 21 * $LastChangedDate: 2015-09-29 14:14:28 +0200 (Tue, 29 Sep 2015) $, @version $Revision: 73 $, by $Author: pknoppers $, initial 22 * version Sep 5, 2015 <br> 23 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 24 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 25 * @param <U> the unit 26 * @param <R> the vector type 27 * @param <MR> the mutable vector type 28 * @param <S> the scalar type 29 */ 30 abstract class AbstractMutableFloatVectorRel<U extends Unit<U>, R extends AbstractFloatVectorRel<U, R, MR, S>, 31 MR extends AbstractMutableFloatVectorRel<U, R, MR, S>, S extends AbstractFloatScalarRel<U, S>> 32 extends AbstractFloatVectorRel<U, R, MR, S> 33 implements MathFunctionsRel<MR>, FloatMathFunctions<MR>, MutableFloatVectorInterface<U> 34 { 35 /** */ 36 private static final long serialVersionUID = 20151006L; 37 38 /** If set, any modification of the data must be preceded by replacing the data with a local copy. */ 39 private boolean copyOnWrite = false; 40 41 /** 42 * Construct a new Relative Mutable FloatVector. 43 * @param values float[]; the values of the entries in the new Relative Mutable FloatVector 44 * @param unit U; the unit of the new Relative Mutable FloatVector 45 * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE) 46 * @throws ValueException when values is null 47 */ 48 AbstractMutableFloatVectorRel(final float[] values, final U unit, final StorageType storageType) throws ValueException 49 { 50 super(values, unit, storageType); 51 } 52 53 /** 54 * Construct a new Relative Mutable FloatVector. 55 * @param values List<Float>; the values of the entries in the new Relative Mutable FloatVector 56 * @param unit U; the unit of the new Relative Mutable FloatVector 57 * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE) 58 * @throws ValueException when values is null 59 */ 60 AbstractMutableFloatVectorRel(final List<Float> values, final U unit, final StorageType storageType) throws ValueException 61 { 62 super(values, unit, storageType); 63 } 64 65 /** 66 * Construct a new Relative Mutable FloatVector. 67 * @param values S[]; the values of the entries in the new Relative Mutable FloatVector 68 * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE) 69 * @throws ValueException when values has zero entries 70 */ 71 AbstractMutableFloatVectorRel(final S[] values, final StorageType storageType) throws ValueException 72 { 73 super(values, storageType); 74 } 75 76 /** 77 * Construct a new Relative Mutable FloatVector. 78 * @param values List<S>; the values of the entries in the new Relative Mutable FloatVector 79 * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE) 80 * @throws ValueException when values has zero entries 81 */ 82 AbstractMutableFloatVectorRel(final List<S> values, final StorageType storageType) throws ValueException 83 { 84 super(values, storageType); 85 } 86 87 /** 88 * Construct a new Relative Mutable FloatVector. 89 * @param values SortedMap<Integer, S>; the values of the entries in the new Relative Sparse Mutable FloatVector 90 * @param length int; the size of the vector 91 * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE) 92 * @throws ValueException when values has zero entries 93 */ 94 AbstractMutableFloatVectorRel(final SortedMap<Integer, S> values, final int length, final StorageType storageType) 95 throws ValueException 96 { 97 super(values, length, storageType); 98 } 99 100 /** 101 * Construct a new Relative Mutable FloatVector. 102 * @param values SortedMap<Integer, Float>; the map of indexes to values of the Relative Sparse Mutable FloatVector 103 * @param unit U; the unit of the new Relative Sparse Mutable FloatVector 104 * @param length int; the size of the vector 105 * @param storageType StorageType; the data type to use (e.g., DENSE or SPARSE) 106 * @throws ValueException when values is null 107 */ 108 AbstractMutableFloatVectorRel(final SortedMap<Integer, Float> values, final U unit, final int length, 109 final StorageType storageType) throws ValueException 110 { 111 super(values, unit, length, storageType); 112 } 113 114 /** 115 * Construct a new Relative Mutable FloatVector. 116 * @param data FloatVectorData; an internal data object 117 * @param unit U; the unit 118 */ 119 AbstractMutableFloatVectorRel(final FloatVectorData data, final U unit) 120 { 121 super(data, unit); 122 } 123 124 /** 125 * Retrieve the value of the copyOnWrite flag. 126 * @return boolean 127 */ 128 private boolean isCopyOnWrite() 129 { 130 return this.copyOnWrite; 131 } 132 133 /** 134 * Change the copyOnWrite flag. 135 * @param copyOnWrite boolean; the new value for the copyOnWrite flag 136 */ 137 final void setCopyOnWrite(final boolean copyOnWrite) 138 { 139 this.copyOnWrite = copyOnWrite; 140 } 141 142 /** {@inheritDoc} */ 143 @Override 144 public final MR mutable() 145 { 146 setCopyOnWrite(true); 147 final MR result = instantiateMutableType(getData(), getUnit()); 148 result.setCopyOnWrite(true); 149 return result; 150 } 151 152 /** 153 * Create a immutable version of this MutableFloatVector. <br> 154 * @return FloatVector<U>; mutable version of this MutableFloatVector 155 */ 156 @Override 157 public R immutable() 158 { 159 setCopyOnWrite(true); 160 return instantiateType(getData(), getUnit()); 161 } 162 163 /**********************************************************************************/ 164 /**************************** TYPED CALCULATION METHODS ***************************/ 165 /**********************************************************************************/ 166 167 /** 168 * Create a deep copy of this MutableFloatVector. <br> 169 * @return FloatVector<U>; deep copy of this MutableFloatVector 170 */ 171 public final MR copy() 172 { 173 return mutable(); 174 } 175 176 /** 177 * Increment the value by the supplied value and return the changed vector. 178 * @param increment R; amount by which the value is incremented 179 * @return the changed MutableFloatVector.Rel<U> 180 * @throws ValueException when the size of increment is not identical to the size of this 181 */ 182 @SuppressWarnings("unchecked") 183 public final MR incrementBy(final R increment) throws ValueException 184 { 185 checkCopyOnWrite(); 186 this.data.incrementBy(increment.getData()); 187 return (MR) this; 188 } 189 190 /** 191 * Increment the value by the supplied value and return the changed vector. 192 * @param increment S; amount by which the value is incremented 193 * @return the changed MutableFloatVector.Rel<U> 194 */ 195 public final MR incrementBy(final S increment) 196 { 197 return incrementBy(increment.si); 198 } 199 200 /** 201 * Increment the value by the supplied constant and return the changed vector. 202 * @param increment float; amount by which the value is incremented 203 * @return the changed MutableFloatVector.Rel<U> 204 */ 205 @SuppressWarnings("unchecked") 206 public final MR incrementBy(final float increment) 207 { 208 checkCopyOnWrite(); 209 this.data.incrementBy(increment); 210 return (MR) this; 211 } 212 213 /** 214 * Decrement the value by the supplied value and return the changed vector. 215 * @param decrement R; amount by which the value is decremented 216 * @return the changed MutableFloatVector.Rel<U> 217 * @throws ValueException when the size of increment is not identical to the size of this 218 */ 219 @SuppressWarnings("unchecked") 220 public final MR decrementBy(final R decrement) throws ValueException 221 { 222 checkCopyOnWrite(); 223 this.data.decrementBy(decrement.getData()); 224 return (MR) this; 225 } 226 227 /** 228 * Decrement the value by the supplied value and return the changed vector. 229 * @param decrement S; amount by which the value is decremented 230 * @return the changed MutableFloatVector.Rel<U> 231 */ 232 public final MR decrementBy(final S decrement) 233 { 234 return decrementBy(decrement.si); 235 } 236 237 /** 238 * Decrement the value by the supplied constant and return the changed vector. 239 * @param decrement float; amount by which the value is decremented 240 * @return the changed MutableFloatVector.Rel<U> 241 */ 242 @SuppressWarnings("unchecked") 243 public final MR decrementBy(final float decrement) 244 { 245 checkCopyOnWrite(); 246 this.data.decrementBy(decrement); 247 return (MR) this; 248 } 249 250 /** 251 * Multiply the values in the vector by the supplied values and return the changed vector. 252 * @param factors R; amounts by which the value is multiplied 253 * @return the changed MutableFloatVector.Rel<U> 254 * @throws ValueException when the size of the factors is not identical to the size of this 255 */ 256 @SuppressWarnings("unchecked") 257 public final MR multiplyBy(final R factors) throws ValueException 258 { 259 checkCopyOnWrite(); 260 this.data.multiplyBy(factors.getData()); 261 return (MR) this; 262 } 263 264 /** 265 * Multiply the values in the vector by the supplied value and return the changed vector. 266 * @param factor S; amount by which the values in the vector are multiplied 267 * @return the changed MutableFloatVector.Rel<U> 268 */ 269 public final MR multiplyBy(final S factor) 270 { 271 return multiplyBy(factor.si); 272 } 273 274 /** {@inheritDoc} */ 275 @SuppressWarnings("unchecked") 276 @Override 277 public final MR multiplyBy(final float factor) 278 { 279 checkCopyOnWrite(); 280 this.data.multiplyBy(factor); 281 return (MR) this; 282 } 283 284 /** 285 * Divide the values in the vector by the supplied values and return the changed vector. 286 * @param factors R; amounts by which the value is divided 287 * @return the changed MutableFloatVector.Rel<U> 288 * @throws ValueException when the size of the factors is not identical to the size of this 289 */ 290 @SuppressWarnings("unchecked") 291 public final MR divideBy(final R factors) throws ValueException 292 { 293 checkCopyOnWrite(); 294 this.data.divideBy(factors.getData()); 295 return (MR) this; 296 } 297 298 /** {@inheritDoc} */ 299 @Override 300 @SuppressWarnings({ "checkstyle:designforextension", "unchecked" }) 301 public MR divideBy(final float factor) 302 { 303 this.data.divideBy(factor); 304 return (MR) this; 305 } 306 307 /** 308 * Divide the values in the vector by the supplied value and return the changed vector. 309 * @param factor S; amount by which the values in the vector are divided 310 * @return the changed MutableFloatVector.Rel<U> 311 */ 312 public final MR divideBy(final S factor) 313 { 314 return divideBy(factor.si); 315 } 316 317 /**********************************************************************************/ 318 /********************************** MATH METHODS **********************************/ 319 /**********************************************************************************/ 320 321 /** 322 * Execute a function on a cell by cell basis. Note: because many functions have to act on zero cells or can generate cells 323 * with a zero value, the functions have to be applied on a dense dataset which has to be transformed back to a sparse 324 * dataset if necessary. 325 * @param floatFunction FloatFunction; the function to apply 326 */ 327 public final void assign(final FloatFunction floatFunction) 328 { 329 checkCopyOnWrite(); 330 if (this.data instanceof FloatVectorDataDense) 331 { 332 ((FloatVectorDataDense) this.data).assign(floatFunction); 333 } 334 else 335 { 336 FloatVectorDataDense dvdd = ((FloatVectorDataSparse) this.data).toDense(); 337 dvdd.assign(floatFunction); 338 this.data = dvdd.toSparse(); 339 } 340 } 341 342 /** {@inheritDoc} */ 343 @SuppressWarnings("unchecked") 344 @Override 345 public final MR abs() 346 { 347 assign(FloatMathFunctions.ABS); 348 return (MR) this; 349 } 350 351 /** {@inheritDoc} */ 352 @Override 353 @SuppressWarnings("unchecked") 354 public final MR ceil() 355 { 356 assign(FloatMathFunctions.CEIL); 357 return (MR) this; 358 } 359 360 /** {@inheritDoc} */ 361 @Override 362 @SuppressWarnings("unchecked") 363 public final MR floor() 364 { 365 assign(FloatMathFunctions.FLOOR); 366 return (MR) this; 367 } 368 369 /** {@inheritDoc} */ 370 @Override 371 @SuppressWarnings("unchecked") 372 public final MR neg() 373 { 374 assign(FloatMathFunctions.NEG); 375 return (MR) this; 376 } 377 378 /** {@inheritDoc} */ 379 @Override 380 @SuppressWarnings("unchecked") 381 public final MR rint() 382 { 383 assign(FloatMathFunctions.RINT); 384 return (MR) this; 385 } 386 387 /** {@inheritDoc} */ 388 @Override 389 @SuppressWarnings("unchecked") 390 public final MR round() 391 { 392 assign(FloatMathFunctions.ROUND); 393 return (MR) this; 394 } 395 396 /** 397 * Check the copyOnWrite flag and, if it is set, make a deep copy of the data and clear the flag. 398 */ 399 protected final void checkCopyOnWrite() 400 { 401 if (isCopyOnWrite()) 402 { 403 this.data = this.data.copy(); 404 setCopyOnWrite(false); 405 } 406 } 407 408 /** 409 * Replace the value at index by the supplied value which is expressed in the standard SI unit. 410 * @param index int; index of the value to replace 411 * @param valueSI float; the value to store (expressed in the standard SI unit) 412 * @throws ValueException when index out of range (index < 0 or index >= size()) 413 */ 414 public final void setSI(final int index, final float valueSI) throws ValueException 415 { 416 checkIndex(index); 417 checkCopyOnWrite(); 418 this.data.setSI(index, valueSI); 419 } 420 421 /** 422 * Replace the value at index by the supplied value which is in a compatible unit. 423 * @param index int; index of the value to replace 424 * @param value S; the strongly typed value to store 425 * @throws ValueException when index out of range (index < 0 or index >= size()) 426 */ 427 public final void set(final int index, final S value) throws ValueException 428 { 429 setSI(index, value.getSI()); 430 } 431 432 /** 433 * Replace the value at index by the supplied value which is expressed in a supplied (compatible) unit. 434 * @param index int; index of the value to replace 435 * @param value float; the value to store (which is expressed in valueUnit) 436 * @param valueUnit U; unit of the supplied value 437 * @throws ValueException when index out of range (index < 0 or index >= size()) 438 */ 439 public final void setInUnit(final int index, final float value, final U valueUnit) throws ValueException 440 { 441 setSI(index, (float) ValueUtil.expressAsSIUnit(value, valueUnit)); 442 } 443 444 /** 445 * Normalize the vector, i.e. scale the values to make the sum equal to 1. 446 * @throws ValueException when the sum of the values is zero and normalization is not possible 447 */ 448 public final void normalize() throws ValueException 449 { 450 float sum = zSum(); 451 if (0 == sum) 452 { 453 throw new ValueException("zSum is 0; cannot normalize"); 454 } 455 checkCopyOnWrite(); 456 this.data.divideBy(sum); 457 } 458 }