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.AbsoluteLinearUnit; 8 import org.djunits.unit.Unit; 9 import org.djunits.value.Absolute; 10 import org.djunits.value.FunctionsAbs; 11 import org.djunits.value.StorageType; 12 import org.djunits.value.ValueException; 13 import org.djunits.value.vdouble.scalar.AbstractDoubleScalarAbs; 14 15 /** 16 * Absolute Immutable typed vector. 17 * <p> 18 * Copyright (c) 2013-2017 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 <AU> the absolute unit 26 * @param <RU> the relative unit 27 * @param <A> the absolute vector type 28 * @param <R> the relative vector type 29 * @param <MA> the mutable absolute vector type 30 * @param <S> the absolute scalar type 31 */ 32 abstract class AbstractDoubleVectorAbs<AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 33 A extends AbstractDoubleVectorAbs<AU, RU, A, R, MA, S>, R extends AbstractDoubleVectorRel<RU, R, ?, ?>, 34 MA extends AbstractMutableDoubleVectorAbs<AU, RU, A, R, MA, S>, S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> 35 extends AbstractDoubleVector<AU, A> implements FunctionsAbs<AU, RU, A, R>, Absolute, Serializable 36 { 37 /** */ 38 private static final long serialVersionUID = 20151006L; 39 40 /** 41 * Construct a new Absolute Immutable DoubleVector. 42 * @param values double[]; the values of the entries in the new Absolute Immutable DoubleVector 43 * @param unit AU; the unit of the new Absolute Immutable DoubleVector 44 * @param storageType the data type to use (e.g., DENSE or SPARSE) 45 * @throws ValueException when values is null 46 */ 47 AbstractDoubleVectorAbs(final double[] values, final AU unit, final StorageType storageType) throws ValueException 48 { 49 super(unit, DoubleVectorData.instantiate(values, unit.getScale(), storageType)); 50 } 51 52 /** 53 * Construct a new Absolute Immutable DoubleVector. 54 * @param values List; the values of the entries in the new Absolute Immutable DoubleVector 55 * @param unit AU; the unit of the new Absolute Immutable DoubleVector 56 * @param storageType the data type to use (e.g., DENSE or SPARSE) 57 * @throws ValueException when values is null 58 */ 59 AbstractDoubleVectorAbs(final List<Double> values, final AU unit, final StorageType storageType) throws ValueException 60 { 61 super(unit, DoubleVectorData.instantiate(values, unit.getScale(), storageType)); 62 } 63 64 /** 65 * Construct a new Absolute Immutable DoubleVector. 66 * @param values DoubleScalar.Abs<U>[]; the values of the entries in the new Absolute Immutable DoubleVector 67 * @param storageType the data type to use (e.g., DENSE or SPARSE) 68 * @throws ValueException when values has zero entries 69 */ 70 AbstractDoubleVectorAbs(final S[] values, final StorageType storageType) throws ValueException 71 { 72 super(checkUnit(values), DoubleVectorData.instantiate(values, storageType)); 73 } 74 75 /** 76 * Construct a new Absolute Immutable DoubleVector. 77 * @param values List; the values of the entries in the new Absolute Immutable DoubleVector 78 * @param storageType the data type to use (e.g., DENSE or SPARSE) 79 * @throws ValueException when values has zero entries 80 */ 81 AbstractDoubleVectorAbs(final List<S> values, final StorageType storageType) throws ValueException 82 { 83 super(checkUnit(values), DoubleVectorData.instantiateLD(values, storageType)); 84 } 85 86 /** 87 * Construct a new Absolute Immutable DoubleVector. 88 * @param values DoubleScalar.Abs<U>[]; the values of the entries in the new Absolute Sparse Mutable DoubleVector 89 * @param length the size of the vector 90 * @param storageType the data type to use (e.g., DENSE or SPARSE) 91 * @throws ValueException when values has zero entries 92 */ 93 AbstractDoubleVectorAbs(final SortedMap<Integer, S> values, final int length, final StorageType storageType) 94 throws ValueException 95 { 96 super(checkUnit(values), DoubleVectorData.instantiateMD(values, length, storageType)); 97 } 98 99 /** 100 * Construct a new Absolute Immutable DoubleVector. 101 * @param values Map; the map of indexes to values of the Absolute Sparse Mutable DoubleVector 102 * @param unit AU; the unit of the new Absolute Sparse Mutable DoubleVector 103 * @param length the size of the vector 104 * @param storageType the data type to use (e.g., DENSE or SPARSE) 105 * @throws ValueException when values is null 106 */ 107 AbstractDoubleVectorAbs(final SortedMap<Integer, Double> values, final AU unit, final int length, 108 final StorageType storageType) throws ValueException 109 { 110 super(unit, DoubleVectorData.instantiate(values, length, unit.getScale(), storageType)); 111 } 112 113 /** 114 * Construct a new Relative Immutable DoubleVector. 115 * @param data an internal data object 116 * @param unit the unit 117 */ 118 AbstractDoubleVectorAbs(final DoubleVectorData data, final AU unit) 119 { 120 super(unit, data.copy()); 121 } 122 123 /** 124 * Create a mutable version of this DoubleVector. <br> 125 * The mutable version is created with a shallow copy of the data and the internal copyOnWrite flag set. The first operation 126 * in the mutable version that modifies the data shall trigger a deep copy of the data. 127 * @return MA; mutable version of this DoubleVector 128 */ 129 @Override 130 public MA mutable() 131 { 132 return instantiateMutableType(getData(), getUnit()); 133 } 134 135 /** 136 * Construct a new Absolute Immutable DoubleVector of the right type. Each extending class must implement this method. 137 * @param dvd an internal data object 138 * @param unit the unit 139 * @return M the Mutable DoubleVector of the right type 140 */ 141 protected abstract A instantiateTypeAbs(DoubleVectorData dvd, AU unit); 142 143 /** 144 * Construct a new Relative Immutable DoubleVector of the right type. Each extending class must implement this method. 145 * @param dvd an internal data object 146 * @param unit the unit 147 * @return M the Mutable DoubleVector of the right type 148 */ 149 protected abstract R instantiateTypeRel(DoubleVectorData dvd, RU unit); 150 151 /** 152 * Construct a new Absolute Mutable DoubleVector of the right type. Each extending class must implement this method. 153 * @param dvd an internal data object 154 * @param unit the unit 155 * @return M the Mutable DoubleVector of the right type 156 */ 157 protected abstract MA instantiateMutableType(DoubleVectorData dvd, AU unit); 158 159 /** 160 * Construct a new Absolute Immutable DoubleScalar of the right type. Each extending class must implement this method. 161 * @param value the value 162 * @param unit the unit 163 * @return S the Immutable DoubleScalar of the right type 164 */ 165 protected abstract S instantiateScalar(double value, AU unit); 166 167 /** {@inheritDoc} */ 168 @Override 169 public final S get(final int index) throws ValueException 170 { 171 return instantiateScalar(getInUnit(index, getUnit()), getUnit()); 172 } 173 174 /**********************************************************************************/ 175 /**************************** TYPED CALCULATION METHODS ***************************/ 176 /**********************************************************************************/ 177 178 /** {@inheritDoc} */ 179 @Override 180 public final A plus(final R rel) throws ValueException 181 { 182 return instantiateTypeAbs(this.getData().plus(rel.getData()), getUnit()); 183 } 184 185 /** {@inheritDoc} */ 186 @Override 187 public A minus(final R rel) throws ValueException 188 { 189 return instantiateTypeAbs(this.getData().minus(rel.getData()), getUnit()); 190 } 191 192 /** {@inheritDoc} */ 193 @Override 194 public R minus(final A abs) throws ValueException 195 { 196 return instantiateTypeRel(this.getData().minus(abs.getData()), getUnit().getRelativeUnit()); 197 } 198 199 /* ============================================================================================ */ 200 /* ============================= STATIC CONSTRUCTOR HELP METHODS ============================== */ 201 /* ============================================================================================ */ 202 203 /** 204 * Check that a provided array can be used to create some descendant of a DoubleVector, and return the Unit. 205 * @param dsArray the array to check and get the unit for 206 * @param <AU> the absolute unit 207 * @param <RU> the corresponding relative unit 208 * @param <S> the scalar type 209 * @return the unit of the object 210 * @throws ValueException when the array has length equal to 0 211 */ 212 static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 213 S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> AU checkUnit(final S[] dsArray) throws ValueException 214 { 215 if (dsArray != null && dsArray.length > 0) 216 { 217 return dsArray[0].getUnit(); 218 } 219 throw new ValueException( 220 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty array of DoubleScalar"); 221 } 222 223 /** 224 * Check that a provided list can be used to create some descendant of a DoubleVector, and return the Unit. 225 * @param dsList the list to check and get the unit for 226 * @param <AU> the absolute unit of the scalars in the list 227 * @param <RU> the corresponding relative unit 228 * @param <S> the scalar in the list 229 * @return the unit of the object 230 * @throws ValueException when the array has length equal to 0 231 */ 232 static <AU extends AbsoluteLinearUnit<AU, RU>, RU extends Unit<RU>, 233 S extends AbstractDoubleScalarAbs<AU, S, RU, ?>> AU checkUnit(final List<S> dsList) throws ValueException 234 { 235 if (dsList != null && dsList.size() > 0) 236 { 237 return dsList.get(0).getUnit(); 238 } 239 throw new ValueException( 240 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty list of DoubleScalar"); 241 } 242 243 /** 244 * Check that a provided Map can be used to create some descendant of a DoubleVector. 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 AbstractDoubleScalarAbs<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( 261 "Cannot create a DoubleVector or MutableDoubleVector from a null or empty Map of DoubleScalar"); 262 } 263 264 }