1 package org.djunits.value.vfloat.vector; 2 3 import java.io.Serializable; 4 import java.util.List; 5 import java.util.SortedMap; 6 7 import org.djunits.unit.Unit; 8 import org.djunits.value.Relative; 9 import org.djunits.value.StorageType; 10 import org.djunits.value.ValueException; 11 import org.djunits.value.vfloat.scalar.AbstractFloatScalarRel; 12 13 /** 14 * Relative Immutable typed vector. 15 * <p> 16 * Copyright (c) 2013-2017 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br> 17 * BSD-style license. See <a href="http://djunits.org/docs/license.html">DJUNITS License</a>. 18 * <p> 19 * $LastChangedDate: 2015-09-29 14:14:28 +0200 (Tue, 29 Sep 2015) $, @version $Revision: 73 $, by $Author: pknoppers $, initial 20 * version Sep 5, 2015 <br> 21 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a> 22 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a> 23 * @param <U> the unit 24 * @param <R> the relative vector type 25 * @param <MR> the mutable relative vector type 26 * @param <S> the relative scalar type 27 */ 28 abstract class AbstractFloatVectorRel<U extends Unit<U>, R extends AbstractFloatVectorRel<U, R, MR, S>, 29 MR extends AbstractMutableFloatVectorRel<U, R, MR, S>, S extends AbstractFloatScalarRel<U, S>> 30 extends AbstractFloatVector<U, R> implements Relative, Serializable 31 { 32 /** */ 33 private static final long serialVersionUID = 20151006L; 34 35 /** 36 * Construct a new Relative Immutable FloatVector. 37 * @param values float[]; the values of the entries in the new Relative Immutable FloatVector 38 * @param unit U; the unit of the new Relative Immutable FloatVector 39 * @param storageType the data type to use (e.g., DENSE or SPARSE) 40 * @throws ValueException when values is null 41 */ 42 AbstractFloatVectorRel(final float[] values, final U unit, final StorageType storageType) throws ValueException 43 { 44 super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType)); 45 } 46 47 /** 48 * Construct a new Relative Immutable FloatVector. 49 * @param values List; the values of the entries in the new Relative Immutable FloatVector 50 * @param unit U; the unit of the new Relative Immutable FloatVector 51 * @param storageType the data type to use (e.g., DENSE or SPARSE) 52 * @throws ValueException when values is null 53 */ 54 AbstractFloatVectorRel(final List<Float> values, final U unit, final StorageType storageType) throws ValueException 55 { 56 super(unit, FloatVectorData.instantiate(values, unit.getScale(), storageType)); 57 } 58 59 /** 60 * Construct a new Relative Immutable FloatVector. 61 * @param values FloatScalar.Rel<U>[]; the values of the entries in the new Relative Immutable FloatVector 62 * @param storageType the data type to use (e.g., DENSE or SPARSE) 63 * @throws ValueException when values has zero entries 64 */ 65 AbstractFloatVectorRel(final S[] values, final StorageType storageType) throws ValueException 66 { 67 super(checkUnit(values), FloatVectorData.instantiate(values, storageType)); 68 } 69 70 /** 71 * Construct a new Relative Immutable FloatVector. 72 * @param values List; the values of the entries in the new Relative Immutable FloatVector 73 * @param storageType the data type to use (e.g., DENSE or SPARSE) 74 * @throws ValueException when values has zero entries 75 */ 76 AbstractFloatVectorRel(final List<S> values, final StorageType storageType) throws ValueException 77 { 78 super(checkUnit(values), FloatVectorData.instantiateLD(values, storageType)); 79 } 80 81 /** 82 * Construct a new Relative Immutable FloatVector. 83 * @param values FloatScalar.Rel<U>[]; the values of the entries in the new Relative Sparse Mutable FloatVector 84 * @param length the size of the vector 85 * @param storageType the data type to use (e.g., DENSE or SPARSE) 86 * @throws ValueException when values has zero entries 87 */ 88 AbstractFloatVectorRel(final SortedMap<Integer, S> values, final int length, final StorageType storageType) 89 throws ValueException 90 { 91 super(checkUnit(values), FloatVectorData.instantiateMD(values, length, storageType)); 92 } 93 94 /** 95 * Construct a new Relative Immutable FloatVector. 96 * @param values Map; the map of indexes to values of the Relative Sparse Mutable FloatVector 97 * @param unit U; the unit of the new Relative Sparse Mutable FloatVector 98 * @param length the size of the vector 99 * @param storageType the data type to use (e.g., DENSE or SPARSE) 100 * @throws ValueException when values is null 101 */ 102 AbstractFloatVectorRel(final SortedMap<Integer, Float> values, final U unit, final int length, 103 final StorageType storageType) throws ValueException 104 { 105 super(unit, FloatVectorData.instantiate(values, length, unit.getScale(), storageType)); 106 } 107 108 /** 109 * Construct a new Relative Immutable FloatVector. 110 * @param data an internal data object 111 * @param unit the unit 112 */ 113 AbstractFloatVectorRel(final FloatVectorData data, final U unit) 114 { 115 super(unit, data.copy()); 116 } 117 118 /** 119 * Create a mutable version of this FloatVector. <br> 120 * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation 121 * in the mutable version that modifies the data shall trigger a deep copy of the data. 122 * @return MR; mutable version of this FloatVector 123 */ 124 @Override 125 public MR mutable() 126 { 127 return instantiateMutableType(getData(), getUnit()); 128 } 129 130 /** 131 * Construct a new Relative Immutable FloatVector of the right type. Each extending class must implement this method. 132 * @param dvd an internal data object 133 * @param unit the unit 134 * @return R the FloatVector of the right type 135 */ 136 protected abstract R instantiateType(FloatVectorData dvd, U unit); 137 138 /** 139 * Construct a new Relative Mutable FloatVector of the right type. Each extending class must implement this method. 140 * @param dvd an internal data object 141 * @param unit the unit 142 * @return MR the Mutable FloatVector of the right type 143 */ 144 protected abstract MR instantiateMutableType(FloatVectorData dvd, U unit); 145 146 /** 147 * Construct a new Relative Immutable FloatScalar of the right type. Each extending class must implement this method. 148 * @param value the value 149 * @param unit the unit 150 * @return S the Immutable FloatScalar of the right type 151 */ 152 protected abstract S instantiateScalar(float value, U unit); 153 154 /** {@inheritDoc} */ 155 @Override 156 public S get(final int index) throws ValueException 157 { 158 return instantiateScalar(getInUnit(index, getUnit()), getUnit()); 159 } 160 161 /**********************************************************************************/ 162 /**************************** TYPED CALCULATION METHODS ***************************/ 163 /**********************************************************************************/ 164 165 /** 166 * Add a Relative value to this Relative value for a vector or matrix. The addition is done value by value and store the 167 * result in a new Relative value. If both operands are sparse, the result is a sparse vector or matrix, otherwise the 168 * result is a dense vector or matrix. 169 * @param rel the right operand 170 * @return the addition of this vector and the operand 171 * @throws ValueException in case this vector or matrix and the operand have a different size 172 */ 173 public final R plus(final R rel) throws ValueException 174 { 175 return instantiateType(this.getData().plus(rel.getData()), getUnit()); 176 } 177 178 /** 179 * Subtract a Relative value from this Relative value for a vector or matrix. The subtraction is done value by value and 180 * store the result in a new Relative value. If both operands are sparse, the result is a sparse vector or matrix, otherwise 181 * the result is a dense vector or matrix. 182 * @param rel the right operand 183 * @return the subtraction of this vector and the operand 184 * @throws ValueException in case this vector or matrix and the operand have a different size 185 */ 186 public final R minus(final R rel) throws ValueException 187 { 188 return instantiateType(this.getData().minus(rel.getData()), getUnit()); 189 } 190 191 /** 192 * Multiply a Relative value with this Relative value for a vector or matrix. The multiplication is done value by value and 193 * store the result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise 194 * the result is a sparse vector or matrix. 195 * @param rel the right operand 196 * @return the multiplication of this vector and the operand 197 * @throws ValueException in case this vector or matrix and the operand have a different size 198 */ 199 public final R times(final R rel) throws ValueException 200 { 201 return instantiateType(this.getData().times(rel.getData()), getUnit()); 202 } 203 204 /** 205 * Divide this Relative value by a Relative value for a vector or matrix. The division is done value by value and store the 206 * result in a new Relative value. If both operands are dense, the result is a dense vector or matrix, otherwise the result 207 * is a sparse vector or matrix. 208 * @param rel the right operand 209 * @return the division of this vector and the operand 210 * @throws ValueException in case this vector or matrix and the operand have a different size 211 */ 212 public final R divide(final R rel) throws ValueException 213 { 214 return instantiateType(this.getData().divide(rel.getData()), getUnit()); 215 } 216 217 /* ============================================================================================ */ 218 /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */ 219 /* ============================================================================================ */ 220 221 /** 222 * Check that a provided array can be used to create some descendant of a FloatVector, and return the Unit. 223 * @param dsArray the array to check and get the unit for 224 * @param <U> the unit 225 * @param <S> the scalar type 226 * @return the unit of the object 227 * @throws ValueException when the array has length equal to 0 228 */ 229 static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final AbstractFloatScalarRel<U, S>[] dsArray) 230 throws ValueException 231 { 232 if (dsArray != null && dsArray.length > 0) 233 { 234 return dsArray[0].getUnit(); 235 } 236 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty array of FloatScalar"); 237 } 238 239 /** 240 * Check that a provided list can be used to create some descendant of a FloatVector, and return the Unit. 241 * @param dsList the list to check and get the unit for 242 * @param <U> the unit 243 * @param <S> the scalar in the list 244 * @return the unit of the object 245 * @throws ValueException when the array has length equal to 0 246 */ 247 static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final List<S> dsList) throws ValueException 248 { 249 if (dsList != null && dsList.size() > 0) 250 { 251 return dsList.get(0).getUnit(); 252 } 253 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty list of FloatScalar"); 254 } 255 256 /** 257 * Check that a provided Map can be used to create some descendant of a FloatVector. 258 * @param dsMap the provided map 259 * @param <U> Unit; the unit of the FloatScalar list 260 * @param <S> the scalar in the list 261 * @return List the provided list 262 * @throws ValueException when the list has size equal to 0 263 */ 264 static <U extends Unit<U>, S extends AbstractFloatScalarRel<U, S>> U checkUnit(final SortedMap<Integer, S> dsMap) 265 throws ValueException 266 { 267 if (dsMap != null && dsMap.size() > 0) 268 { 269 return dsMap.get(dsMap.firstKey()).getUnit(); 270 } 271 throw new ValueException("Cannot create a FloatVector or MutableFloatVector from a null or empty Map of FloatScalar"); 272 } 273 274 }