1 package org.djunits.value.vfloat.vector; 2 3 import java.io.Serializable; 4 import java.util.Iterator; 5 import java.util.List; 6 import java.util.NoSuchElementException; 7 import java.util.SortedMap; 8 9 import org.djunits.unit.Unit; 10 import org.djunits.value.Relative; 11 import org.djunits.value.StorageType; 12 import org.djunits.value.ValueException; 13 import org.djunits.value.vfloat.scalar.AbstractFloatScalarRel; 14 15 /** 16 * Relative Immutable typed vector. 17 * <p> 18 * Copyright (c) 2013-2018 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 relative vector type 27 * @param <MR> the mutable relative vector type 28 * @param <S> the relative scalar type 29 */ 30 abstract class AbstractFloatVectorRel<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 AbstractFloatVector<U, R> implements Relative, Serializable, Iterable<S> 33 { 34 /** */ 35 private static final long serialVersionUID = 20151006L; 36 37 /** 38 * Construct a new Relative Immutable FloatVector. 39 * @param values float[]; the values of the entries in the new Relative Immutable FloatVector 40 * @param unit U; the unit of the new Relative Immutable FloatVector 41 * @param storageType the data type to use (e.g., DENSE or SPARSE) 42 * @throws ValueException when values is null 43 */ 44 AbstractFloatVectorRel(final float[] values, final U unit, final StorageType storageType) throws ValueException 45 { 46 super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType)); 47 } 48 49 /** 50 * Construct a new Relative Immutable FloatVector. 51 * @param values List; the values of the entries in the new Relative Immutable FloatVector 52 * @param unit U; the unit of the new Relative Immutable FloatVector 53 * @param storageType the data type to use (e.g., DENSE or SPARSE) 54 * @throws ValueException when values is null 55 */ 56 AbstractFloatVectorRel(final List<Float> values, final U unit, final StorageType storageType) throws ValueException 57 { 58 super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType)); 59 } 60 61 /** 62 * Construct a new Relative Immutable FloatVector. 63 * @param values FloatScalar.Rel<U>[]; the values of the entries in the new Relative Immutable FloatVector 64 * @param storageType the data type to use (e.g., DENSE or SPARSE) 65 * @throws ValueException when values has zero entries 66 */ 67 AbstractFloatVectorRel(final S[] values, final StorageType storageType) throws ValueException 68 { 69 super(checkUnit(values), FloatVectorData.instantiate(values, storageType)); 70 } 71 72 /** 73 * Construct a new Relative Immutable FloatVector. 74 * @param values List; the values of the entries in the new Relative Immutable FloatVector 75 * @param storageType the data type to use (e.g., DENSE or SPARSE) 76 * @throws ValueException when values has zero entries 77 */ 78 AbstractFloatVectorRel(final List<S> values, final StorageType storageType) throws ValueException 79 { 80 super(checkUnit(values), FloatVectorData.instantiateLD(values, storageType)); 81 } 82 83 /** 84 * Construct a new Relative Immutable FloatVector. 85 * @param values FloatScalar.Rel<U>[]; the values of the entries in the new Relative Sparse Mutable FloatVector 86 * @param length the size of the vector 87 * @param storageType the data type to use (e.g., DENSE or SPARSE) 88 * @throws ValueException when values has zero entries 89 */ 90 AbstractFloatVectorRel(final SortedMap<Integer, S> values, final int length, final StorageType storageType) 91 throws ValueException 92 { 93 super(checkUnit(values), FloatVectorData.instantiateMD(values, length, storageType)); 94 } 95 96 /** 97 * Construct a new Relative Immutable FloatVector. 98 * @param values Map; the map of indexes to values of the Relative Sparse Mutable FloatVector 99 * @param unit U; the unit of the new Relative Sparse Mutable FloatVector 100 * @param length the size of the vector 101 * @param storageType the data type to use (e.g., DENSE or SPARSE) 102 * @throws ValueException when values is null 103 */ 104 AbstractFloatVectorRel(final SortedMap<Integer, Float> values, final U unit, final int length, 105 final StorageType storageType) throws ValueException 106 { 107 super(unit, FloatVectorData.instantiate(values, length, unit.getScale(), storageType)); 108 } 109 110 /** 111 * Construct a new Relative Immutable FloatVector. 112 * @param data an internal data object 113 * @param unit the unit 114 */ 115 AbstractFloatVectorRel(final FloatVectorData data, final U unit) 116 { 117 super(unit, data.copy()); 118 } 119 120 /** 121 * Create a mutable version of this FloatVector. <br> 122 * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation 123 * in the mutable version that modifies the data shall trigger a deep copy of the data. 124 * @return MR; mutable version of this FloatVector 125 */ 126 @Override 127 public MR mutable() 128 { 129 return instantiateMutableType(getData(), getUnit()); 130 } 131 132 /** 133 * Construct a new Relative Immutable FloatVector of the right type. Each extending class must implement this method. 134 * @param dvd an internal data object 135 * @param unit the unit 136 * @return R the FloatVector of the right type 137 */ 138 protected abstract R instantiateType(FloatVectorData dvd, U unit); 139 140 /** 141 * Construct a new Relative Mutable FloatVector of the right type. Each extending class must implement this method. 142 * @param dvd an internal data object 143 * @param unit the unit 144 * @return MR the Mutable FloatVector of the right type 145 */ 146 protected abstract MR instantiateMutableType(FloatVectorData dvd, U unit); 147 148 /** 149 * Construct a new Relative Immutable FloatScalar of the right type. Each extending class must implement this method. 150 * @param value the value 151 * @param unit the unit 152 * @return S the Immutable FloatScalar of the right type 153 */ 154 protected abstract S instantiateScalar(float value, U unit); 155 156 /** {@inheritDoc} */ 157 @Override 158 public S get(final int index) throws ValueException 159 { 160 return instantiateScalar(getInUnit(index, getUnit()), getUnit()); 161 } 162 163 /**********************************************************************************/ 164 /**************************** TYPED CALCULATION METHODS ***************************/ 165 /**********************************************************************************/ 166 167 /** 168 * Add a Relative value to this Relative value for a vector or matrix. The addition is done value by value and store the 169 * result in a new Relative value. If both operands are sparse, the result is a sparse vector or matrix, otherwise the 170 * result is a dense vector or matrix. 171 * @param rel the right operand 172 * @return the addition of this vector and the operand 173 * @throws ValueException in case this vector or matrix and the operand have a different size 174 */ 175 public final R plus(final R rel) throws ValueException 176 { 177 return instantiateType(this.getData().plus(rel.getData()), getUnit()); 178 } 179 180 /** 181 * Subtract a Relative value from this Relative value for a vector or matrix. The subtraction is done value by value and 182 * store the result in a new Relative value. If both operands are sparse, the result is a sparse vector or matrix, otherwise 183 * the result is a dense vector or matrix. 184 * @param rel the right operand 185 * @return the subtraction of this vector and the operand 186 * @throws ValueException in case this vector or matrix and the operand have a different size 187 */ 188 public final R minus(final R rel) throws ValueException 189 { 190 return instantiateType(this.getData().minus(rel.getData()), getUnit()); 191 } 192 193 /** 194 * Multiply a Relative value with this Relative value for a vector or matrix. The multiplication is done value by value and 195 * store the result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise 196 * the result is a sparse vector or matrix. 197 * @param rel the right operand 198 * @return the multiplication of this vector and the operand 199 * @throws ValueException in case this vector or matrix and the operand have a different size 200 */ 201 public final R times(final R rel) throws ValueException 202 { 203 return instantiateType(this.getData().times(rel.getData()), getUnit()); 204 } 205 206 /** 207 * Divide this Relative value by a Relative value for a vector or matrix. The division is done value by value and store the 208 * result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise the result 209 * is a sparse vector or matrix. 210 * @param rel the right operand 211 * @return the division of this vector and the operand 212 * @throws ValueException in case this vector or matrix and the operand have a different size 213 */ 214 public final R divide(final R rel) throws ValueException 215 { 216 return instantiateType(this.getData().divide(rel.getData()), getUnit()); 217 } 218 219 /* ============================================================================================ */ 220 /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */ 221 /* ============================================================================================ */ 222 223 /** 224 * Check that a provided array can be used to create some descendant of a FloatVector, and return the Unit. 225 * @param dsArray the array to check and get the unit for 226 * @param <U> the unit 227 * @param <S> the scalar type 228 * @return the unit of the object 229 * @throws ValueException when the array has length equal to 0 230 */ 231 static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final AbstractFloatScalarRel<U, S>[] dsArray) 232 throws ValueException 233 { 234 if (dsArray != null && dsArray.length > 0) 235 { 236 return dsArray[0].getUnit(); 237 } 238 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty array of FloatScalar"); 239 } 240 241 /** 242 * Check that a provided list can be used to create some descendant of a FloatVector, and return the Unit. 243 * @param dsList the list to check and get the unit for 244 * @param <U> the unit 245 * @param <S> the scalar in the list 246 * @return the unit of the object 247 * @throws ValueException when the array has length equal to 0 248 */ 249 static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final List<S> dsList) throws ValueException 250 { 251 if (dsList != null && dsList.size() > 0) 252 { 253 return dsList.get(0).getUnit(); 254 } 255 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty list of FloatScalar"); 256 } 257 258 /** 259 * Check that a provided Map can be used to create some descendant of a FloatVector. 260 * @param dsMap the provided map 261 * @param <U> Unit; the unit of the FloatScalar list 262 * @param <S> the scalar in the list 263 * @return List the provided list 264 * @throws ValueException when the list has size equal to 0 265 */ 266 static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final SortedMap<Integer, S> dsMap) 267 throws ValueException 268 { 269 if (dsMap != null && dsMap.size() > 0) 270 { 271 return dsMap.get(dsMap.firstKey()).getUnit(); 272 } 273 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty Map of FloatScalar"); 274 } 275 276 /* ============================================================================================ */ 277 /* =============================== ITERATOR METHODS AND CLASS ================================= */ 278 /* ============================================================================================ */ 279 280 /** 281 * Returns an iterator over the scalars in this vector in proper sequence. 282 * @return an iterator over the scalars in this vector in proper sequence 283 */ 284 @Override 285 public Iterator<S> iterator() 286 { 287 return new Itr(); 288 } 289 290 /** 291 * The iterator class is loosely based in AbstractList.Itr. It does not throw a ConcurrentModificationException, because the 292 * size of the vector does not change. Normal (non-mutable) vectors cannot change their size, nor their content. The only 293 * thing for the MutableVector that can change is its content, not its length. 294 */ 295 protected class Itr implements Iterator<S> 296 { 297 /** index of next element to return. */ 298 private int cursor = 0; 299 300 @Override 301 public boolean hasNext() 302 { 303 return this.cursor != size(); 304 } 305 306 /** {@inheritDoc} */ 307 @Override 308 public S next() 309 { 310 if (this.cursor >= size()) 311 { 312 throw new NoSuchElementException(); 313 } 314 try 315 { 316 int i = this.cursor; 317 S next = get(i); 318 this.cursor = i + 1; 319 return next; 320 } 321 catch (ValueException exception) 322 { 323 throw new RuntimeException(exception); 324 } 325 } 326 327 /** {@inheritDoc} */ 328 @Override 329 public void remove() 330 { 331 throw new RuntimeException("Remove function cannot be applied on fixed-size DJUNITS Vector"); 332 } 333 } 334 335 }