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