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