1 package org.djunits.value.vdouble.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.vdouble.scalar.AbstractDoubleScalarRel; 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 AbstractDoubleVectorRel<U extends Unit<U>, R extends AbstractDoubleVectorRel<U, R, MR, S>, 29 MR extends AbstractMutableDoubleVectorRel<U, R, MR, S>, S extends AbstractDoubleScalarRel<U, S>> 30 extends AbstractDoubleVector<U, R> implements Relative, Serializable 31 { 32 /** */ 33 private static final long serialVersionUID = 20151006L; 34 35 /** 36 * Construct a new Relative Immutable DoubleVector. 37 * @param values double[]; the values of the entries in the new Relative Immutable DoubleVector 38 * @param unit U; the unit of the new Relative Immutable DoubleVector 39 * @param storageType the data type to use (e.g., DENSE or SPARSE) 40 * @throws ValueException when values is null 41 */ 42 AbstractDoubleVectorRel(final double[] values, final U unit, final StorageType storageType) throws ValueException 43 { 44 super(unit, DoubleVectorData.instantiate(values, unit.getScale(), storageType)); 45 } 46 47 /** 48 * Construct a new Relative Immutable DoubleVector. 49 * @param values List; the values of the entries in the new Relative Immutable DoubleVector 50 * @param unit U; the unit of the new Relative Immutable DoubleVector 51 * @param storageType the data type to use (e.g., DENSE or SPARSE) 52 * @throws ValueException when values is null 53 */ 54 AbstractDoubleVectorRel(final List<Double> values, final U unit, final StorageType storageType) throws ValueException 55 { 56 super(unit, DoubleVectorData.instantiate(values, unit.getScale(), storageType)); 57 } 58 59 /** 60 * Construct a new Relative Immutable DoubleVector. 61 * @param values DoubleScalar.Rel<U>[]; the values of the entries in the new Relative Immutable DoubleVector 62 * @param storageType the data type to use (e.g., DENSE or SPARSE) 63 * @throws ValueException when values has zero entries 64 */ 65 AbstractDoubleVectorRel(final S[] values, final StorageType storageType) throws ValueException 66 { 67 super(checkUnit(values), DoubleVectorData.instantiate(values, storageType)); 68 } 69 70 /** 71 * Construct a new Relative Immutable DoubleVector. 72 * @param values List; the values of the entries in the new Relative Immutable DoubleVector 73 * @param storageType the data type to use (e.g., DENSE or SPARSE) 74 * @throws ValueException when values has zero entries 75 */ 76 AbstractDoubleVectorRel(final List<S> values, final StorageType storageType) throws ValueException 77 { 78 super(checkUnit(values), DoubleVectorData.instantiateLD(values, storageType)); 79 } 80 81 /** 82 * Construct a new Relative Immutable DoubleVector. 83 * @param values DoubleScalar.Rel<U>[]; the values of the entries in the new Relative Sparse Mutable DoubleVector 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 AbstractDoubleVectorRel(final SortedMap<Integer, S> values, final int length, final StorageType storageType) 89 throws ValueException 90 { 91 super(checkUnit(values), DoubleVectorData.instantiateMD(values, length, storageType)); 92 } 93 94 /** 95 * Construct a new Relative Immutable DoubleVector. 96 * @param values Map; the map of indexes to values of the Relative Sparse Mutable DoubleVector 97 * @param unit U; the unit of the new Relative Sparse Mutable DoubleVector 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 AbstractDoubleVectorRel(final SortedMap<Integer, Double> values, final U unit, final int length, 103 final StorageType storageType) throws ValueException 104 { 105 super(unit, DoubleVectorData.instantiate(values, length, unit.getScale(), storageType)); 106 } 107 108 /** 109 * Construct a new Relative Immutable DoubleVector. 110 * @param data an internal data object 111 * @param unit the unit 112 */ 113 AbstractDoubleVectorRel(final DoubleVectorData data, final U unit) 114 { 115 super(unit, data.copy()); 116 } 117 118 /** 119 * Create a mutable version of this DoubleVector. <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 DoubleVector 123 */ 124 @Override 125 public MR mutable() 126 { 127 return instantiateMutableType(getData(), getUnit()); 128 } 129 130 /** 131 * Construct a new Relative Immutable DoubleVector 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 DoubleVector of the right type 135 */ 136 protected abstract R instantiateType(DoubleVectorData dvd, U unit); 137 138 /** 139 * Construct a new Relative Mutable DoubleVector 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 DoubleVector of the right type 143 */ 144 protected abstract MR instantiateMutableType(DoubleVectorData dvd, U unit); 145 146 /** 147 * Construct a new Relative Immutable DoubleScalar 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 DoubleScalar of the right type 151 */ 152 protected abstract S instantiateScalar(double value, U unit); 153 154 /** {@inheritDoc} */ 155 @Override 156 public final 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 DoubleVector, 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 AbstractDoubleScalarRel<U, S>> U checkUnit( 230 final AbstractDoubleScalarRel<U, S>[] dsArray) throws ValueException 231 { 232 if (dsArray != null && dsArray.length > 0) 233 { 234 return dsArray[0].getUnit(); 235 } 236 throw new ValueException( 237 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty array of DoubleScalar"); 238 } 239 240 /** 241 * Check that a provided list can be used to create some descendant of a DoubleVector, and return the Unit. 242 * @param dsList the list to check and get the unit for 243 * @param <U> the unit 244 * @param <S> the scalar in the list 245 * @return the unit of the object 246 * @throws ValueException when the array has length equal to 0 247 */ 248 static <U extends Unit<U>, S extends AbstractDoubleScalarRel<U, S>> U checkUnit(final List<S> dsList) throws ValueException 249 { 250 if (dsList != null && dsList.size() > 0) 251 { 252 return dsList.get(0).getUnit(); 253 } 254 throw new ValueException( 255 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty list of DoubleScalar"); 256 } 257 258 /** 259 * Check that a provided Map can be used to create some descendant of a DoubleVector. 260 * @param dsMap the provided map 261 * @param <U> Unit; the unit of the DoubleScalar 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 AbstractDoubleScalarRel<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( 274 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty Map of DoubleScalar"); 275 } 276 }